75

为了将包含透明文本图像的 div 设置为文档中的最高 z-index,我选择了数字 10,000,它解决了我的问题。

之前我已经猜到了数字 3,但它没有效果。

那么,有没有更科学的方法来确定 z-index 比所有其他元素的 z-index 高?

我尝试在 Firebug 中查找此指标,但找不到。

4

18 回答 18

49

为了清楚起见,从 abcoder 网站窃取了一些代码:

  var maxZ = Math.max.apply(null, 
    $.map($('body *'), function(e,n) {
      if ($(e).css('position') != 'static')
        return parseInt($(e).css('z-index')) || 1;
  }));
于 2009-07-13T08:07:14.107 回答
40

您可以调用findHighestZIndex特定的元素类型,例如<div>

findHighestZIndex('div');

假设一个findHighestZindex这样定义的函数:

function findHighestZIndex(elem)
{
  var elems = document.getElementsByTagName(elem);
  var highest = Number.MIN_SAFE_INTEGER || -(Math.pow(2, 53) - 1);
  for (var i = 0; i < elems.length; i++)
  {
    var zindex = Number.parseInt(
      document.defaultView.getComputedStyle(elems[i], null).getPropertyValue("z-index"),
      10
    );
    if (zindex > highest)
    {
      highest = zindex;
    }
  }
  return highest;
}
于 2009-07-13T15:14:00.040 回答
21

使用 ES6 更清洁的方法

function maxZIndex() {

     return Array.from(document.querySelectorAll('body *'))
           .map(a => parseFloat(window.getComputedStyle(a).zIndex))
           .filter(a => !isNaN(a))
           .sort()
           .pop();
}
于 2017-10-03T09:24:40.997 回答
6

我想添加我在我的一个用户脚本中使用的 ECMAScript 6 实现。我正在使用这个来定义z-index特定元素的元素,以便它们始终显示为最高。

在 JS 中,您可以另外为您可能想要排除的元素设置某些属性或类名。例如,考虑您的脚本data-highest在您希望显示为最高元素(例如弹出窗口)的元素上设置属性;并考虑一个您无法控制的类名元素yetHigher,它应该更高(例如自定义上下文菜单)。我可以使用链式:not选择器排除这些元素。请注意,这:not([data-highest], .yetHigher)是可能的,但只是实验性的,并且截至 2021 年 1 月仅对浏览器提供有限的支持。

let highestZIndex = 0;

// Then later, potentially repeatedly
highestZIndex = Math.max(
  highestZIndex,
  ...Array.from(document.querySelectorAll("body *:not([data-highest]):not(.yetHigher)"), (elem) => parseFloat(getComputedStyle(elem).zIndex))
    .filter((zIndex) => !isNaN(zIndex))
);

下面的五行可以多次运行并highestZIndex通过找出当前 highestZIndex值与所有其他计算的所有元素的 z-index 之间的最大值来重复更新变量。filter排除所有"auto"值。

于 2015-08-12T03:03:29.283 回答
4

没有默认属性或任何东西,但您可以编写一些 javascript 来遍历所有元素并找出它。或者如果你使用像 jQuery 这样的 DOM 管理库,你可以扩展它的方法(或者看看它是否已经支持它),以便它从页面加载开始跟踪元素 z-indices,然后检索最高 z-indices 变得微不足道。指数。

于 2009-07-13T08:03:17.937 回答
4

在我看来,解决这个问题的最好方法就是z-index为不同类型的元素设置什么样的 es 的约定。然后,您将z-index通过查看您的文档找到正确的使用方法。

于 2009-07-13T08:05:22.957 回答
4

我相信你正在观察的是巫毒教。如果无法访问您的完整样式表,我当然无法可靠地判断;但让我感到震惊的是,这里真正发生的事情是你忘记了只有定位的元素才会受到z-index.

此外,z-indexes 不会自动分配,仅在样式表中,这意味着没有其他z-indexed 元素,z-index:1;将位于其他所有内容之上。

