Last active
January 28, 2017 06:57
-
-
Save jrf0110/ac5add0e2b73dd527bf33b460bdf754c to your computer and use it in GitHub Desktop.
Gets line number of an HTML element.
This file contains hidden or 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
/** | |
* Gets the line number of an element in an HTML element | |
* @return number -1 if not found | |
* @example | |
* getLineNo(document.body) | |
* @caveat | |
* This function assumes that <html>, </html>, and the DOCTYPE | |
* declaration are all on their own lines. If this isn't the case, | |
* you can adjust options.numLinesForHTMLElement. ALSO, I didn't | |
* make any concessions for browser support, but the general technique | |
* should across browsers. ALSO, this technique is totally useless if | |
* you want the ORIGINAL source line number and some other JS already | |
* messed with the DOM where the element lives | |
*/ | |
function getLineNo(element, options = {}) { | |
for (const key in getLineNo.defaultOptions) { | |
if (!(key in options)) options[key] = getLineNo.defaultOptions[key] | |
} | |
const MAX_I = 100 | |
let prev | |
let i = 0 | |
let curr = element | |
// Get the root node for this element | |
while (curr.parentElement !== null && ++i < options.maxIterationsForRoot) { | |
curr = curr.parentElement | |
} | |
if (i === MAX_I) return -1 | |
// Apply a unique identifier to the element that's very unlikely to | |
// have gotten here otherwise | |
const id = getLineNo.uuid() | |
const searchFor = `data-search-id="${id}"` | |
element.dataset.searchId = id | |
const lines = curr.innerHTML.split('\n') | |
// Find the line containing our id | |
for (let i = 0; i < lines.length; i++) { | |
if (lines[i].indexOf(searchFor) > -1) { | |
delete element.dataset.searchId | |
return i + options.numLinesForHTMLElement | |
} | |
} | |
delete element.dataset.searchId | |
return -1 | |
} | |
getLineNo.defaultOptions = { | |
// This includes html open, close, and the doctype | |
numLinesForHTMLElement: 3, | |
// Maximum amount of times we check for parent before breaking | |
// the loop to avoid possible infinite loops | |
maxIterationsForRoot: 100, | |
} | |
// Credit: http://stackoverflow.com/a/2117523 | |
getLineNo.uuid = function uuid(){ | |
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | |
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8) | |
return v.toString(16) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment