• 纯CSS属性pointer-events:none解决滚动穿透问题


    ·什么是滚动穿透:

    在移动端的前端开发中,我们常常会用到Modal弹窗,又称模态框,用来在已有页面显示新的选项、提示或新内容。遮罩层常出现在弹窗后,用来在视觉上,帮助用户集中注意力,功能上,防止用户继续操作页面上的其他内容。遮罩层通常是一个绝对定位,宽高充满内容区域或可视区域,层级略低于弹窗的具有一定透明度的背景。

    在Web端,我们只需要通过CSS设置上述属性,就可以完成实现“遮罩实现”的功能,但当用户使用鼠标滚轮,或者在移动端,通过手指滑动时,我们发现:

    位于遮罩层背后的内容,穿透了我们设置的遮罩层,跟随用户的操作发生滚动。这种现象,就被称为“滚动穿透”。

    ·你可能会想到的解决滚动穿透问题的方法:

    看到这种由非直接目标对象响应事件的现象,很多人都会想到 Js的事件处理机制,进而想到,阻止事件冒泡,避免对Modal弹窗层的操作,冒泡到遮罩层下。

    然而这种思路并不总是行得通,冒泡的前提,是两个对象具有父子关系,事件从子对象传递到父对象,然而我们的弹出层经常被直接append到body或根节点中,与原有内容在一个层级,用阻止冒泡的方法并不能达成目的。

    事实上,位于遮罩层下方的可滚动元素和上方的弹出层,由于重叠,直接响应了用户的操作,而不是接受上层的事件传递。

    那我们可不可以阻止默认事件呢?

    通过preventDefault()阻止默认事件,任何通常被该实现触发并作为结果的默认行为都不会发生,上层和下层元素的默认滚动行为都将被阻止,这显然并不是我们想要的。

    此外,还有很都方法,通过十几行甚至几十行代码,在移动端,阻止滚动穿透,有点大材小用啦。

    ·化繁为简,一行CSS3属性解决滚动穿透问题

    让我们先认识这个CSS3属性 pointer-events,它的默认属性值是auto,而对于前端开发,另一个值 none,显然更有用。通过设置:

    pointer-events: none
    
    > 元素永远不会成为鼠标事件的target。但是,当其后代元素的pointer-events属性指定其他值时,鼠标事件可以指向后代元素,在这种情况下,鼠标事件将在捕获或冒泡阶段触发父元素的事件侦听器。

    将MDN的解释形象化,你可以把设置 pointer-events: none 看成一张透明纸,它本身不再响应鼠标事件(事实上,也包括移动的手指触摸Touch事件),却可以传递事件,让事件穿过它自己,继续传到父级。

    简而言之,我们想让哪层不滚动,只需要给这层设置 pointer-events: none 。

    配合弹窗的状态,当弹窗显示的时候,给位于遮罩层底下的图层设置  pointer-events: none ,当弹窗隐藏/关闭的时候,设置  pointer-events: auto ,或者干脆移除这个属性。

    pointer-events 是一个比较早公布的CSS3属性,在Web端和移动端都有良好的支持度:

     
    CSS3的属性pointer-events的浏览器和移动端兼容性图示
    CSS3的属性pointer-events的浏览器和移动端兼容性图示
  • 相关阅读:
    托词坚持了170多天,昨天因为晚上打球竟然给忘了
    2013转眼间半年过去了,回顾一下。也看一下计划的实施情况以及下半年的计划
    开始新的板子PCB绘制了。
    致时代前行者:致敬每一个奔腾不息的心灵(转)
    刚才看了年初的计划,增加一部分内容
    五种男人
    哪些行业会用到乐泰胶水?
    第一个python小程序
    一个简单的IPmsg程序源码分析(一)
    关于linux下面printf函数缓冲区问题
  • 原文地址:https://www.cnblogs.com/ygunoil/p/12765420.html
Copyright © 2020-2023  润新知