Last active
March 19, 2019 05:59
-
-
Save datchley/11383482 to your computer and use it in GitHub Desktop.
DOM related utilities, implementations for wrap(), wrapAll(), geStyle() and getElementsByClassName() - try it http://jsbin.com/jozaje/1/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Faster rounding function to avoid heavy use of Math.round */ | |
function round(n) { | |
return (n + 0.5) << 0; | |
} | |
/** | |
* Wrapper for getBoundingClientRect that returns a | |
* subset ('top','left') and includes a 'width' and 'height'. | |
* It also rounds the pixel measurements to the nearest integer value | |
* | |
* @param {HTMLElement|jQuery} DOM element to get rectangle for | |
* @returns {Object} | |
*/ | |
function getRect(element) { | |
var el = element.jquery ? element[0] : element, | |
rect = el.getBoundingClientRect(); | |
return { | |
top: round(rect.top), | |
left: round(rect.left), | |
height: round(rect.bottom) - round(rect.top), | |
width: round(rect.right) - round(rect.left) | |
}; | |
} | |
/** Implementation of getElementsByClassName, for IE 9 and below */ | |
var getElementsByClassName = function(className, parentElement) { | |
var children = (parentElement || document.body).getElementsByTagName('*'), | |
elements = [], | |
classRE = new RegExp('\\b' + className + '\\b'), | |
child; | |
for (var i = 0, length = children.length; i < length; i++) { | |
child = children[i]; | |
if (classRE.test(child.className)) { | |
elements.push(child); | |
} | |
} | |
return elements; | |
}; | |
/** | |
* Wrap an HTMLElement around each element in a list of elements | |
* Modified global function based on Kevin Jurkowski's implementation | |
* here: http://stackoverflow.com/questions/3337587/wrapping-a-dom-element-using-pure-javascript/13169465#13169465 | |
*/ | |
function wrap(wrapper, elms) { | |
if (!elms.length) { | |
elms = [elms]; | |
} | |
for (var i = elms.length - 1; i >= 0; i--) { | |
var child = (i > 0) ? wrapper.cloneNode(true) : wrapper; | |
var el = elms[i]; | |
var parent = el.parentNode; | |
var sibling = el.nextSibling; | |
child.appendChild(el); | |
if (sibling) { | |
parent.insertBefore(child, sibling); | |
} else { | |
parent.appendChild(child); | |
} | |
} | |
} | |
/** | |
* Wrap an HTMLElement around another set of elements | |
* Modified global function based on Kevin Jurkowski's implementation | |
* here: http://stackoverflow.com/questions/3337587/wrapping-a-dom-element-using-pure-javascript/13169465#13169465 | |
*/ | |
function wrapAll(wrapper, elms) { | |
var el = elms.length ? elms[0] : elms, | |
parent = el.parentNode, | |
sibling = el.nextSibling; | |
wrapper.appendChild(el); | |
while (elms.length) { | |
wrapper.appendChild(elms[0]); | |
} | |
if (sibling) { | |
parent.insertBefore(wrapper, sibling); | |
} | |
else { | |
parent.appendChild(wrapper); | |
} | |
} | |
/** IE8 and below don't have getComputedStyle, so polyfill it... */ | |
var getStyle = (function() { | |
window.getComputedStyle = window.getComputedStyle || function(el, prop) { | |
this.el = el; | |
this.getPropertyValue = function(prop) { | |
var re = /(\-([a-z]){1})/g; | |
if (prop == 'float') { prop = 'styleFloat'; } | |
if (re.test(prop)) { | |
prop = prop.replace(re, function() { | |
return arguments[2].toUpperCase(); | |
}); | |
} | |
return el.currentStyle[prop] ? el.currentStyle[prop] : null; | |
}; | |
}; | |
// This version calls getPropertyValue() automatically | |
return function(el, prop) { | |
return window.getComputedStyle(el, null).getPropertyValue(prop); | |
}; | |
})(); | |
/** | |
* Determine the line-height for a given element. This | |
* is a best guess, as the element may not have uniform line | |
* height. | |
* | |
* @param {HTMLElement|jQuery} - DOM element object | |
* @return {Number} - the line height as an integer | |
*/ | |
function getLineHeight(element) { | |
var el = element.jquery ? element[0] : element, | |
lineheight = getStyle(el, 'line-height'), | |
fontsize = getStyle(el, 'font-size'); | |
if (lineheight == 'normal') { | |
lineheight = Math.floor(parseInt(fontsize, 10) * 1.2); | |
} | |
return parseInt(lineheight, 10); // in px | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* so we can see elements once wrapped */ | |
.highlight * { | |
background-color: yellow !important; | |
} | |
/* so we can see highlighted elements inside wrapper */ | |
.wrapper .highlight * { | |
background-color: orange !important; | |
color: red; | |
} | |
/* with out being highlighted, so we can see stuff inside of wrapper */ | |
.wrapper { | |
color: blue; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script> | |
<meta charset="utf-8"> | |
<title>JS Bin</title> | |
</head> | |
<body> | |
<!-- some content to fiddle with --> | |
<div id="test" class="content"> | |
<p>This paragraph as a leading newline and a trailing newline.</p> | |
<p>Another paragraph with some text in it</p> | |
</div> | |
<!-- we'll wrap other elements in this --> | |
<div class="wrapper"></div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Unit Test for each of the above | |
// | |
// Simple console assert() for use in testing | |
function assert(s, fn) { | |
var assertion = !!(fn()), | |
style = assertion ? 'color: green' : 'color: red'; | |
console.info("> " + s + ": %c" + assertion, style); | |
} | |
// Test our getStyle() implementation | |
assert("getStyle shows line-height as 'normal'", function() { | |
var orig = window.getComputedStyle(target, null).getPropertyValue('line-height'), | |
ours = getStyle(target, 'line-height'); | |
return orig === ours; | |
}); | |
// Test our wrap and wrapAll implementations | |
var wrapper = getElementsByClassName('wrapper')[0], | |
target = getElementsByClassName('content')[0]; | |
// Create a span.highlight element to wrap around each 'p' tag | |
var highlight = document.createElement('span'); | |
highlight.className = 'highlight'; | |
// Wrap each 'p' in a 'span' | |
wrap(highlight, target.getElementsByTagName('p')); | |
assert("each <p> is highlighted after wrap() call", function() { | |
return getElementsByClassName('highlight').length === 2; | |
}); | |
// Wrap entire '.content' contents in '.wrapper' | |
wrapAll(wrapper, target); | |
assert("each <p> is now inside of .wrapper <div> after wrapAll() call", function() { | |
return getElementsByClassName('wrapper')[0].children.length === 1; | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment