1

I am trying to find the highest z-index on a page. I am using this

var getStyleProp = function(el, prop){
            return window.getComputedStyle(el, null).getPropertyValue(prop);
}
var getHighestZIndex = function(){

            var highestZIndex = 0,
                HTMLElems = ["a","abbr","acronym","address","applet","area","article","audio","b","base","basefont","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","embed","fieldset","figcaption","figure","footer","form","frame","frameset","h1, h2, h3, h4, h5, h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","isindex","kbd","keygen","label","legend","li","link","listing","main","map","mark","menu","menuitem","meta","meter","nav","noembed","noscript","object","ol","optgroup","option","output","p","param","plaintext","pre","progress","q","rp","rt","rtc","ruby","s","samp","script","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","tt","u","ul","var","video","wbr","xmp"],
                tags,
                zIndex;

            for (var i = 0; i < HTMLElems.length; i++){

                tags = document.getElementsByTagName(HTMLElems[i]);

                if (tags){
                    for (var c = 0; c < tags.length; c++){
                        zIndex =getStyleProp(tags[c], "z-index");
                           console.log(tags[c], "zIndex=", zIndex);
                        if (zIndex > highestZIndex){
                            highestZIndex = zIndex;
                        }

                    }   
                }


            }

            return highestZIndex;

        }
console.log(getHighestZIndex());

But everything is coming back as "auto". This ancient article explains how a "bug" is causing this behavior. I've tried to make clones of each node, set the position to relative, and then get the z-index,

cl.style.display = "none";
cl.style.position = "absolute";
zIndex = (getStyleProp(cl, "z-index"));

but that is not working either. What is wrong here? Is there a cheaper way to do this than recreating everything on the page?

JSBIN

1252748
  • 14,597
  • 32
  • 109
  • 229

2 Answers2

4

The node's clone does not seem to get the z-index, while the node itself returns the right value. You could try using it instead (not sure how it might react on a page with lots of content):

var getHighestZIndex = function () {
    var highestZIndex = 0,
        zIndex,
        pos,
        tags = document.body.getElementsByTagName('*');

    for (var c = 0; c < tags.length; c++) {
        // Get the original 'position' property
        pos = getComputedStyle(tags[c]).position;
        // Set it temporarily to 'relative'
        tags[c].style.position = "relative";
        // Grab the z-index
        zIndex = getComputedStyle(tags[c]).zIndex;
        // Reset the 'position'
        tags[c].style.position = pos;

        console.log(tags[c], "zIndex=", zIndex);

        if (zIndex > highestZIndex) { highestZIndex = zIndex; }
    }

    return highestZIndex;
};

console.log(getHighestZIndex());

JS Fiddle Demo

Changing the element's position temporarily might produce a glitch. You'll need to test that on a page with lots of contents and elements that are position:absolute; or position:fixed;.

blex
  • 24,941
  • 5
  • 39
  • 72
  • With the edit that your `zIndex` variable should include a `parseInt` (that is the only way it worked for me, I think this is a pretty good solution. Thanks. – 1252748 Mar 23 '15 at 15:18
  • Upon closer inspection, I see what you are doing now. Hrm. No I don't think it is good to change the position of every node. – 1252748 Mar 23 '15 at 15:20
  • @thomas I don't think either. That's just the only way I could find. – blex Mar 23 '15 at 15:23
1

If this doesn't fit your use-case, just let me know, and I'll remove it. However, as a thought.

Can you loop through all the tags, and if the value is "auto" assume it's 999. If it's >= 1000, take that as your "highest" value. Then, increment your zIndex up from your highest number that way. This way, the first tag you place will be 1000, the next will be 1001.

var elements  = document.getElementsByTagName("*"),
    maxZIndex = 999;

for( var i=0; i < elements.length; i++ ) {
    var zIndex = parseInt(elements[0].style.zIndex) || 999;
    maxZIndex  = zIndex > maxZIndex ? zIndex : maxZIndex;
}
return maxZIndex;

This would fit a use case where you are just trying to make sure that the tag you are placing is greater than anything on the page...such as placing a modal.

999 is overkill...somewhat of a "just in case" I missed something because anything with z-index:auto is equivalent to zero. See the following "proof" where even though my z-index is only "1" it overlaps boxes that are 3-deep of "auto".

<div style='position:absolute;background-color:white;z-index:1;width:94px;height:94px;'>

</div>
<div style='position:absolute;background-color:red;width:100px;height:100px;'>
    <div style='position:absolute;background-color:blue;width:98px;height:98px;'>
        <div style='position:absolute;background-color:green;width:96px;height:96px;'>

        </div>
    </div>
</div>
calamari
  • 234
  • 1
  • 5
  • @thomas, auto just means that it's the same as its parent...it's a non-value. So, you can actually assume that a value of 1 is sufficient for "auto" if no actual values are found for z-index...then they are all zero. – calamari Mar 20 '15 at 21:03
  • @thomas, http://stackoverflow.com/questions/14109862/difference-between-auto-0-and-no-z-index – calamari Mar 20 '15 at 21:04
  • @thomas, I added a proof of sorts to show that even at 3-deep, the "auto" values for a tag's z-index is still zero and "1" will overlay it. – calamari Mar 20 '15 at 21:15
  • Could you add a fiddle to this? I just am not understanding what you mean. Thanks very much. – 1252748 Mar 23 '15 at 15:56