于 2009-07-13T08:06:23.533 回答
4

我想你必须自己做这个......

function findHighestZIndex()
{
    var divs = document.getElementsByTagName('div');
    var highest = 0;
    for (var i = 0; i < divs .length; i++)
    {
        var zindex = divs[i].style.zIndex;
        if (zindex > highest) {
            highest = zindex;
        }
    }
    return highest;
}
于 2009-07-13T08:07:43.920 回答
3

上面的“ES6”版本比第一个解决方案效率低,因为它在整个阵列上进行了多次冗余传递。而是尝试:

findHighestZ = () =>
  [...document.querySelectorAll('body *')]
    .map(elt => parseFloat(getComputedStyle(elt).zIndex))
    .reduce((highest, z) => z > highest ? z : highest, 1)

从理论上讲,在一个 reduce 步骤中完成它会更快,但是一些快速的基准测试显示没有显着差异,并且代码更粗糙

于 2020-09-02T04:56:03.623 回答
2

使用 jQuery:

如果没有提供元素,它会检查所有元素。

function maxZIndex(elems)
{
    var maxIndex = 0;
    elems = typeof elems !== 'undefined' ? elems : $("*");

    $(elems).each(function(){
                      maxIndex = (parseInt(maxIndex) < parseInt($(this).css('z-index'))) ? parseInt($(this).css('z-index')) : maxIndex;
                      });

return maxIndex;
}
于 2015-04-07T02:40:24.847 回答
2

我最近不得不为一个项目做这个,我发现我从@Philippe Gerber的好答案和@flo的好答案(接受的答案)中受益匪浅。

与上述答案的主要区别是:

  • CSSz-index和任意内联z-index样式都进行了计算,并使用两者中较大的一个进行比较和计算。
  • 值被强制转换为整数,并且忽略任何字符串值(autostatic等)。

是代码示例的 CodePen,但它也包含在此处。

(() => {
  /**
   * Determines is the value is numeric or not.
   * See: https://stackoverflow.com/a/9716488/1058612.
   * @param {*} val The value to test for numeric type.
   * @return {boolean} Whether the value is numeric or not.
   */
  function isNumeric(val) {
    return !isNaN(parseFloat(val)) && isFinite(val);
  }

  
  /**
   * Finds the highest index in the current document.
   * Derived from the following great examples:
   *  [1] https://stackoverflow.com/a/1118216/1058612
   *  [2] https://stackoverflow.com/a/1118217/1058612
   * @return {number} An integer representing the value of the highest z-index.
   */
  function findHighestZIndex() {
    let queryObject = document.querySelectorAll('*');
    let childNodes = Object.keys(queryObject).map(key => queryObject[key]);
    let highest = 0;
    
    childNodes.forEach((node) => {
      // Get the calculated CSS z-index value.
      let cssStyles = document.defaultView.getComputedStyle(node);
      let cssZIndex = cssStyles.getPropertyValue('z-index');
      
      // Get any inline z-index value.
      let inlineZIndex = node.style.zIndex;

      // Coerce the values as integers for comparison.
      cssZIndex = isNumeric(cssZIndex) ? parseInt(cssZIndex, 10) : 0;
      inlineZIndex = isNumeric(inlineZIndex) ? parseInt(inlineZIndex, 10) : 0;
      
      // Take the highest z-index for this element, whether inline or from CSS.
      let currentZIndex = cssZIndex > inlineZIndex ? cssZIndex : inlineZIndex;
      
      if ((currentZIndex > highest)) {
        highest = currentZIndex;
      }
    });

    return highest;
  }

  console.log('Highest Z', findHighestZIndex());
})();
#root {
  background-color: #333;
}

.first-child {
  background-color: #fff;
  display: inline-block;
  height: 100px;
  width: 100px;
}

.second-child {
  background-color: #00ff00;
  display: block;
  height: 90%;
  width: 90%;
  padding: 0;
  margin: 5%;
}

