Email Obfuscation

html

Display a clickable email address that's hidden from scrapers. The email is stored as separate data attributes and assembled by JavaScript, making it invisible to bots that parse HTML for mailto links.

<!-- HTML -->
<a href="#" class="email-link" 
   data-user="contact" 
   data-domain="example.com">
   <span class="email-placeholder">Loading...</span>
</a>

<script>
// JavaScript - run after DOM loads
document.querySelectorAll('.email-link').forEach(link => {
    const user = link.dataset.user;
    const domain = link.dataset.domain;
    if (user && domain) {
        const email = `${user}@${domain}`;
        link.href = `mailto:${email}`;
        const placeholder = link.querySelector('.email-placeholder');
        if (placeholder) {
            placeholder.textContent = email;
        }
    }
});
</script>

Copy to Clipboard

javascript

A modern async clipboard function with fallback for older browsers. Returns a promise so you can show success/error feedback.

async function copyToClipboard(text) {
    try {
        // Modern async clipboard API
        await navigator.clipboard.writeText(text);
        return true;
    } catch (err) {
        // Fallback for older browsers
        const textarea = document.createElement('textarea');
        textarea.value = text;
        textarea.style.position = 'fixed';
        textarea.style.opacity = '0';
        document.body.appendChild(textarea);
        textarea.select();
        try {
            document.execCommand('copy');
            return true;
        } catch (e) {
            return false;
        } finally {
            document.body.removeChild(textarea);
        }
    }
}

// Usage:
copyToClipboard('Hello!').then(success => {
    if (success) alert('Copied!');
});

Debounce Function

javascript

Limit how often a function can fire. Useful for search inputs, window resize handlers, and scroll events.

function debounce(func, wait = 300) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

// Usage:
const handleSearch = debounce((query) => {
    console.log('Searching for:', query);
    // Make API call here
}, 500);

// Attach to input
searchInput.addEventListener('input', (e) => {
    handleSearch(e.target.value);
});

LocalStorage with Expiry

javascript

Wrapper functions for localStorage that support automatic expiration of stored values.

function setWithExpiry(key, value, ttlMinutes) {
    const item = {
        value: value,
        expiry: Date.now() + (ttlMinutes * 60 * 1000)
    };
    localStorage.setItem(key, JSON.stringify(item));
}

function getWithExpiry(key) {
    const itemStr = localStorage.getItem(key);
    if (!itemStr) return null;
    
    try {
        const item = JSON.parse(itemStr);
        if (Date.now() > item.expiry) {
            localStorage.removeItem(key);
            return null;
        }
        return item.value;
    } catch (e) {
        return null;
    }
}

// Usage:
setWithExpiry('session_token', 'abc123', 30); // expires in 30 min
const token = getWithExpiry('session_token');

Format Bytes to Human Readable

javascript

Convert byte counts to human-readable strings like '1.5 MB' or '256 KB'.

function formatBytes(bytes, decimals = 2) {
    if (bytes === 0) return '0 Bytes';
    
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    
    return parseFloat(
        (bytes / Math.pow(k, i)).toFixed(decimals)
    ) + ' ' + sizes[i];
}

// Examples:
formatBytes(1234);        // "1.21 KB"
formatBytes(1234567);     // "1.18 MB"
formatBytes(1234567890);  // "1.15 GB"