请选择 进入手机版 | 继续访问电脑版
虚位以待    招租QQ:244594752    尺寸:960x60
终身VIP需技术指导请加(官方QQ :244594752 )
加入我们,终身VIP只需159元,全站下载(老客户请联系我补差价即可升级)
查看: 350|回复: 1

javascript 寻找当前页面中最大的 z-index 值的方法

[复制链接]

该用户从未签到

2275

主题

2307

帖子

8053

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
8053
发表于 2018-6-1 22:25:49 | 显示全部楼层 |阅读模式

我们在写类似 toast 这样的组件的时候,会希望我们的弹出层在当前页面的最上层,也就是说,希望 z-index 值为最大。所以,我们需要找到当前页面中最大的 z-index 值,然后把这个值 +1 即可。

我们先来想一想思路。

我们可以把 DOM 中的所有元素集合起来,然后转化成一个数组,然后我们遍历这个数组,把所有元素的 z-index 值提取出来,然后就形成了一个纯数字的数组,最后从中取到最大值,就是当前页面中的最大的 z-index 值了。

好,将我们的思路,转化为代码,我们一个一个来解决。

将思路转化为代码找到所有的元素,转化为数组

方法1:

Array.from(document.querySelectorAll('body *'))
  • 1

我们用 querySelectorAll 形成的是一个类数组结构,但不是数组,不支持数组方法。因此,使用 Array.from 方法,将它转化为真正的数组。

方法2:

Array.from(document.body.querySelectorAll('*'))
  • 1

嗯,没什么区别,但是这样比上面好看一点。从性能上,要比第一种要强一点点。

方法3:

[...document.body.querySelectorAll('*')]
  • 1

用 ES6 方法,将类数组转化为数组。

方法4:

[...document.all]
  • 1

从 body 中寻找,和从全部中寻找,性能差异几乎没差,关键是,代码好看了许多。就酱紫。

查找元素的 Z-INDEX 值

下面示例中 __DOM__ 为伪代码,指 dom 元素。

方法1(错误示范):

__DOM__.style.zIndex
  • 1

嗯,这样只能找到行内样式中的 z-index 值,如果是写在 css 文件中的,那么就找不到了。

所以,这是一个错误的示范。

方法2:

我们要找到元素的真实 css 属性,就必须使用 window.getComputedStyle() 方法。

window.getComputedStyle(__DOM__).zIndex
  • 1

这样,我们就可以拿到元素的 z-index 值了。但是问题是,我们拿到的不一定是一个数字,而可能是 auto 这样的字符串值,我们就需要处理一下了。

逻辑非常简单,就是将这个值转化为数字,如果是 NaN 就覆盖为 0 ,否则,就给原值即可。

// 正常写法Number(window.getComputedStyle(__DOM__).zIndex) || 0// 简写写法+window.getComputedStyle(__DOM__).zIndex || 0
  • 1
  • 2
  • 3
  • 4
  • 5

数组中寻找最大值

这个没什么难度了。

方法1:

Math.max.apply(null, arr)
  • 1

这个是一贯的寻找最大值的方法。

方法2:

Math.max(...arr)
  • 1

其实和第一种一样,不过是 ES6 的写法罢了。

方法3:

arr.reduce((num1, num2) => {    return num1 > num2 ? num1 : num2})
  • 1
  • 2
  • 3

reduce 方法是一个比较高级的方法,它会把数组序号 0 的值和数组序号 1 的值用自定义的函数进行计算,然后将返回的结果,和数组序号 3 的值再次进行自定义函数的计算,直到数组里的每一个值都计算完成。

上面的代码就是一个简单的对比函数。

至于其他 for 循环,以及排序方法就不赘述了。

好,两个本质问题解决,下面我们来组装代码。

查找当前页面 z-index 最大值实现代码

方法1

var arr = [...document.all].map(e => +window.getComputedStyle(e).zIndex || 0)return arr.length ? Math.max(...arr) : 0
  • 1
  • 2

如上,我们轻松的实现了效果。

这里需要注意的是,Math.max() 方法如果对一个空数组进行处理,是会出错的,所以上面进行了一个数组长度判断,来避免出错。

方法2

前面用的方法,是我们之前的设想的思路,我感觉这个思路是大多数人都可以想到的。

但是这个方法,先整了一个数组,然后再在数组里面寻找最大值,我感觉这个运算量还是比较大的,我就想,可以不可以用更轻的运算,来实现这个功能。

我们来看一下,上面说的,我们从一组数组中寻找最大值的方法的方法3,reduce() 方法。我们是不是可以直接进行运算呢?说干就干,代码如下:

return [...document.all].reduce((r, e) => Math.max(r, +window.getComputedStyle(e).zIndex || 0), 0)
  • 1

我们知道,如果是空数组的话,用 reduce 是会出错的,所以,我们需要加上一个默认的计算值—— 0 。如下图所示:

initialValue可选
用作第一个调用 callback 的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

这样,就可以避免为空的时候的错误了。

document.all 在获取元素类数组的时候,即便为空页面,也是可以得到非空的数组的。但是,我们写代码,一定要考虑异常状况。

小结

我听说这个题目是某些公司的面试题,然后我就思考了一下,写出了本文。和大多数写博客的人不一样,我不太喜欢一上来就扔一段代码给大家,我更希望把自己的思路给说清楚,这样便于大家理解。更重要的是,希望大家可以从我的思路中学习到解决问题的方法,而不仅仅是复制一段代码。

遇到问题,首先要做的是分析问题,把一个大的问题,拆分成几个小的问题,然后逐个的把这些小的问题解决,最终,把大问题给解决。

如果问题得到了解决,我们就需要尝试换一个思路,看看这个问题能不能用其他的思路来解决,无论这个其他的思路是有效的,还是无效的,亦或者是能效比不高的,都没有关系。举一反三的思考问题,才能使我们的学习更加进步。

本文由FungLeo原创,允许转载,但转载必须附带首发链接。


回复

使用道具 举报

该用户从未签到

0

主题

180

帖子

366

积分

禁止发言

积分
366
发表于 2018-8-23 02:24:56 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|妙想源码社区 积分提现

GMT+8, 2019-11-22 01:03 , Processed in 1.135225 second(s), 24 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2020 Comsenz Inc.

快速回复 返回顶部 返回列表
 
FDGDF
客服QQ 妙想科技 244594752
【旺旺】 点击这里给我发消息
【邮箱】
244594752@qq.com
【地址】 湖南省常德市武陵区三姑巷77
【妙想科技】 【9188qhl.com】