.third-child {
  background-color: #0000ff;
  display: block;
  height: 90%;
  width: 90%;
  padding: 0;
  margin: 5%;
}

.nested-high-z-index {
  position: absolute;
  z-index: 9999;
}
<div id="root" style="z-index: 10">
  <div class="first-child" style="z-index: 11">
    <div class="second-child" style="z-index: 12"></div>
  </div>
  <div class="first-child" style="z-index: 13">
    <div class="second-child" style="z-index: 14"></div>
  </div>
  <div class="first-child" style="z-index: 15">
    <div class="second-child" style="z-index: 16"></div>
  </div>
  <div class="first-child" style="z-index: 17">
    <div class="second-child" style="z-index: 18">
      <div class="third-child" style="z-index: 19">
        <div class="nested-high-z-index">Hello!!! </div>
      </div>
    </div>
  </div>
  <div class="first-child">
    <div class="second-child"></div>
  </div>
  <div class="first-child">
    <div class="second-child"></div>
  </div>
  <div class="first-child">
    <div class="second-child"></div>
  </div>
</div>

于 2017-06-22T16:26:34.810 回答
2

数组.reduce()

z-index这是确定使用的最顶层的另一种解决方案Array.reduce()

const max_zindex = [...document.querySelectorAll('body *')].reduce((accumulator, current_value) => {
  current_value = +getComputedStyle(current_value).zIndex;

  if (current_value === current_value) { // Not NaN
    return Math.max(accumulator, current_value)
  }

  return accumulator;
}, 0); // Default Z-Index Rendering Layer 0 (Zero)
于 2019-09-03T05:00:53.453 回答
2

ShadowRoot 解决方案

我们不能忘记自定义元素和影子根内容。

function computeMaxZIndex() {
    function getMaxZIndex(parent, current_z = 0) {
        const z = parent.style.zIndex != "" ? parseInt(parent.style.zIndex, 10) : 0;
        if (z > current_z)
            current_z = z;
        const children = parent.shadowRoot ? parent.shadowRoot.children : parent.children;
        for (let i = 0; i < children.length; i++) {
            const child = children[i];
            current_z = getMaxZIndex(child, current_z);
        }
        return current_z;
    }
    return getMaxZIndex(document.body) + 1;
}

于 2020-07-30T06:50:17.760 回答
1

一个从@Rajkeshwar Prasad的绝妙想法中获得灵感的解决方案。

	/**
	returns highest z-index
	@param {HTMLElement} [target] highest z-index applyed to target if it is an HTMLElement.
	@return {number} the highest z-index.
	*/
	var maxZIndex=function(target) {
	    if(target instanceof HTMLElement){
	        return (target.style.zIndex=maxZIndex()+1);
	    }else{
	        var zi,tmp=Array.from(document.querySelectorAll('body *'))
	            .map(a => parseFloat(window.getComputedStyle(a).zIndex));
	        zi=tmp.length;
	        tmp=tmp.filter(a => !isNaN(a));
	        return tmp.length?Math.max(tmp.sort((a,b) => a-b).pop(),zi):zi;
	    }
	};
#layer_1,#layer_2,#layer_3{
  position:absolute;
  border:solid 1px #000;
  width:100px;
  height:100px;
}
#layer_1{
  left:10px;
  top:10px;
  background-color:#f00;
}
#layer_2{
  left:60px;
  top:20px;
  background-color:#0f0;
  z-index:150;
}
#layer_3{
  left:20px;
  top:60px;
  background-color:#00f;
}
<div id="layer_1" onclick="maxZIndex(this)">layer_1</div>
<div id="layer_2" onclick="maxZIndex(this)">layer_2</div>
<div id="layer_3" onclick="maxZIndex(this)">layer_3</div>

于 2019-02-22T20:12:34.117 回答
1

如果您要显示具有最高 z 索引的所有元素的 ID

