Skip to content

Instantly share code, notes, and snippets.

@bvaughn
Created July 12, 2015 20:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bvaughn/e363aa6c9c2e9e210787 to your computer and use it in GitHub Desktop.
Save bvaughn/e363aa6c9c2e9e210787 to your computer and use it in GitHub Desktop.
JavaScript utility capable of highlighting elements matching CSS selector(s)
var StyleMatcher = function() {
this.indicatorContainer_ = document.createElement('div');
document.body.appendChild(this.indicatorContainer_);
};
StyleMatcher.DEFAULT_STYLES_ = {
position: 'absolute',
borderWidth: '1px',
borderStyle: 'solid',
borderColor: 'red',
pointerEvents: 'none',
zIndex: 10000
};
StyleMatcher.prototype.clear = function() {
styleMatcher.indicatorContainer_.innerHTML = ''; // Faster than multiple removeNode() calls
};
StyleMatcher.prototype.match = function(selectorOrSelectors, opt_highlightColor) {
this.clear();
if (!(selectorOrSelectors instanceof Array)) {
selectorOrSelectors = [selectorOrSelectors];
}
selectorOrSelectors.forEach(function(selector) {
var nodeList = document.querySelectorAll(selector);
if (!nodeList.length) {
console.warn('No elements were founding matching the selector:', selector);
return;
}
for (var i = 0; i < nodeList.length; ++i) { // NodeList not Array
var indicator = this.createIndicator_(nodeList[i], opt_highlightColor);
this.indicatorContainer_.appendChild(indicator);
}
}, this);
};
StyleMatcher.prototype.createIndicator_ = function(element, opt_highlightColor) {
var absoluteOffset = this.getAbsoluteOffset_(element);
var indicator = document.createElement('div');
indicator.innerHTML = '&nbsp;';
for (var propName in StyleMatcher.DEFAULT_STYLES_) {
indicator.style[propName] = StyleMatcher.DEFAULT_STYLES_[propName];
}
if (!Number.isNaN(absoluteOffset.offsetLeft)) {
indicator.style.left = (absoluteOffset.offsetLeft - 1) + 'px';
}
if (!Number.isNaN(absoluteOffset.offsetRight)) {
indicator.style.right = (absoluteOffset.offsetRight - 1) + 'px';
}
if (!Number.isNaN(absoluteOffset.offsetTop)) {
indicator.style.top = (absoluteOffset.offsetTop - 1) + 'px';
}
if (!Number.isNaN(absoluteOffset.offsetBottom)) {
indicator.style.bottom = (absoluteOffset.offsetBottom - 1) + 'px';
}
indicator.style.width = (element.offsetWidth + 1) + 'px';
indicator.style.height = (element.offsetHeight + 1) + 'px';
if (opt_highlightColor) {
indicator.style.borderColor = opt_highlightColor;
}
return indicator;
};
StyleMatcher.prototype.getAbsoluteOffset_ = function(element) {
var offsetLeft = 0, offsetRight = 0, offsetTop = 0, offsetBottom = 0;
var currentElement = element;
while (currentElement) {
offsetLeft += currentElement.offsetLeft;
offsetRight += currentElement.offsetRight;
offsetTop += currentElement.offsetTop;
offsetBottom += currentElement.offsetBottom;
currentElement = currentElement.offsetParent;
}
return {
offsetLeft: offsetLeft,
offsetRight: offsetRight,
offsetTop: offsetTop,
offsetBottom: offsetBottom
};
};
var styleMatcher = new StyleMatcher();
styleMatcher.match('div');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment