场景:uniapp框架优化小程序项目中,发现了一个movable-area相关的事件穿透的问题,先整理下业务逻辑,在线客服通过小图标的展现形式悬浮在页面上,小程序初始化时赋一个初始坐标位置,用户可以在页面中随意拖动在线客服图标位置,防止阻挡到页面的正常展示或者事件的触发,拖动以后全局记录拖动坐标,切换页面保持当前拖动后的坐标位置
由于app和小程序的架构是逻辑层与视图层分离,使用js监听拖动时会引发逻辑层和视图层的频繁通讯,影响性能。所以为了方便高性能的实现拖动,使用了uniapp中的movable-area组件。需注意movable-view必须在movable-area组件中,并且必须是直接子节点,否则不能移动。这就导致了在开发组件的时候必须要考虑fixed定位后如何让movable-area不显示,还要让movable-view中的在线客服在页面层的上面显示。
思路一:理论上的最佳层级关系是:在线客服图标层级 (movable-view)> 页面层 > 在线客服的拖动范围层(movable-area) ,在保证在线客服图标fixed定位的情况下不影响页面层的逻辑事件,那么问题来了,fixed定位的元素(movable-area)z-index如果小于其他页面层的z-index,那fixed定位的(movable-area)中的子元素(movable-view)z-index无论怎么设置都不能超过页面层展示。这种情况其实也有解决方案,把movable-area写在组件外,在每个引用在线客服的页面最外层包一个movable-area(把页面层和movable-view包在movable-area里面),但是这种情况就导致了很多页面都需要写一层movable-area包裹当前页面元素,所以不推荐这种方式
思路二:把movable-area放在页面层上方(movable-area的z-index > 页面层的z-index),这种布局方式可以解决图标的显示问题,但是会影响到页面层的点击事件,于是就用到了css的pointer-events,以前一直没用过,这种情景下真是让人眼前一亮,没聊结果pointer-events的可以参考下张鑫旭大佬的文章,介绍的比较清晰明了,CSS3 pointer-events:none应用举例及扩展
完美解决这种情况,既不影响movable-area fixed定位下图标的展示和点击 又不影响页面层的点击事件