CSS pointer-events属性的使用

楔子

在前端的开发中,我们都是直接与用户接触,应该尽量让用户感到操作畅快愉悦,获得类似native的感觉。其中动画是最常用的方法。

这里的需求是,弹层的设计,这个弹层希望可以像 native 上的弹层一样,点击按钮出现,点击遮罩或按钮时关闭,并且出现和关闭时有动画效果(fade,slide等)。

问题

在关闭弹层时,以fadeOut动画效果为例,我这里是利用opacity从1 -> 0的过程模拟逐渐消失的动画过程,container是弹层组件最外层容器:

.container {position: fixed;left: 0;top: 0;width: 100%;height: 100%;z-index: 9999;animation: .5s fadeOut forwards;
}
@keyframes fadeOut {0% {opacity: 1;}100% {opacity: 0;}
}

问题是opacity为0只是container内的元素透明不可见的,container仍然存在于dom节点中。当我们给弹层的蒙层mask绑定关闭事件时,由于container的z-index非常大,点击事件都会触发在mask上。

transitionend和animationend事件

为了解决上述问题,同时让用户体验更好,我们可以通过监听transitionend和animationend事件等动画效果执行完再将container节点隐藏(display:none)。这样就不会出现mask拦截点击事件的问题了。

简介

采用CSS技术生成的动画效果,我们可以在JS中捕获动画或变换的结束事件:transitionend和animationend事件标准的浏览器事件。 transitionend 事件会在 CSS transition 结束后触发。
animationend 事件会在一个 CSS 动画完成时触发(不包括完成前就已终止的情况,例如元素变得不可见或者动画从元素中移除)。

代码示例:

/** 在container元素上监听transitionend事件* 然后指定一个函数, 例如 showMessage()*/
function showMessage() {console.log('Transition 已完成');
}var element = document.getElementById("container");
element.addEventListener("transitionend", showMessage, false);

浏览器兼容性

以transitionend事件为例,animationend事件相似。

可以看出,在WebKit浏览器里仍然需要使用webkit前缀,所以我们需要根据各种浏览器分别检测事件。

缺点

我的需求是,这个弹层组件可能会频繁调用,即用户关闭弹层后,会再次打开。
使用这种方案,通过监听动画结束事件,在display:none和display:block之间切换,但是这会增加浏览器渲染(重绘和重排)成本,且要考虑浏览器兼容性,需要根据各种浏览器分别检测事件。

pointer-events CSS 属性

有没有更优雅更简单的解决呢?下面介绍我们的主角:pointer-events。
需要注意的是,这个pointer-events不同于Pointer Events(用于处理来自设备(包括鼠标,笔,触摸屏等)的硬件指针输入的事件和相关接口)。

简介

The ‘pointer-events’ property specifies under what circumstances a given graphics element can be the target element for a pointer event. It affects the circumstances under which the following are processed:

  • user interface events such as mouse clicks
  • dynamic pseudo-classes (i.e., :hover, :active and :focus; [CSS2], section 5.11)
  • hyperlinks

简而言之,pointer-events CSS 属性指定在什么情况下 (如果有) 某个特定的图形元素可以成为鼠标事件的 target。

规范

Its extension to HTML elements, though present in early drafts of CSS Basic User Interface Module Level 3, has been pushed to its level 4.

它主要针对的是SVG,但已经扩展到其他html元素。

语法

/* Keyword values */
pointer-events: auto;
pointer-events: none;
pointer-events: visiblePainted; /* SVG only */
pointer-events: visibleFill;    /* SVG only */
pointer-events: visibleStroke;  /* SVG only */
pointer-events: visible;        /* SVG only */
pointer-events: painted;        /* SVG only */
pointer-events: fill;           /* SVG only */
pointer-events: stroke;         /* SVG only */
pointer-events: all;            /* SVG only */

比如说,pointer-events: visibleFill;
这个只适用于SVG,只有在元素的visibility属性为visible时,且鼠标指针在元素内部时,元素才会成为鼠标事件的目标,fill属性不影响事件处理。
其他只适用于SVG的属性介绍不再赘述,可以参考 这里 。

