微信小程序开发(七):事件与冒泡


本篇笔记部分内容整理自网络中的一些文章及视频,详见文末的“参考资料”部分。存在部分AI生成的内容,请仔细甄别可能存在的错误。



一、初识小程序事件

在小程序中,事件是视图层到逻辑层的通讯方式

往往是由视图层触发某个动作,以某种联系方式关联到逻辑层的一个方法上面,逻辑层进行对应的处理并将结果反馈到视图层。这其中的“动作”就是所谓的事件。点击按钮、滑动页面,包括不是由用户出发的操作如视频播放结束、到达某个时间点等等,都可以看做是一个个的事件,综合来说,小程序中的事件由用户行为反馈事件组件状态反馈事件两部分组成。

最简单的点击事件

1
<button bindtap="alert">bindtap</button>   <!-- 这里写成bind:tap也可以  -->
1
2
3
4
5
6
7
8
9
10
11
Page({
data: {},

alert: function (event) {
wx.showToast({
title: '触发成功', // 标题
icon: 'success', // 图标类型,默认success
duration: 1500 // 提示窗停留时间,默认1500ms
})
}
})

这段代码调用了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
<button bindtap="alert" id="btn" data-name="听风是风" data-age="27">bindtap</button>
1
2
3
4
5
6
Page({
data: {},
alert: function (event) {
console.log(event);
}
})

这样可以在点击事件触发后,在控制台看到这个事件的所有信息。

四、hover-class 与 hover-style

虽然手指头没有鼠标一样“悬浮”的概念,无法在小程序中使用hover伪类,但是我们可以使用hover-classhover-style定义用户按住元素时的样式;例如大多数按钮被点击瞬间的灰色效果,就可以使用这个属性来实现。

1
2
3
4
5
6
7
8
<button hover-class="onBtnPressed">点击我<button>

<style>
.onBtnPressed{
background-color: grey;
border: solid 2px grey;
}
</style>

五、事件冒泡与事件捕获

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="parent">
父元素
<div class="child">
子元素
</div>
</div>

<style>
.parent{
width: 200px;
height: 200px;
background-color: #bbded6;
}
.child{
width: 100px;
height: 100px;
background-color: rgba(255,80,47,1);
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var parent = document.querySelector(".parent"),
child = document.querySelector(".child");

// 1. 父元素捕获阶段触发(第三个参数 true)
parent.addEventListener("click", function () {
console.log("A");
}, true);

// 2. 父元素冒泡阶段触发(第三个参数 false 或省略)
parent.addEventListener("click", function () {
console.log("B");
});

// 3. 子元素捕获阶段触发(第三个参数 true)
child.addEventListener("click", function () {
console.log("D");
}, true);

// 4. 子元素冒泡阶段触发(第三个参数 false 或省略)
child.addEventListener("click", function () {
console.log("C");
}, false);

关于addEventListener

addEventListener事件监听参数以及含义:

1
2
3
element.addEventListener(event,function() {
// 事件处理程序
},useCapture);

其中eventfunction为必填,event表示事件类型,function为事件处理函数,而useCapture为选填,它的值为Boolean值。用于指定事件是否在捕获或者冒泡阶段执行,默认为false,即在冒泡阶段执行,反之在捕获阶段执行。

事件流顺序

  1. 捕获阶段(Capturing Phase)(从外向内):
    • 检查parent是否有捕获阶段监听器(useCapture: true),执行A
    • 检查child是否有捕获阶段监听器,执行D
  2. 目标阶段(Target Phase)
    • 执行child本身的监听器(DC)。
  3. 冒泡阶段(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
2
3
4
5
6
<view id="parent" catch:tap="tap1" >
父元素
<view id="child" catch:tap="tap3" >
子元素
</view>
</view>

点击子元素,可以发现只输出了tap3,成功阻止了点击事件向上冒泡触发父元素的tap事件。再看下面的例子:

1
2
3
4
5
6
<view id="parent" bind:tap="tap1" capture-catch:tap="tap2">
父元素
<view id="child" bind:tap="tap3" capture-catch:tap="tap4">
子元素
</view>
</view>

使用capture-catch中断事件的捕获阶段和取消冒泡事件;这时无论点击父元素还是子元素都只会输出tap2

总结

  • bind不会阻止冒泡,但如果想抓捕获阶段,可以添加前缀capture,也就是capture-bind
  • catch会阻止冒泡,如果添加capture前缀,捕获阶段会中断的同时,也会阻止冒泡。

参考资料

  1. 听风是风.从零开始的微信小程序入门教程(四)[EB/OL].(2020-05-02)[2025-08-16]. https://www.cnblogs.com/echolun/p/12817733.html

微信小程序开发(七):事件与冒泡
http://blog.morely.top/2025/08/17/微信小程序开发(七):事件与冒泡/
作者
陌离
发布于
2025年8月17日
许可协议