如何找出文档中最高的 z-index?

发布于 2024-07-26 15:30:08 字数 183 浏览 8 评论 0原文

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

之前我曾猜过数字3,但没有效果。

那么,是否有更科学的方法来确定哪个 z-index 高于所有其他元素的 z-index?

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

In order to set a div containing a transparent text image as the highest z-index in my document, I picked the number 10,000 and it solved my problem.

Previously I had guessed with the number 3 but it had no effect.

So, is there a more scientific way of figuring out what z-index is higher than that of all of your other elements?

I tried looking for this metric in Firebug but couldn't find it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(23

猫腻 2024-08-02 15:30:09

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

There isn't a default property or anything, but you could write some javascript to loop through all elements and figure it out. Or if you use a DOM management library like jQuery, you could extend its methods (or find out if it supports it already) so that it starts tracking element z-indices from page load, and then it becomes trivial to retrieve the highest z-index.

我ぃ本無心為│何有愛 2024-08-02 15:30:09

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

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

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

The "ES6" version above is less efficient than the first solution because it does multiple redundant passes across the full array. Instead try:

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

In theory it would be even quicker to do it in one reduce step, but some quick benchmarking showed no significant difference, and the code is gnarlier

苯莒 2024-08-02 15:30:09

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

The best way to solve this problem is, in my opinion, just to set yourself conventions for what kinds of z-indexes are used for different kinds of elements. Then, you'll find the correct z-index to use by looking back at your documentation.

花开半夏魅人心 2024-08-02 15:30:09

最近我不得不为一个项目这样做,我发现我从 @Philippe Gerber 的这里有一个很好的答案,以及 @flo 的很好的答案(已接受的答案)。

与上面引用的答案的主要区别是:

  • CSS z-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>

I had to do this for a project recently, and I found that I benefitted a lot from @Philippe Gerber's great answer here, and @flo's great answer (the accepted answer).

The key differences to the answers referenced above are:

  • Both the CSS z-index, and any inline z-index style are calculated, and use the larger of the two for comparison and calculation.
  • Values are coerced into integers, and any string values (auto, static, etc) are ignored.

Here is a CodePen for the code example, but it's included here as well.