在这里我们更关注[auto|none]两个属性值。这两个属性值用在其他html元素上也很有意思。
当值为auto时。与pointer-events属性未指定时的表现效果相同,对于SVG内容,该值与visiblePainted效果相同。
当值为none时,元素永远不会成为鼠标事件的target。换而言之,值none表示鼠标事件“穿透”该元素并且指定该元素“下面”的任何东西。

浏览器兼容性

可以看出,pointer-events兼容绝大多数移动端浏览器,且没有前缀要求。

注意的点

当pointer-events值为none时,不一定说明该元素的事件监听事件永远不会被触发。如果他的子元素有明确的设定pointer-events属性,且指定自己能成为鼠标事件的目标,那么触发的过程会通过事件冒泡传到父元素,父元素的事件监听事件就会被触发。

总结

在弹层组件可能会频繁调用的情况下,使用pointer-events方案,即点击遮罩或按钮时关闭时,设置container动画效果和pointer-events:none,弹层出现时,再设置pointer-events:auto。这样只需改变css的属性即可解决问题。

若有不对之处或其他更优雅的解决办法,欢迎各位的指正和交流。


更多专业前端知识,请上 【猿2048】www.mk2048.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解JavaScript之Event Loop

前言 最近阅读《高性能JavaScript》时,第六章谈到“通过定时器将JavaScript执行代码的控制权先让给浏览器用于更新UI状态,然后再将控制权交回给JavaScript代码,这样就可以使得页面更为流畅”,就联想到了之前理解的事件循环。 这…

使用EasyPoi导出Excel

