JavaScript bookmarklet to click an element and copy its text contents

Updated . Posted . Visible to the public.

Here is some JavaScript code that allows you to click the screen and get the clicked element's text contents (or value, in case of inputs).

The approach is simple: we place an overlay so you don't really click the target element. When you click the overlay, we look up the element underneath it and show its text in a browser dialog. You can then copy it from there.

While moving the mouse, the detected element is highlighted.

Here is the one-liner URL that you can store as a bookmark. Place it in your bookmarks bar and click it to activate.

javascript:(function(){var overlay=document.createElement('div');Object.assign(overlay.style,{position:'fixed',top:0,left:0,width:'100vw',height:'100vh',zIndex:99999999,background:'transparent',cursor:'crosshair'});document.body.append(overlay);function getElement(event){overlay.style.pointerEvents='none';var element=document.elementFromPoint(event.clientX,event.clientY);overlay.style.pointerEvents='auto';return element};document.addEventListener('mousemove',function(event){var element=getElement(event);if(!element)return;var position=element.getBoundingClientRect();Object.assign(overlay.style,{background:'rgba(0, 128, 255, 0.25)',outline:'1px solid rgba(0, 128, 255, 0.5)',top:''+position.top+'px',left:''+position.left+'px',width:''+position.width+'px',height:''+position.height+'px'})});overlay.addEventListener('click',function(event){var element=getElement(event);var text=element.textContent||element.value;text=text.replace(/\n[ \n]+\n/g,"\n").replace(/\n\n+/g,"\n\n").replace(/^\n+|\n+$/g,'');if(!text.match("\n"))text=text.replace(/^ +| +$/,'');window.prompt('Press Ctrl+C to copy',text);document.body.removeChild(overlay)})})()

Here is the formatted JavaScript code:

(function() {
  var overlay = document.createElement('div');
  Object.assign(overlay.style, {
    position: 'fixed',
    top: 0,
    left: 0,
    width: '100vw',
    height: '100vh',
    zIndex: 99999999,
    background: 'transparent',
    cursor: 'crosshair'
  });
  document.body.append(overlay);

  function getElement(event) {
    overlay.style.pointerEvents = 'none';
    var element = document.elementFromPoint(event.clientX, event.clientY);
    overlay.style.pointerEvents = 'auto';

    return element;
  }

  document.addEventListener('mousemove', function(event) {
    var element = getElement(event);
    if (!element) return;

    var position = element.getBoundingClientRect();

    Object.assign(overlay.style, {
      background: 'rgba(0, 128, 255, 0.25)',
      outline: '1px solid rgba(0, 128, 255, 0.5)',
      top: '' + position.top + 'px',
      left: '' + position.left + 'px',
      width: '' + position.width + 'px',
      height: '' + position.height + 'px'
    });
  });

  overlay.addEventListener('click', function(event) {
    var element = getElement(event);
    var text = element.textContent || element.value;
    text = text.replace(/\n[ \n]+\n/g, "\n").replace(/\n\n+/g, "\n\n").replace(/^\n+|\n+$/g, '');
    if (!text.match("\n")) text = text.replace(/^ +| +$/, '')

    window.prompt('Press Ctrl+C to copy', text);
    document.body.removeChild(overlay);
  });
})()

You can also find it on GitHub Show archive.org snapshot . If you make any improvements, please let me know.

Things to note:

  • We slightly clean up found text: leading or trailing blank lines are remove while keeping indentation whitespace; indentation whitespace is only removed when there is a single line of text.
  • The script focuses the element underneath the mouse pointer. If container elements have no borders or padding, you may only be select the inner elements, not the container.
  • You could extend this script to use the execCommand API and copy directly into the clipboard. Using a simple prompt allows the user to see the content and decide if they want to copy or not.
Arne Hartherz
Last edit
Arne Hartherz
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2017-08-24 09:32)