JSFiddle - React, Tailwind, and code Playground

by jfriend00

HTML

<div>
    <div id="test"></div>
    <div></div>
</div>
<div id="result"></div>

JavaScript

function findElementPercentage(target) {
    var cnt = 0;
    var pos;
    treeWalkFast(document.body, function(node) {
        if (node === target) {
            pos = cnt;
        }
        ++cnt;
    });
    // handle situation where target was not found
    if (pos === undefined) {
        return undefined;
    }
    // return percentage
    return (pos / cnt) * 100;
}

var treeWalkFast = (function() {
    // create closure for constants
    var skipTags = {"SCRIPT": true, "IFRAME": true, "OBJECT": true, 
        "EMBED": true, "STYLE": true, "LINK": true, "META": true};
    return function(parent, fn, allNodes) {
        var node = parent.firstChild, nextNode;
        while (node && node != parent) {
            if (allNodes || node.nodeType === 1) {
                if (fn(node) === false) {
                    return(false);
                }
            }
            // if it's an element &&
            //    has children &&
            //    has a tagname && is not in the skipTags list
            //  then, we can enumerate children
            if (node.nodeType === 1 && node.firstChild && !(node.tagName && skipTags[node.tagName])) {
                node = node.firstChild;
            } else  if (node.nextSibling) {
                node = node.nextSibling;
            } else {
                // no child and no nextsibling
                // find parent that has a nextSibling
                while ((node = node.parentNode) != parent) {
                    if (node.nextSibling) {
                        node = node.nextSibling;
                        break;
                    }
                }
            }
        }
    }
})();

var pos = findElementPercentage(document.getElementById("test"));
document.getElementById("result").innerHTML = pos;