楔子

在前端的开发中,我们都是直接与用户接触,应该尽量让用户感到操作畅快愉悦,获得类似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

CSS pointer-events属性的使用相关推荐

  1. 把鼠标、触摸屏、触控笔统一起来,Pointer Events介绍

    跨设备的问题 平时我们在电脑上访问的网页,大部分情况下是用鼠标来控制的.比如说链接跳转,就是鼠标指针移动到链接文字或图片的位置,然后点击一下.又比如说滚动屏幕,滑动一下鼠标滚轮就可以. 如果是供手机访 ...

  2. CSS的浮动属性,详细学习指南

    前言 腾讯的面试凉了,接着开始面试网易 网易的面试体验挺不错.它的微信公众号会给你叫号,前台小姐姐也会提醒你,每一面结束后都可以找前台小姐姐查询面试结果.而且食堂超级好吃!还可以边吃饭边吸猫!面试地点 ...

  3. CSS的浮动属性,附架构师必备技术详解

    前言 本文主要是javascript和css方面的基础面试题,适合面试前以及平时复习食用. 基础知识是前端一面必问的,如果你在基础知识这一块翻车了,就算你框架玩的再6,webpack.git.node ...

  4. DIV css中cursor属性详解-鼠标移到图片变换鼠标形状 (转)

    css中cursor属性详解-鼠标移到图片变换鼠标形状 语法:  cursor : auto | all-scroll | col-resize| crosshair | default | hand ...

  5. 巧用CSS的Border属性

    . 作者:冯永曜 来源:黄山村夫 制作过网页的人都有为画线而烦恼的经历,本文介绍的小技巧也许对你有所帮助.我们先来认识一下"Border"(画边框),它是CSS的一个属性,用它可以 ...

  6. CSS中background-position属性

    CSS中background属性是经常用到的,可以给某个块设置背景色.以下主要说明以下background-position属性的应用. 一般在设置background属性时的写法是: backgro ...

  7. CSS中连接属性的排序

    在CSS超链接的属性中,有四个连接方式: a:link  a:hover a:visited a:acticve 之前在使用的时候一直是按照自认为的顺序中去写的,就是 L H V A的排序方式,然而有 ...

  8. html图片加波浪滤镜,CSS滤镜wave属性(波形滤镜)

    [实例介绍] CSS滤镜wave属性(波形滤镜) wave滤镜用来把对象按照垂直的波纹样式打乱.waVe的表达式还是比较复杂的,它一共有5个参数. [基本语法] filter:wave(add=参数值 ...

  9. CSS使用浮动属性和边距设计3行3列定宽的布局实例

    CSS使用浮动属性和边距设计3行3列定宽的布局 下面使用CSS的浮动属性和边距属性设计一个简单地3行3列并且是固定宽度的布局页面. 实例 设计步骤如下: 1. 制作3行3列定宽布局的XHTML部分.源 ...

  10. CSS中float属性详解

    首先我们了解到,CSS网页布局的原理,就是按照HTML代码中对象声明的顺序,以流布局的方式来显示它,而流布局就不得不说到float浮动技术..在HTML中的所有对象,默认分为两种:块元素(block ...

最新文章

  1. 2022-2028年中国数字化制造产业研究及前瞻分析报告
  2. R语言单因素方差分析与协方差分析
  3. 2018 年最值得期待的学术进展——致人工智能研究者们的年终总结
  4. 记录mysql的配置表误删
  5. python爬虫-利用代理ip访问网页(urllib)
  6. BZOJ1734: [Usaco2005 Feb]Aggressive cows 愤怒的牛
  7. 训练效率低?GPU利用率上不去?快来看看别人家的tricks吧~
  8. 桌面消息提醒_手机消息总是延迟,真的是网速不行?3招教你找出捣鬼设置
  9. Alarm:IT界朋友请珍惜你的身体[转贴]
  10. IDEA导入JDBC驱动的jar包
  11. PHP、MySQL分库分表中间件、支持协程
  12. linux如何撤销权限修改,linux 撤销权限
  13. Python 圆拟合
  14. 汇编语言||存储单元,存储字长,存储字,存储容量的理解
  15. 第四章 变形-学习笔记+练习题
  16. pthread_cond_wait和pthread_cond_signal函数详解
  17. nodejs c++ addon插件的应用场景
  18. 25 行 Python 代码实现人脸检测——OpenCV 技术教程
  19. uefi启动 多硬盘gtp_UEFI+GPT双硬盘安装Win10+Ubuntu16.04双系统
  20. 【Pytorch】对比matual,mm和bmm函数

热门文章

  1. Java多线程(4)--线程的同步解决线程安全问题
  2. 远程连接Oracle 数据库连接报错ORA-12638身份检索失败
  3. linux常用命令:touch 命令
  4. 跨域/非跨域接口专题
  5. Visual C++中MFC消息的分类
  6. 【坑】执行Consumer的时候发生java.net.UnknownHostException错误
  7. 《无码的青春》第四章 程序员的二象性,左手流氓,右手疯子
  8. Coder-Strike 2014 - Finals (online edition, Div. 2) A. Pasha and Hamsters
  9. UVAlive 6131 dp+斜率优化
  10. matplotlib plt.subplot