Flash里面有个很好的特性是,一个容器里,不存在实际对象的部分,不会阻拦鼠标事件穿透到下一层。
前端就不一样了,两个div层叠以后,上层div会接收到所有事件(即使这个div里面内容是空的,没有任何实际对象),下层div什么事件都接不到。
举个例子:
这个示意图中
C方块在A容器中(A容器边框为红色)
D方块在B容器中(B容器边框为绿色)
A B部分重叠,B在上层。
不做任何处理的话,C方块永远无法被点到,因为B把它盖住了。
下面,我将给出一种方案,在不改变页面结构的情况下,让CD都能得到正常相应。
主要利用的是css中的pointer-events属性
语法:
pointer-events:auto | none | visiblepainted | visiblefill | visiblestroke | visible | painted | fill | stroke | all
默认值:auto
适用于:所有元素
继承性:有
动画性:否
计算值:指定值
取值:
- auto:
- 与pointer-events属性未指定时的表现效果相同。在svg内容上与
visiblepainted
值相同 - none:
- 元素永远不会成为鼠标事件的target。但是,当其后代元素的pointer-events属性指定其他值时,鼠标事件可以指向后代元素,在这种情况下,鼠标事件将在捕获或冒泡阶触发父元素的事件侦听器。
- 其他值只能应用在SVG上。
- 参考链接:http://www.css88.com/book/css/properties/user-interface/pointer-events.htm
- 注意,这个属性部分旧版浏览器可能不支持。
- 我注意到,设置为none之后,其子元素仍然可以通过显式设置auto来响应鼠标事件,那么我们可以将A B容器都设置为none,不响应鼠标事件,同时,将CD显式设置为auto,让他们响应鼠标事件,这样一来,B就不会挡住A了,下面是具体代码
<!DOCTYPE html> <html> <head> <title>Test position</title> <style type="text/css"> .a { position: absolute; border: solid 1px red; width: 400px; height: 400px; left: 0px; pointer-events:none; } .b { position: absolute; border: solid 1px green; width: 400px; height: 400px; left: 200px; pointer-events:none; } .a1 { position: absolute; width: 100px; height: 100px; background: red; left: 250px; top: 50px; pointer-events:auto; } .b1 { position: absolute; width: 100px; height: 100px; background: green; left: 50px; top: 250px; pointer-events:auto; } </style> </head> <body> <div class="a" onclick="onclicka()"> <div class="a1"></div> </div> <div class="b" onclick="onclickb()"> <div class="b1"></div> </div> <script type="text/javascript"> function onclicka() { console.log('click a'); } function onclickb() { console.log('click b'); } </script> </body> </html>
结果如下:
搞定收工。