浅析微信小程序的事件机制

知晓程序是爱范儿旗下专注小程序生态的品牌,我们已经做了这些:

  • 知晓程序公众号(微信号 zxcx0101):做最好的小程序媒体,让你了解小程序的一切
  • 小程序商店(minapp.com):全网首家小程序商店,已吸引海量小程序入驻,数量仍在不断增长中
  • 未来小程序活动矩阵:包含黑客马拉松、MindTalk 、WorkShop,创造多样的小程序交流分享空间
  • 《微信小程序入门指南电子书》:全网首本小程序电子书已在多看阅读、微信读书、QQ 阅读上架

文 | 一斤代码

事件机制是一种非常典型的通讯方式。有了它,你可以令代码中的不同对象互相传递信息,也可以在应用的不同层面进行沟通协作。

今天我们来看一下微信小程序框架提供的事件处理机制。

小程序官方文档对事件的定义是:

  • 事件是视图层到逻辑层的通信方式;
  • 事件可以将用户的行为反馈到逻辑层进行处理;
  • 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数;
  • 事件对象可以携带额外信息,如 iddatasettouches

从这里我们可以看到,官方文档主要将事件用于小程序中针对用户交互行为的处理,即视图层(WXML)到逻辑层(Page)的通信,逻辑层收到这些用户行为事件后,可以进行业务处理,然后根据情况反馈或不反馈结果给用户。

好,那我们今天就撇开事件的其他用法,专门就讲视图层和逻辑层之间的事件用法。

在视图层绑定事件

总体上来说,小程序中的事件机制在工作原理上来讲,和 HTML DOM 的事件机制是一致的。在 HTML 中,我们可以通过在 HTML 元素上设置一个如 onclick="clickHandler(event)" 的属性来绑定用户的页面点击事件处理函数。

而在 WXML 中,我们为一个组件绑定一个事件处理函数,可以使用如下语法来完成:

这里的 bindtap 就可以理解为将点击事件绑定到一个名为 tapName 的事件处理函数上来进行处理。然后在相应的 Page 代码中,我们需要定义这个 tapName 函数:

这样完成了一个简单的点击事件的处理。当我们在小程序的界面上去点击这个显示为 Click me 的 view 组件的时候:

  • view 组件捕获到这个点击动作,然后告诉 Page 中的 tapName 函数,要对这个动作进行处理;
  • 同时,这个组件也为 tapName 函数提供了足够多的信息,也就是 event 对象,来帮助我们更好更精准的处理我们的业务逻辑。

我们可以来看一下我们这个例子中的 event 对象里面包含了哪些内容:

这里我们可以看到,在 event 对象中,包含了事件的名称,事件目标对象的信息,以及事件发生的在界面上的位置信息等等。

我们在组件上设置的 data-hi 属性的值,也在 target 中的 dataset 上被携带了过来,这是比较有用的。在实际开发中,我们可以利用这个特性,来传递更多视图层的信息到逻辑层进行处理。

事件的继承和冒泡

如果你有 DOM 编程的经验,你就会在这里想到,小程序里事件的冒泡和非冒泡是怎么处理的?

如果你还不了解什么是事件冒泡,那我在这里解释一下:

在 HTML 或者 WXML 这些基于 XML 的树形结构的界面布局方式中,元素与元素之间是有层级关系的。

子级元素上触发的事件,可以向父级元素逐层向上传递。所以,父级元素上也可以捕获子级元素上的事件并进行逻辑处理。

这种事件冒泡的机制,在实际的开发中也经常会用到,所以我们有必要来了解下在小程序中,是如何来使用冒泡事件的。WXML 中分别提供了两种方式,用来绑定事件处理函数:

  • 使用 bind 开头的事件绑定,这种绑定不会阻止冒泡事件向上冒泡;
  • 使用 catch 开头的事件绑定,这种绑定可以阻止冒泡事件向上冒泡。

直观起见,我们直接来看一个示例代码:

在这个示例代码中,有三个逐级嵌套的 view 元素,最里层的是 content 元素,最外层的为 outer-container 元素。

最里层和最外层的元素上,使用了 bind 属性绑定了 tap 事件的处理函数,而中间的 innner-container 上,使用了 catch 属性进行 tap 事件绑定。

然后,我们尝试在 content 上点击一下,可以看到这样的结果:

