如何计算HTML元素的有效z-index

13
我想通过代码确定 HTML 页面上一个元素的 z-index 值,我正在使用 jQuery。jQuery 可以使用 $(element).css("z-index") 来检查已应用的 z-index 值。但是,如果该元素没有直接设置 z-index 值,则 Firefox 返回 "auto",IE 返回 "0"。此时,该节点的有效 z-index 取决于其容器的 z-index。因此,我想通过查看节点及其父级,直到找到 z-index 值来计算有效的 z-index 值。但问题在于,至少在 IE 上,我无法将具有 z-index 为 0 的元素与将继承其父级 z-index 的元素区分开来,因为在这两种情况下,.css("z-index") 都返回 0。请问如何计算元素的实际 z-index 值?
<html>
<head>
    <script src="http://code.jquery.com/jquery-latest.js"></script>

</head>

<body>

<script type="text/javascript">
    alert($("<div></div>").css("z-index"));
    alert($("<div style='position:relative'></div>").css("z-index"));
    alert($("<div style='z-index:0'></div>").css("z-index"));
    alert($("<div style='z-index:100'></div>").css("z-index"));
</script>

</body>
</html>

1
这将是一项棘手的任务,因为在某些页面上可能会有多个堆叠索引。您是在尝试弄清楚如何将某物堆叠在另一物体之上吗? - scunliffe
类似这样的内容(将超过某个z-index限制的内容隐藏起来) - Frank Schwieterman
5个回答

10
在IE浏览器中,我无法区分具有z-index为0的元素和将继承其父级z-index的元素。您需要查找具有非静态定位的position样式的元素的父级来查找具有有效z-index的元素。因此,您应该一直向上查找父级,直到找到具有非auto z-index 的被定位的元素。(这将为您提供最内部的z-index。堆叠上下文可以嵌套,因此您可能希望通过查看最远的祖先来查看最外层的z-index。)
在IE6-7中,没有 z-index 的元素会错误地接收自动的z-index为0。 因此,在IE6-7中查看没有z-index的定位元素时,这确实会给您一个读数为0... 这可能是不正确的,但它反映了IE已经存在的错误渲染,您必须避免或解决这个问题。
(在IE8中,这个问题终于得到了修复,并且您确实会获得第一个警告的auto值,假设适当的doctype/EmulateIE设置将其发送到IE8本机模式。)

好的观点是 z-index 只应考虑定位元素(并且任何遍历以确定元素的 z-index 应跳过非定位元素)。 - Frank Schwieterman
IE在继承z-index的情况下会返回0。但是,IE会正确地应用继承的z-index,因此IE6-IE7的情况仍然存在问题。 - Frank Schwieterman
错误在于IE6-7无法在定位元素上“继承”堆叠上下文。当您在定位元素上获得0作为z-index时,可以确定0是IE实际用于呈现该元素的z-index - 即使根据CSS规范它不应该这样做。 - bobince
嗯,这对我来说是个新闻。与我过去所看到的事情相矛盾,我必须进行实验以确保我理解您所说的内容。谢谢你的澄清。 - Frank Schwieterman
谷歌IE z-index bug问题已经被无数次报告。通常,如果您嵌套了定位元素,最安全的做法是确保在每个定位元素上都放置z-index。否则,IE6-7可能会呈现错误的内容。 - bobince

1

我看到了问题,但我不确定它是否真的很重要...因为页面的根 z-index 是0。在以下代码中:

alert($("<div id='root' style='z-index:10'><div id='blah'></div><div>").get(0).style.zIndex);
alert($("<div id='root' style='z-index:10'><div id='blah'></div><div>").children('#blah').get(0).style.zIndex);

FF 报告 10 和(不是“自动”)。IE 报告 10 和 0。对于 IE,如果您看到 0,则向上移动一个级别。对于 FF,如果您看到空白,则向上移动一个级别。然后,在任何情况下,如果您到达根,并且该值为“auto”(在 FF 的条件下),则我(猜测)可以假设它为 0。(也许这不是一个很好的假设!)


对于IE浏览器,如果您看到一个0,则向上移动一级。这个语句假设元素的z-index没有被明确设置为0。我猜这是不太可能的,但我在此之前排除了这种方法。也许这是可能的,因为我正在查看的内容是广告内容,其中一些广告提供商可能会做一些奇怪的事情以获得更多的曝光率。 - Frank Schwieterman
是的,我明白你的意思...然而我会质疑...IE本身是否有区分呢?也就是说,它是否使用0作为标记来表示“未设置”?如果是这样的话,那么设置0与根本不设置没有任何区别。我想你需要运行一些实际的渲染测试才能真正确定。 - Michael Bray

1

我认为这个函数在大多数情况下都能解决你的问题。

function ustMaxZIndex(eleman) {
  var elm = $('#'+eleman);
  var zindex = parseInt(elm.css("z-index")) > 0 ? elm.css("z-index") : 0;
  while(true) {
    zindex = (parseInt(elm.css("z-index")) > 0 && parseInt(elm.css("z-index")) > zindex) ? elm.css("z-index") : zindex;
    if(elm.length > 0) {
      elm = elm.parent();
    } else {
      break;
    }
  }
  return zindex;
}

0

这是我的尝试。如果找不到特定的 z-index 数字,函数将返回 auto,否则将返回一个数字。它包括通过 addBack 方法调用传递的元素。

希望对某人有所帮助:


/**
 * __getElementZIndex
 * 
 * @access  private
 * @param   HTMLElement element
 * @return  String
 */
var __getElementZIndex = function(element) {
    var response = 'auto',
        zIndex,
        items = $(element).parents().addBack().toArray(),
        index,
        item;
    for (index in items) {
        item = items[index];
        zIndex = $(item).css('z-index');
        if (zIndex === 'auto') {
            continue;
        }
        if (zIndex === 'initial') {
            continue;
        }
        if (zIndex === 'inherit') {
            continue;
        }
        if (isNaN(zIndex) === true) {
            continue;
        }
        zIndex = parseInt(zIndex, 10);
        if (response === 'auto') {
            response = zIndex;
            continue;
        }
        if (zIndex > response) {
            response = zIndex;
            continue;
        }
    }
    return response;
};

注意:需要使用 jQuery。

0

MC_delta_T答案的优化版本:

这个方法不能处理嵌套的z-indexes,但是它可以找到层级中最高的值,大多数情况下都能正常工作:

function getEffectiveZIndex(elm) {
    var elementZIndex,
        style,
        zindex = 0;

    while(elm) {
        style = getComputedStyle(elm);

        if (style) {
            elementZIndex = parseInt(style.getPropertyValue('z-index'), 10);

            if (elementZIndex > zindex) {
                zindex = elementZIndex;
            }
        }

        elm = elm.parentNode;
    }

    return zindex;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接