最近有学员问我苹果公众号中的伸长返回功能的实现方法,苹果的案例里用到了我称之为事件双重触发的技巧,这个技巧最早是在@科蝌的公众号中提出的,他巧妙地利用事件穿透原理实现了动画的双重触发,从而实现了以往要用ID或者JS才能实现的开关动画效果,今天行哥就来刨析一下这个技巧的实现原理。

事件穿透原理

要理解事件双重触发先要明白什么是事件穿透,所谓事件穿透就是利用click事件在移动设备上触发有300ms左右延迟的特性,我们可以在touchstart事件中快速移除当前层元素,让事件短时间内穿透到下层从而触发下层的click动画,请参考下图示意。

event2
事件穿透原理演示
<!-- 事件穿透 -->
<svg style="height:0;">
  <rect>
    <animate 
      attributeName="opacity" 
      to="0" 
      begin="click" 
      dur="1s">
    </animate>
  </rect>
</svg>
<svg>
  <rect>
    <animate 
      attributeName="visibility" 
      to="hidden" 
      begin="touchstart" 
      dur="0.001ms">
    </animate>
  </rect>
</svg>

事件的双重触发

事件双重触发就是将开和关2个状态动画写在一起,系统会根据事件选择执行其中之一,拿苹果的图文伸缩动画为例。

<svg>
  <!-- 伸长动画 -->
  <animate 
    attributeName="width" 
    values="100%;100%;200%" 
    begin="touchstart" 
    fill="freeze" 
    dur="0.75s"
  ></animate>
  <!-- 返回动画 -->
  <animate 
    attributeName="width" 
    values="200%;100%;100%" 
    begin="click" 
    fill="freeze" 
    dur="0.75s"
  ></animate>
</svg>

当我们将这2段开关动画写在一起时,我们会发现系统只选择touchstart事件动画执行而选择性忽略了click事件动画,这是因为touchstart没有click事件的延迟,这就好比2个人前后脚到蛋糕店买蛋糕,而这时蛋糕店只剩下一块蛋糕,老板自然是会给先到店的那个人。

在执行了伸长动画后,我们怎么让返回动画执行呢?这就要利用上面介绍过的事件穿透模型,我们要在当前层之上制造一个挡板层,让系统选择click事件动画执行而忽略touchstart动画。

还是拿刚才蛋糕店的例子,现在我们通过”事件穿透”这层朋友关系让老板把蛋糕给晚进店的那个人。

总结

通过事件双重触发可以实现一些状态切换的开关效果,如图文的伸长和返回,弹窗的弹出和关闭等,还是许愿哦要配合一些防误触和遮挡的技巧,篇幅所限大家可以直接查看本文的源码来学习。