eaich

Eddie

Posted on October 14, 2019

Spy on the DOM

This module allows you to quickly see a DOM element's attributes by simply hovering your mouse over it inside your browser. Basically, it's an on-the-fly inspector.

SpyOn demo

Hovering your mouse over DOM elements shows its attributes!

Try it out yourself

Copy the entire code block below and paste it into your browser web console. Now hover your mouse around whatever web page you're on. What do you see?

(function SpyOn() {

  const _id = 'spyon-container',
        _posBuffer = 3;

  function init() {
    document.body.addEventListener('mousemove', glide);
    document.body.addEventListener('mouseover', show);
    document.body.addEventListener('mouseleave', hide);
  }

  function hide(e) {
    document.getElementById(_id).style.display = 'none';
  }

  function show(e) {
    const spyContainer = document.getElementById(_id);
    if (!spyContainer) {
      create();
      return;
    }
    if (spyContainer.style.display !== 'block') {
      spyContainer.style.display = 'block';
    }
  }

  function glide(e) {
    const spyContainer = document.getElementById(_id);
    if (!spyContainer) {
      create();
      return;
    }
    const left = e.clientX + getScrollPos().left + _posBuffer;
    const top = e.clientY + getScrollPos().top + _posBuffer;
    spyContainer.innerHTML = showAttributes(e.target);
    if (left + spyContainer.offsetWidth > window.innerWidth) {
      spyContainer.style.left = left - spyContainer.offsetWidth + 'px';
    } else {
      spyContainer.style.left = left + 'px';
    }
    spyContainer.style.top = top + 'px';
  }

  function getScrollPos() {
    const ieEdge = document.all ? false : true;
    if (!ieEdge) {
      return {
        left : document.body.scrollLeft,
        top : document.body.scrollTop
      };
    } else {
      return {
        left : document.documentElement.scrollLeft,
        top : document.documentElement.scrollTop
      };
    }
  }

  function showAttributes(el) {
    const nodeName = `<span style="font-weight:bold;">${el.nodeName.toLowerCase()}</span><br/>`;
    const attrArr = Array.from(el.attributes);
    const attributes = attrArr.reduce((attrs, attr) => {
      attrs += `<span style="color:#ffffcc;">${attr.nodeName}</span>="${attr.nodeValue}"<br/>`;
      return attrs;
    }, '');
    return nodeName + attributes;
  }

  function create() {
    const div = document.createElement('div');
    div.id = _id;
    div.setAttribute('style', `
      position: absolute;
      left: 0;
      top: 0;
      width: auto;
      height: auto;
      padding: 10px;
      box-sizing: border-box;
      color: #fff;
      background-color: #444;
      z-index: 100000;
      font-size: 12px;
      border-radius: 5px;
      line-height: 20px;
      max-width: 45%;
      `
    );
    document.body.appendChild(div);
  }

  init();

})();

Enter fullscreen mode Exit fullscreen mode

How it works

This module is implemented as an IIFE. This way, you can just copy and paste the code into your web console whenever you need some DOM spying assitance. A div is inserted into your document's body and mouse event listeners are enabled on the body. Attributes are retrieved from the target element, reduced down to a single string and then displayed inside the tooltip.

Use cases

  1. Help troubleshoot a UI bug
  2. Ensure that your app's DOM elements are working as expected (getting the right class on click, etc)
  3. Find out how another web app is structured

What you can learn from this code

  1. How to implement a tooltip module using vanilla JS
  2. How to parse a DOM object's attributes
  3. How to find the mouse's X and Y position
  4. How to take into account the document's scroll position
  5. Understand how different browsers behave - Edge vs. Chrome vs. Safari

Open source

You can find the source code here and I encourage you to make it better! Perhaps you don't want it to be implemented as an IIFE, or maybe you want to show other data, or maybe it's just broken!

Happy spying!

πŸ’– πŸ’ͺ πŸ™… 🚩
eaich
Eddie

Posted on October 14, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related