Skip to content

Back to Snippets

highlight​Elements​Matching()

The highlightElementsMatching() function highlights DOM elements for which the passed function returns true. It uses a MutationObserver to keep watching for changes to the DOM tree and highlight accordingly.

function highlightElementsMatching(predicate, label) {
	
	if (!document.head.querySelector('#dt-highlight-style')) {

		const s = document.createElement('style');
		s.id = 'dt-highlight-style';
		s.textContent = `
			.dt-highlight {
				outline: 2px solid red;
				box-shadow: inset 0px 0px 0 9999px rgba(255, 0, 0, 0.1);
			}
		`;
		document.head.appendChild(s);

		const mo = new MutationObserver(function() {
			document.dispatchEvent(new CustomEvent('dt-change', {
				detail: this
			}));
		});

		mo.observe(document.documentElement, {
			childList: true,
			subtree: true,
			attributes: true
		});
	}

	function onChange(e) {
		if (e.detail) {
			e.detail.disconnect();
		}
		document.querySelectorAll('*').forEach(el => {
			if (predicate(el)) {
				if (!el.classList.contains('dt-highlight')) {
					el.classList.add('dt-highlight');
				}
				const title = label ? label(el) : '';
				if (el.title !== title) {
					el.title = title;	
				}
			} else {
				if (el.classList.contains('dt-highlight')) {
					el.classList.remove('dt-highlight');
				}
				if (el.title) {
					el.title = '';
				}
			}
 		});
 		if (e.detail) {
	 		e.detail.observe(document.documentElement, {
				childList: true,
				subtree: true,
				attributes: true
			});
	 	}
	}

	document.addEventListener('dt-change', onChange);
	document.dispatchEvent(new CustomEvent('dt-change'));
}