Skip to content

Instantly share code, notes, and snippets.

@SMUsamaShah
Last active July 22, 2025 08:37
Show Gist options
  • Save SMUsamaShah/5f1d341ee8c78680f0963e2687a3121a to your computer and use it in GitHub Desktop.
Save SMUsamaShah/5f1d341ee8c78680f0963e2687a3121a to your computer and use it in GitHub Desktop.
Bookmarklet to drag select and copy all the selected links from a page
  1. Click bookmarklet
  2. Draw over links, links will be copied to clipboard
  3. Paste
javascript:(function () {
    
    if (window.__linkSelectActive) return;
    window.__linkSelectActive = true;
    
    const overlay = document.createElement('div');
    Object.assign(overlay.style, {
        position: 'fixed',
        inset: 0,
        zIndex: 2147483647,          
        cursor: 'crosshair'
    });
    document.body.appendChild(overlay);
    
    const box = document.createElement('div');
    Object.assign(box.style, {
        position: 'absolute',
        border: '2px dashed #09f',
        background: 'rgba(0,153,255,0.12)',
        pointerEvents: 'none'
    });
    overlay.appendChild(box);
    
    let startX, startY;            
    let links = [];                

    overlay.addEventListener('mousedown', onDown);
    
    function onDown(e) {
        startX = e.clientX;
        startY = e.clientY;

        
        Object.assign(box.style, {
            left:  startX + 'px',
            top:   startY + 'px',
            width: 0,
            height: 0
        });

        overlay.addEventListener('mousemove', onMove);
        overlay.addEventListener('mouseup',   onUp);
        e.preventDefault(); 
    }


    function onMove(e) {
        const x = Math.min(e.clientX, startX);
        const y = Math.min(e.clientY, startY);
        const w = Math.abs(e.clientX - startX);
        const h = Math.abs(e.clientY - startY);

        Object.assign(box.style, {
            left:   x + 'px',
            top:    y + 'px',
            width:  w + 'px',
            height: h + 'px'
        });
    }

    function onUp() {
        overlay.removeEventListener('mousemove', onMove);
        overlay.removeEventListener('mouseup',   onUp);

        const sel = box.getBoundingClientRect();

        
        links = [...document.querySelectorAll('a[href]')].filter(a => {
            const r = a.getBoundingClientRect();
            return !(
                r.right  < sel.left  ||
                r.left   > sel.right ||
                r.bottom < sel.top   ||
                r.top    > sel.bottom
            );
        });

        
        links.forEach(a => (a.style.outline = '2px solid #ff5252'));

        const textToCopy = links.map(a => a.href).join('\n');

        

        
        function cleanup() {
            links.forEach(a => (a.style.outline = ''));
            try { document.body.removeChild(overlay); } catch (_) {  }
            delete window.__linkSelectActive;
        }

        
        function copySuccess() {
            alert(`Copied ${links.length} link${links.length !== 1 ? 's' : ''} to clipboard.`);
            setTimeout(cleanup, 800);           
        }

        
        function legacyCopy() {
            const ta = document.createElement('textarea');
            ta.value = textToCopy;
            document.body.appendChild(ta);
            ta.select();
            try {
                document.execCommand('copy');
                copySuccess();
            } catch (err) {
                
                prompt('Copy links:', textToCopy);
                cleanup();
            }
            document.body.removeChild(ta);
        }

        
        if (links.length) {
            
            if (navigator.clipboard && navigator.clipboard.writeText) {
                navigator.clipboard.writeText(textToCopy)
                    .then(copySuccess)
                    .catch(legacyCopy);
            } else {
                legacyCopy();
            }
        } else {
            alert('No links selected.');
            cleanup();
        }
    }
})();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment