关于css中pointer-events属性的怪异行为

时间:2023-03-09 07:38:21
关于css中pointer-events属性的怪异行为

在我的记忆中pointer-events就是用来进行事件穿透的,也就是说,如果给父元素设置了pointer-events:none,那么父元素不再监听鼠标事件事件(类似于touch,click这样的)。

需要这样做的情况,通常是我们想“穿透”父层,直接点击子元素时,父元素会当作什么也没有发生一样。这是我以前的知识体系中所收集的信息。现在看来也没有错,只是这不完整。

它是有副作用的,或者说,上面的知识应用是有条件的。当我们在属于父子关系的元素上应用这个(pointer-events:none)属性,确实是这个行为,但是如果当我们作用在平行层的两个块元素上的时候,它还是这样子吗?

关于css中pointer-events属性的怪异行为

这个问题就是由上面这个截图所示的应用所引出的。我稍后在给出简化的原型。先简单介绍一下这个场景演示的问题。上图其实是有四个层的:

作为页面容器的page层以及page下面的花花草草所组成的子层,为了后面的演示方便,取名为pagesub层。

另一层是用来进行左右翻页的按钮层,这一层和page层是并列的,取名为float层,因为看起来像是浮在page上面。float层下面有一个叫floatsub层,用来包装小蘑菇按钮。

我希望点击小蘑菇的时候,不会触发float层上的事件,于是我给float层加上了pointer-events:none;那么问题来了,现在我点小蘑茹没有反应。经过监听,发现点到的是page里边的花花草草层。我百思不得其姐,经过一翻激烈的追求,终于得到真爱。下面我就公布这一充满曲折的求姐过程:

关于css中pointer-events属性的怪异行为

pagesub是page的子元素,floatpage是float 的子元素,它们的位置关系如上图所示。其中绿色的page就是页面层,蓝色的pagesub就是花花草草层。红色的float就是按钮层

灰色的float page就是蘑菇层。(色盲的朋友看文字就好了)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
body {
text-align: center;
}
.page {
position: absolute;
top : 0;
left:0;
height: 400px;
background-color: green;
width:500px;
z-index: 2;
} .float {
width: 400px;
height: 200px;
position: absolute;
top:50px;
left: 50px;
z-index: 3;
pointer-events:none;
background-color: red;
} .pagesub {
width: 90%;
height: 60%;
position: absolute;
top:30px;
left: 10px;
z-index: 4;
background-color: blue;
color:white;
} .floatsub {
width:80%;
height: 60%;
position: absolute;
top:33px;
left:44px;
background-color: gray;
z-index: 4;
color: white;
}
</style>
</head>
<body> <div class="page">
page
<div class="pagesub">
pagesub
</div>
</div> <div class="float">
float
<div class="floatsub">
float page
</div>
</div>
</body>
</html>

根据上面的源码,在chrome中进行调式,发现,当我在float page(灰色)层查看元素的时候,居然显示是蓝色的pagesub层。简直没有天理了,有图有真相:

关于css中pointer-events属性的怪异行为

但是当我试着把pointer-events这个属性去掉的时候,奇迹出现了,一切回归预期。这是为什么呢?说明pointer-events 会影响绝对定位的层及关系!当然,前提条件是并列关系,而不是父子关系。在并列关系的元素上使用pointer-events,会造成后面的元素被忽视掉。

注意我这里说的“绝对定位的层及关系” 是指看起来像是用了pointer-events:none属性的元素跑到没有用的元素的后面去了,而至于底层是不是真的发生了这样的情况,我没法去证实,但是测试的结果表明就是这样的现象。

除了none之外,顺道提一下pointer-events:的其它几个属性;

  • auto------- 默认值,鼠标不会穿透当前层
  • 针对SVG的: visiblePainted*visibleFill*visibleStroke*visible*,painted*fill*stroke*all*

好了,本次分享就到这里了,发贴辛苦!