Excel模板来自自己写死的一个excel模板,相当于是用户查询数据,数据填充到一个模板的Excel里,再导出Excel /*创建模板*/String a request.getSession().getServletContext().getRealPath("/resource/河南能源化工集团安全监控系统联网系统…

Hazelcast入门

7月,我写了一个博客向Java开发人员介绍erlang,重点介绍了这两种语言之间的一些异同。 erlang虚拟机具有许多令人印象深刻的内置功能,其中之一是它们独立于位置并且可以互相通信。 这意味着可以通过编写很少的代码行在VM之间同步数据。 如果您…

android手机最低内存,原神手机端需要哪些配置 手机端最低配置要求介绍

原神是一款由米哈游自主研发的全新开放世界冒险游戏,游戏最近迎来了pc端的首次测试,而且在不久之后就会开启原神手机端的公测版本,那么手机端需要什么配置呢?小编带来了详细的介绍。移动端预下载:9月25日下午16&#x…

AnswerOpenCV一周佳作欣赏(0615-0622)

一、How to make auto-adjustments(brightness and contrast) for image Android Opencv Image Correctionim using OpenCV for Android. I would like to know,how to make image correction(auto adjustments of brightness/contrast) for image(bitmap) in android via Open…

所有其他指标均无用

对于队列,无论是实现为JMS ,数据库表(即Ruby的Delayed :: Job用于队列的什么),甚至是Amazon的SQS ,用于评估队列状态的最常见指标是其长度。 从本质上讲,可以基于在任何给定时间队列中驻留多少消…

类似苹果数据线的android,除了常见的安卓、苹果、Type-c,还有哪些你不知道的手机数据线?...

随着智能手机日益发展,辅助智能手机的数据线配件也越来越多样。现在我们最常见的无非就是标准Micro usb口、正反随便插的Type-c接口、还有苹果Lightning数据线,那么除了这些类型数据线,你知道如今市面上还有哪些更方便好用的手机数据线吗&…

canvas入门实战--邀请卡生成与下载

1.前言 写了很多的javascript和css3的文章,是时候写一篇canvas的了。canvas是html5提供的一个新的功能!至于作用,就是一个画布。然后画笔就是javascript。canvas的用途非常的广,特别是html5游戏以及数据可视化这两个方面。现在can…

Apache ActiveMQ 5.9发布

Apache ActiveMQ团队刚刚发布了新的ActiveMQ 5.9版本 。 Apache ActiveMQ 5.9发布 自从先前的5.8版本以来,此版本是8个月的辛苦工作。 在此发行版中,我们将像往常一样对代理进行增强,并使用最新的协议(例如AMQP和MQTT&#xff…

android 美颜录像,Android 关于美颜/滤镜 利用PBO从OpenGL录制视频

前言上次我写了一遍文章《Android 关于美颜/滤镜 从OpenGl录制视频的一种方案》,里面利用ImageReader来从获取Surface上获取数据,但是经过熊皮皮的提醒,我发现多PBO的确可以实现跟ImageReader一样的效果,并且版本要求仅为Android4…

Java对象到对象映射器

我在该项目上使用了Dozer一段时间。 但是,最近我遇到了一个非常有趣的错误,它促使我环顾四周,并尝试使用其他“对象到对象”映射器。 这是我找到的工具列表: 推土机:推土机是Java Bean到Java Bean的映射器&#xff…

android媒体播放框架,Android 使用超简单的多媒体播放器JiaoZiVideoPlayer

在之前的项目中用到了视频播放的功能,在网上看了看使用了大家用的比较多的一个开源项目JiaoZiVideo可以迅速的实现视频播放的相关功能。JiaoZiVideo的简单使用集成了JiaoZiVideo后仅需这几行代码就可以实现播放视频JZVideoPlayerStandard jzVideoPlayerStandard (J…

送福利:ROKID 语音开发板免费送,开启你的物联网之旅

都让一让,我说个事情:掘金联合 Rokid 开发者社区给大家发福利啦! 掘金联合 Rokid 开发者社区为大家准备了一些福利,只要秀出你的 skill 和技术栈,就有可能获得 Rokid 全栈语音智能开发套件。 ? Rokid开箱试用活动 活…

如何使用JavaScript控制台改进工作流程

作为Web开发人员,很有必要了解如何调试代码。后台开发我们经常使用外部库来记录日志,并在某些情况下格式化显示日志,前端我们会使用断点和控制台,但是我们浏览器的控制台比我们想象的要强大得多。 当我们考虑控制台时&#xff0c…

select、poll、epoll之间的区别总结[整理]

原文:https://www.cnblogs.com/Anker/p/3265058.html 好文章收藏下,慢慢品味 select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者…

JPA(七):映射关联关系------映射双向多对一的关联关系

映射双向多对一的关联关系 修改Customer.java package com.dx.jpa.singlemanytoone;import java.util.Date; import java.util.HashSet; import java.util.Set;import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; impo…

如何优雅的绘制一棵省市区三级可选择的树?

开始 总结一下 开发过程中的思路想法 各位大佬们看看就好 首先你拥有的数据结构 所有省市区的信息列表 以及已经选中的信息 用的是element-ui的 el-tree const cityStorage {provinceList:[{id: 1, provinceId: "110000", name: "北京市"}],//所有省ci…

html click事件 参数,vue 实现click同时传入事件对象和自定义参数

这篇文章主要介绍了vue 实现click同时传入事件对象和自定义参数,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧仅仅传入自定义参数HTMLdddddJS代码new Vue({el:#app,methods:{tm:function(e){console.log(e);}}})仅仅传入事件对象HTML…

Android学习(七)—— Android布局

Android布局 1、LinearLayout 线性布局,这种布局在平时的开发中用的最多,内部控件只能水平或竖直进行排列,在搭建较复杂的界面时会有点麻烦。 常用属性 android:orientation 控制控件排列方向,属性值为垂直(vertical…

不一样的ZTree,权限树.js插件

每一个有趣的创新,都源于苦逼的生活。在最近的工作中,遇到一个做权限管理筛选的需求。 简单总结需求: 1展示一个组织中的组织结构 2通过点击组织结构中的任意一个节点可以向上向下查询对应的组织结构 如果你不想苦逼的重复劳动,还…