为了将包含透明文本图像的div设置为文档中的最高z索引,我选择了10,000,它解决了我的问题。
以前我猜过数字3,但没有效果。
因此,是否有更科学的方法来确定哪个z索引比您所有其他元素的z索引高?
我尝试在Firebug中寻找此指标,但找不到。
为了将包含透明文本图像的div设置为文档中的最高z索引,我选择了10,000,它解决了我的问题。
以前我猜过数字3,但没有效果。
因此,是否有更科学的方法来确定哪个z索引比您所有其他元素的z索引高?
我尝试在Firebug中寻找此指标,但找不到。
Answers:
您可以像这样调用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;
}
findHighestZIndex
,它将获得所有元素。
为了清楚起见,从abcoder站点窃取了一些代码:
var maxZ = Math.max.apply(null,
$.map($('body *'), function(e,n) {
if ($(e).css('position') != 'static')
return parseInt($(e).css('z-index')) || 1;
}));
Math.max
:“如果数组包含太多元素,两者都会传播(...)
,apply
否则将失败或返回错误的结果”
Math.max
在Chrome上最多可以接受100,000个参数,在Firefox上可以接受300,000个参数,在Edge上可以接受400,000个参数,在IE11上可以接受150,000个参数(在Win10上经过测试,所有浏览器都是最新的)。
使用ES6更清洁的方法
function maxZIndex() {
return Array.from(document.querySelectorAll('body *'))
.map(a => parseFloat(window.getComputedStyle(a).zIndex))
.filter(a => !isNaN(a))
.sort()
.pop();
}
[2 ,1, 100].sort()
给出结果[1, 100, 2]
错误的。请改用比较器:[2 ,1, 100].sort((a,b) => a-b)
这样比较正确[1, 2, 100]
sort
似乎有很多不必要的cpu和内存消耗
reduce
只会通过索引集去一次这样O = n
,尽管sort
有O = n log(n)
。因此,人们可以很容易地更换sort
和pop
使用reduce
。
.sort((a,b) => a-b)
为@AdamSzmyd说使它工作。
我想添加在一个UserScript中使用的ECMAScript 6实现。我正在使用这一z-index
元素来定义特定元素,以使它们始终显示为最高。我可以使用链接的:not
选择器排除这些元素。
let highestZIndex = 0;
// 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索引。在filter
排除所有的"auto"
值。
Math.max
要做到这一点:“既传播(...)
和apply
要么失败或返回错误的结果,如果数组有太多元素[...]将降低解决方案不存在这个问题”
在我看来,解决此问题的最佳方法是为自己设定约定,以将z-index
不同类型的元素用于不同类型的元素。然后,z-index
通过回顾文档,您将找到正确的使用方法。
我想你必须自己做...
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;
}
element.style.zIndex
找不到在外部样式表中设置的z索引。谷歌getComputedStyle
寻找那些。
使用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;
}
我最近不得不为一个项目执行此操作,发现从@Philippe Gerber的出色答案和@flo的出色答案(已接受的答案)中受益匪浅。
与上述参考答案的主要区别在于:
z-index
和任何内联z-index
样式都将被计算,并使用两者中较大的一个进行比较和计算。auto
,static
,等)将被忽略。这是代码示例的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>
这里是另一种解决方案,以确定最上面的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)
getComputedStyle
和style
对象由节点本身提供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 *"));
我们一定不要忘记自定义元素和影子根目录内容。
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;
}
上面的“ ES6”版本比第一个解决方案效率低,因为它在整个阵列上进行了多次冗余传递。而是尝试:
findHighestZ = () => [...document.querySelectorAll('body *')]
.map(elt => parseFloat(getComputedStyle(elt).zIndex))
.reduce((z, highest=Number.MIN_SAFE_INTEGER) =>
isNaN(z) || z < highest ? highest : z
)
从理论上讲,在一个减少的步骤中执行此操作甚至会更快,但是一些快速基准测试没有明显区别,并且代码更加粗糙
如果要显示具有最高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
}]
一个受@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>
position: relative; z-index: 10000;
位于的元素之内position: relative; z-index: 100;
,则您需要击败的数字是100,而不是10,000。