(() => {
  /**
   * 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>

溺深海 2024-08-02 15:30:09

使用 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;
}

Using jQuery:

if no elements supplied, it checks all elements.

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;
}
雪花飘飘的天空 2024-08-02 15:30:09

Array.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)

Array.reduce()

Here's another solution to determine the topmost z-index that uses 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)
半葬歌 2024-08-02 15:30:09

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;
}

ShadowRoot solutions

We must not forget about custom-elements and shadow-root content.

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;
}

亢潮 2024-08-02 15:30:09

如果您希望显示具有最高 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
}]

If you're looking to show the IDs of all elements with the highest z indices:

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)
}

Usage:

show_highest_z()

Result:

[{
    "id": "overlay_LlI4wrVtcuBcSof",
    "z_index": 999999
}, {
    "id": "overlay_IZ2l6piwCNpKxAH",
    "z_index": 999999
}]
转角预定愛 2024-08-02 15:30:09

一个解决方案深受 @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>

A solution highly inspired from the excellent idea of @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>

人疚 2024-08-02 15:30:09

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

  1. 您应该检查节点本身提供的 getCompulatedStylestyle 对象
  2. 使用 Number.isNaN 而不是 isNaN 因为 isNaN("" ) === 假
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 *"));

Robust solution to find maximum zIndex in NodeList

  1. You should check both getComputedStyle and style object provided by node itself
  2. Use Number.isNaN instead of isNaN because of 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 *"));
帅哥哥的热头脑 2024-08-02 15:30:09

短的

[...document.querySelectorAll`*`]
  .reduce((a,e,i,t,z=+window.getComputedStyle(e).zIndex||0) => z>a ? z:a ,0);

let z = [...document.querySelectorAll`*`].reduce((a,e,i,t,z=+window.getComputedStyle(e).zIndex||0) => z>a ? z:a ,0);

console.log(z);
<div style="z-index: 100"></div>
<div style="z-index: 3000"></div>
<div style="z-index: 200"></div>

Short

[...document.querySelectorAll`*`]
  .reduce((a,e,i,t,z=+window.getComputedStyle(e).zIndex||0) => z>a ? z:a ,0);

let z = [...document.querySelectorAll`*`].reduce((a,e,i,t,z=+window.getComputedStyle(e).zIndex||0) => z>a ? z:a ,0);

console.log(z);
<div style="z-index: 100"></div>
<div style="z-index: 3000"></div>
<div style="z-index: 200"></div>

献世佛 2024-08-02 15:30:09

使用 mapfilter 的非常简单的代码

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>

Very simple code using map and 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>

泛泛之交 2024-08-02 15:30:09

基于之前的答案:

经过一些修改的函数

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();

Based on previous answers:

function with some modifications

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

Prototype

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

usage

document.querySelector('body').zIndexMax();
风轻花落早 2024-08-02 15:30:09

在浏览了 StackOverflow 上的大量解决方案后,我发现它们都没有真正正常工作,并考虑了 zIndex 实际如何工作。 我编写了一个解决方案,也考虑了堆叠上下文。 你可以参考这个文章 了解堆叠上下文在 CSS 中的工作原理。

const getZIndex = el => {
  const computedStyle = getComputedStyle(el, null)
  const zIndex = computedStyle.getPropertyValue('z-index')
  return zIndex !== 'auto' ? parseInt(zIndex) : null
}

const getZIndexWithinStackingContext = (el, context) => {
  let zIndex = getZIndex(el)
  if (!zIndex) return null

  let result = zIndex

  while (el.parentElement !== context) {
    el = el.parentElement
    zIndex = getZIndex(el)
    if (zIndex) {
      result = zIndex
    }
  }

  return result
}

const createZIndex = (overVisibleOnly = false, context = document.body) => {
  const elements = [...document.querySelectorAll('body *')]
  let highestZIndex = 0

  elements.forEach(el => {
    if (overVisibleOnly) {
      const isVisible = !!el.offsetParent
      if (!isVisible) return
    }

    const zIndex = getZIndexWithinStackingContext(el, context)

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

  return highestZIndex + 1
}

请注意,此解决方案考虑所有元素,而不仅仅是定位元素,因为它们可以在添加某个类后变得定位。 但是您只需添加对位置计算样式属性的检查即可轻松解决此问题。

After looking through a lot of solutions here on StackOverflow - I've seen that none of them actually works correctly and considers how is zIndex actually working. I have written a solution that also takes into consideration the stacking context. You can refer to this article to understand how stacking context works in CSS.

const getZIndex = el => {
  const computedStyle = getComputedStyle(el, null)
  const zIndex = computedStyle.getPropertyValue('z-index')
  return zIndex !== 'auto' ? parseInt(zIndex) : null
}

const getZIndexWithinStackingContext = (el, context) => {
  let zIndex = getZIndex(el)
  if (!zIndex) return null

  let result = zIndex

  while (el.parentElement !== context) {
    el = el.parentElement
    zIndex = getZIndex(el)
    if (zIndex) {
      result = zIndex
    }
  }

  return result
}

const createZIndex = (overVisibleOnly = false, context = document.body) => {
  const elements = [...document.querySelectorAll('body *')]
  let highestZIndex = 0

  elements.forEach(el => {
    if (overVisibleOnly) {
      const isVisible = !!el.offsetParent
      if (!isVisible) return
    }

    const zIndex = getZIndexWithinStackingContext(el, context)

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

  return highestZIndex + 1
}

Note that this solution considers all elements, and not only positioned ones because they can become positioned after some class is added. But you can fix this easily by just adding a check for the position computed style property.

时常饿 2024-08-02 15:30:09

我发现当页面上的 z 索引动态更改时,提供的方法不起作用(当前方法仅获取原始设置的 z 索引)。

此函数还适用于动态添加的 z 索引:

function find_max_z_index() {    
    const all_z = [];
    document.querySelectorAll("*").forEach(function(elem) {
        all_z.push(elem.style.zIndex)
    })
    const max_index = Math.max.apply(null, all_z.map((x) => Number(x)));
    return(max_index)
}

I have found the provided methods don't work when there have been z-indices changed dynamically on the page (the current methods only grab the originally set z-indices).

This function also works with dynamically added z indices:

function find_max_z_index() {    
    const all_z = [];
    document.querySelectorAll("*").forEach(function(elem) {
        all_z.push(elem.style.zIndex)
    })
    const max_index = Math.max.apply(null, all_z.map((x) => Number(x)));
    return(max_index)
}
落在眉间の轻吻 2024-08-02 15:30:09

这是我的两行函数:

const getMaxZIndex = function () {
    const elements = [...document.querySelectorAll("body *")];
    return Math.max(...elements.map(x => parseInt(getComputedStyle(x, null).zIndex) || 0));
};
console.log(getMaxZIndex());

Here is my two-line function:

const getMaxZIndex = function () {
    const elements = [...document.querySelectorAll("body *")];
    return Math.max(...elements.map(x => parseInt(getComputedStyle(x, null).zIndex) || 0));
};
console.log(getMaxZIndex());
童话 2024-08-02 15:30:09

这里只是提供另一种方式。

如果你只是想知道一个元素是否在顶层,
您可以使用 document.elementFromPoint 函数,
返回 (x,y) 坐标处的顶部元素,

例如:

function elevate(node) {
    const e = node
    const r = e.getBoundingClientRect()
    const x = r.x + r.width / 2
    const y = r.y + r.height / 2

    const top = document.elementFromPoint(x, y)
    if (top == e) return true
    e.style.zIndex = (Number(window.getComputedStyle(e).zIndex) || 0) + 1
}

但是,这仅检查元素的中心是否不在
被其他元素覆盖,但不是整个元素。

Just provide another way here.

If you just want to know whether a element is on the top layer,
you can use the document.elementFromPoint function,
which return the top element at (x,y) coordinate

eg:

function elevate(node) {
    const e = node
    const r = e.getBoundingClientRect()
    const x = r.x + r.width / 2
    const y = r.y + r.height / 2

    const top = document.elementFromPoint(x, y)
    if (top == e) return true
    e.style.zIndex = (Number(window.getComputedStyle(e).zIndex) || 0) + 1
}

However, this only check whether the center of the element is not
covered by other element, but not the whole element.

可是我不能没有你 2024-08-02 15:30:08

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

  var maxZ = Math.max.apply(null, 
    $.map($('body *'), function(e,n) {
      if ($(e).css('position') != 'static')
        return parseInt($(e).css('z-index')) || 1;
  }));

Stealing some code from abcoder site for the sake of clarity:

  var maxZ = Math.max.apply(null, 
    $.map($('body *'), function(e,n) {
      if ($(e).css('position') != 'static')
        return parseInt($(e).css('z-index')) || 1;
  }));
我家小可爱 2024-08-02 15:30:08

您可以为特定元素类型(例如

)调用 findHighestZIndex,如下所示:

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;
}

You could call findHighestZIndex for a particular element type such as <div> like this:

findHighestZIndex('div');

assuming a findHighestZindex function that is defined like this:

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;
}
弱骨蛰伏 2024-08-02 15:30:08

使用 ES6 更简洁的方法

function maxZIndex() {

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

Using ES6 a cleaner approach

function maxZIndex() {

     return Array.from(document.querySelectorAll('body *'))
           .map(a => parseFloat(window.getComputedStyle(a).zIndex))
           .filter(a => !isNaN(a))
           .sort()
           .pop();
}
仙女 2024-08-02 15:30:08

我想添加我在用户脚本之一中使用的 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找出当前的最高ZIndex 值与所有元素的所有其他计算的z 索引之间的最大值。 过滤器排除所有“auto”值。

I’d like to add my ECMAScript 6 implementation that I use in one of my UserScripts. I’m using this one to define the z-index of specific elements so that they always appear the highest.

In JS, you can additionally set certain attributes or class names to elements that you may want to exclude. For instance, consider your script setting a data-highest attribute on an element that you want to appear as the highest element (e.g. a popup); and consider an element with class name yetHigher that you don’t control, which should be even higher (e.g. a custom context menu). I can exclude these elements with a chained :not selector. Note that :not([data-highest], .yetHigher) is possible, but experimental, and only has limited browser support as of January 2021.

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))
);

The lower five lines can run multiple times and update the variable highestZIndex repeatedly by finding out the maximum between the current highestZIndex value and all the other computed z-indexes of all elements. The filter excludes all the "auto" values.

北音执念 2024-08-02 15:30:08

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

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

I believe what you are observing is Voodoo. Without access to your complete style sheet I can of course not tell reliably; but it strikes me as likely that what really has happened here is that you have forgotten that only positioned elements are affected by z-index.

Additionally, z-indexes aren't assigned automatically, only in style sheets, which means that with no other z-indexed elements, z-index:1; will be on top of everything else.

风蛊 2024-08-02 15:30:08

我想你必须自己做这件事......

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;
}

I guess you have to do this yourself ...

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文