contentinner-container 元素的 tap 事件处理函数被执行了,而 outer-container 元素的没有被执行。这说明在点击 content 的过程中,产生的 tap 事件向父级元素传递。

而作为 content 元素的父级元素 inner-container, 它使用了能阻止事件冒泡的 catch 方式,所以它在捕获通过冒泡形式过来的子级元素事件并执行事件处理函数后,让该事件停止向上传递。

因此,同样是父级元素的 outer-contaner,就不再能收到这个冒泡事件了。

然后,来看一下,在不同层级的元素捕获的 event 对象,在数据方面有什么特点:

我们可以看到,在 contenttap 事件处理函数中,event 里面的 targetcurrentTargetid 都是 content

而在 inner-container 中的 event 对象里,targetidcontent,而 currentTargetidinner-content

由此我们可以知道,event 对象中的 target 是事件产生的源头组件,而 currentTarget 则是当前捕获这个事件的组件。

event 对象中还包含其他一些有用的信息,如 toucheschangedTouches 表示一个或多个手指在屏幕上的触摸位置和变动位置等信息,可以用来实现多点触摸的高级手势处理。

最后,关于事件冒泡,有一点是值得注意一下的:在微信小程序中,并不是所有事件都是冒泡的。

比如,官方文档提到,<canvas> 组件的触摸事件是不可冒泡的。

原文地址:http://www.jianshu.com/p/6b2005ddfb8f

本文由知晓程序授权转载,关注微信号 zxcx0101,回复「1228」获得全网第一本《小程序入门指南》电子书。

原文发布于微信公众号 - 知晓程序(zxcx0101)

原文发表时间:2017-01-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IMWeb前端团队

微信小程序之购物车功能

本文作者:IMWeb 林鑫 原文出处:IMWeb社区 未经同意,禁止转载 前言 以往的购物车,基本都是通过大量的 DOM 操作来实现。微信小程序其实跟...

3439
来自专栏ThoughtWorks

使用Enzyme测试React(Native)组件|洞见

组件化与UI测试 在组件化出现之前,我们不谈UI的单元测试,哪怕是对于UI页面进行测试都是一件非常困难的事情。其实组件化并不完全是为了复用,很多情况下也恰恰是为...

2844
来自专栏前端新视界

如何在已有的 Web 应用中使用 ReactJS

当我们学习一项新技术,可能是一个 JavaScript 框架,也可能是一个 CSS 方法,我们将面对这样的挑战 如何在旧网站上运用这项新技术?。很多教程讲述了如...

580
来自专栏web前端教室

风继续吹&&先行者成员:王广铎(duo 二声)的作业分析,从他的作业理解“React单向数据流”

他的作业:“分页组件”React版,写的很好,主要是思路很清晰。本来是想上周日视频课程直播的时候讲一下了,现在只能是放在文章中大概的说说了。先看截图, ? 很...

1868
来自专栏技术总结

UIKit Dynamics 置身真实世界

23810
来自专栏vue学习

11、组件入门及写个首页头部组件

前言:项目准备工作说了很久,不知道大家学会了没有?今天开始我们开始正式搭建页面,先从首页开始,在搭建页面的过程中,我也会将vue的知识点在其中穿插讲解,但是你最...

862
来自专栏彭湖湾的编程世界

【响应式】foundation栅格布局的“尝鲜”与“填坑”

提到响应式,就不得不提两个响应式框架——bootstrap和foundation。在标题上我已经说明白啦,今天给大家介绍的是foundation框架。 何为“尝...

30511
来自专栏司想君

React编程思想

能够按照构建的方式来思考web app的实现,是React众多优点之一。在这篇文章中,我们将引导你进行使用React构建可搜索产品数据表的思考过程。

4815
来自专栏前端达人

前沿动态 | 带你提前体验CSS未来的新特性

本篇文章,Rachel Andrew将会带着大家了解下浏览器在CSS方面的未来动向, 例如Flexbox行和列布局支持gap间隙属性的标准。

803
来自专栏Charlie's Road

UIKit Dynamics:开始入门 —《Graphics & Animation系列一》

翻译自raywenderlich网站iOS教程Graphics & Animation系列 介绍 UIKit Dynamics是一个集成到UIKit中的完整物理...

813

扫码关注云+社区