微信小程序开发(七):事件与冒泡
本篇笔记部分内容整理自网络中的一些文章及视频,详见文末的“参考资料”部分。存在部分AI生成的内容,请仔细甄别可能存在的错误。
一、初识小程序事件
在小程序中,事件是视图层到逻辑层的通讯方式。
往往是由视图层触发某个动作,以某种联系方式关联到逻辑层的一个方法上面,逻辑层进行对应的处理并将结果反馈到视图层。这其中的“动作”就是所谓的事件。点击按钮、滑动页面,包括不是由用户出发的操作如视频播放结束、到达某个时间点等等,都可以看做是一个个的事件,综合来说,小程序中的事件由用户行为反馈事件和组件状态反馈事件两部分组成。
最简单的点击事件
1 |
|
1 |
|
这段代码调用了wx.showToast
的提示接口,点击按钮后会弹出一个toast提示,效果如下图:
二、常见事件类型
事件类型 | 触发条件 |
---|---|
touchstart | 手指触摸动作开始触发 |
touchmove | 手指触摸后移动触发 |
touchcancel | 手指触摸动作被打断,如来电提醒,弹窗 |
touchend | 手指触摸动作结束 |
tap | 手指触摸后马上离开 |
longpress | 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发(与tap同时定义,优先级更高) |
longtap | 手指触摸后,超过350ms再离开(推荐使用longpress事件代替) |
transitionend | 在 WXSS transition 或 wx.createAnimation 动画结束后触发 |
animationstart | 在 WXSS animation 动画开始时触发 |
animationiteration | 在 WXSS animation 一次迭代结束时触发 |
animationend | 在 WXSS animation 动画完成时触发 |
三、常用事件对象
属性 | 类型 | 说明 |
---|---|---|
type | String | 当前绑定的事件类型 |
timeStamp | Integer | 页面打开到触发事件所经过的毫秒数 |
target | Object | 触发事件的组件的一些属性值集合 |
currentTarget | Object | 当前组件的一些属性值集合 |
detail | Object | 额外的信息 |
touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
1 |
|
1 |
|
这样可以在点击事件触发后,在控制台看到这个事件的所有信息。
四、hover-class 与 hover-style
虽然手指头没有鼠标一样“悬浮”的概念,无法在小程序中使用hover
伪类,但是我们可以使用hover-class
和hover-style
定义用户按住元素时的样式;例如大多数按钮被点击瞬间的灰色效果,就可以使用这个属性来实现。
1 |
|
五、事件冒泡与事件捕获
1 |
|
1 |
|
关于addEventListener
addEventListener
事件监听参数以及含义:
1 |
|
其中event
与function
为必填,event
表示事件类型,function
为事件处理函数,而useCapture
为选填,它的值为Boolean
值。用于指定事件是否在捕获或者冒泡阶段执行,默认为false
,即在冒泡阶段执行,反之在捕获阶段执行。
事件流顺序
- 捕获阶段(Capturing Phase)(从外向内):
- 检查
parent
是否有捕获阶段监听器(useCapture: true
),执行A
。 - 检查
child
是否有捕获阶段监听器,执行D
。
- 检查
- 目标阶段(Target Phase):
- 执行
child
本身的监听器(D
和C
)。
- 执行
- 冒泡阶段(Bubbling Phase)(从内向外):
- 检查
child
是否有冒泡阶段监听器(useCapture: false
),执行C
。 - 检查
parent
是否有冒泡阶段监听器,执行B
。
- 检查
最终输出顺序
点击子元素,控制台输出顺序为:A → D → C → B
小程序中的事件冒泡与事件捕获
在微信小程序中,事件同样存在捕获与冒泡阶段。比如我们前面所说的bind
前缀就表示事件在冒泡阶段执行,在bind
前面加上capture
,即capture-bind
就表示捕获阶段执行。
如果我们分别给父子绑定bind事件,点子区域,会先执行子的bind
再执行父的bind
,毕竟我们没使用capture
定义捕获阶段,所以全程就只有冒泡。需要记住的,bind不会阻止冒泡,添加capture前缀可以响应捕获阶段。
某些情况下,我们需要阻止一个事件的冒泡,例如点击弹窗外部的遮罩层会关闭弹窗,但是点击弹窗内部的事件也会冒泡倒外部的遮罩层,使得弹窗被关闭。这时应该在弹窗上阻止点击事件的向外冒泡。将bind
替换为catch
事件可以阻止冒泡,见下例:
1 |
|
点击子元素
,可以发现只输出了tap3
,成功阻止了点击事件向上冒泡触发父元素的tap
事件。再看下面的例子:
1 |
|
使用capture-catch
中断事件的捕获阶段和取消冒泡事件;这时无论点击父元素还是子元素都只会输出tap2
。
总结
bind
不会阻止冒泡,但如果想抓捕获阶段,可以添加前缀capture
,也就是capture-bind
。catch
会阻止冒泡,如果添加capture
前缀,捕获阶段会中断的同时,也会阻止冒泡。
参考资料
- 听风是风.从零开始的微信小程序入门教程(四)[EB/OL].(2020-05-02)[2025-08-16]. https://www.cnblogs.com/echolun/p/12817733.html ↩