function show_highest_z() {
    z_inds = []
    ids = []
    res = []
    $.map($('body *'), function(e, n) {
        if ($(e).css('position') != 'static') {
            z_inds.push(parseFloat($(e).css('z-index')) || 1)
            ids.push($(e).attr('id'))
        }
    })
    max_z = Math.max.apply(null, z_inds)
    for (i = 0; i < z_inds.length; i++) {
        if (z_inds[i] == max_z) {
            inner = {}
            inner.id = ids[i]
            inner.z_index = z_inds[i]
            res.push(inner)
        }
    }
    return (res)
}

用法

show_highest_z()

结果

[{
    "id": "overlay_LlI4wrVtcuBcSof",
    "z_index": 999999
}, {
    "id": "overlay_IZ2l6piwCNpKxAH",
    "z_index": 999999
}]
于 2019-03-16T15:04:54.197 回答
1

在 NodeList 中找到最大 zIndex 的稳健解决方案

  1. 您应该检查节点本身提供的getComputedStyle和对象style
  2. 使用 Number.isNaN 而不是 isNaN 因为isNaN("") === false
function convertToNumber(value) {
  const asNumber = parseFloat(value);
  return Number.isNaN(asNumber) ? 0 : asNumber;
}

function getNodeZIndex(node) {
  const computedIndex = convertToNumber(window.getComputedStyle(node).zIndex);
  const styleIndex = convertToNumber(node.style.zIndex);

  if (computedIndex > styleIndex) {
    return computedIndex;
  }

  return styleIndex;
}

function getMaxZIndex(nodeList) {
  const zIndexes = Array.from(nodeList).map(getNodeZIndex);
  return Math.max(...zIndexes);
}

const maxZIndex = getMaxZIndex(document.querySelectorAll("body *"));
于 2020-05-13T14:51:10.600 回答
0

map使用和的非常简单的代码filter

function calMaxZIndex() {
  return Array.from(document.querySelectorAll('body *'))
    .map(a => parseFloat(window.getComputedStyle(a).zIndex || a.style.zIndex))
    .filter(a => !isNaN(a))
    .sort()
    .pop()
}

function getMax() {
  const max = calMaxZIndex() ?? 0
  console.log({
    max
  })
}

getMax()
#ticket-box {
  text-align: center;
  position: fixed;
  top: 0;
  right: 0;
  width: 100%;
  background-color: #e9d295;
  padding: 5px;
  z-index: 6;
}
<div id="menu">
  <a href="javascript:void(0);" onclick="closeMenu();" style="color: #ffffff; position: absolute; top: 15px; right: 15px;text-decoration: none;">CLOSE</a>

  <ul style="text-align:center;list-style-type:none;">
    <li><a href="#">FILM</a></li>
    <li><a href="#">MUSIC</a></li>
    <li><a href="#">SPORTS</a></li>
    <li><a href="#">FINANCE</a></li>
  </ul>
</div>

<div id="ticket-box">Have you bought your tickets for friday's event? No?! <a href="#">Grab yours now!</a></div>

<center><a href="javascript:void(0);" onclick="revealMenu();" style="display: inline-block; color: #333333; margin-top: 90px;">MENU</a></center>

于 2021-10-12T10:19:11.893 回答
0

根据之前的答案:

经过一些修改的功能

let zIndexMax = () =>
    [...document.querySelectorAll('body > *')]
        .map(elem => parseInt(getComputedStyle(elem).zIndex, 10) || 0)
        .reduce((prev, curr) => curr > prev ? curr : prev, 1);

原型

HTMLElement.prototype.zIndexMax = function () {
    return [...this.children]
        .map(elem => parseInt(getComputedStyle(elem).zIndex, 10) || 0)
        .reduce((prev, curr) => curr > prev ? curr : prev, 1);
}

用法

document.querySelector('body').zIndexMax();
于 2022-02-20T01:44:18.120 回答