小程序之冒泡事件,catch与bind区别

本文探讨了小程序中冒泡事件的概念,以tap事件为例,详细解释了bindtap和catchtap的区别。bindtap仅检测事件,而catchtap不仅能检测还阻止事件冒泡。事件响应实际发生在冒泡过程中,捕获阶段(capture-bind或capture-catch)先于冒泡阶段,并且一旦使用catch,后续冒泡将被中止。文中提供了官方示例以辅助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  所谓的冒泡事件就是事件触发后会一层一层向上传递,使所有的包含其子元素的父级元素都触发该事件。而哪些事件属于冒泡事件是由微信官方所定义好的,列表如下

类型触发条件最低版本
touchstart手指触摸动作开始 
touchmove手指触摸后移动 
touchcancel手指触摸动作被打断,如来电提醒,弹窗 
touchend手指触摸动作结束 
tap手指触摸后马上离开 
longpress手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发1.5.0
longtap手指触摸后,超过350ms再离开(推荐使用longpress事件代替) 
transitionend会在 WXSS transition 或 wx.createAnimation 动画结束后触发 
animationstart会在一个 WXSS animation 动画开始时触发 
animationiteration会在一个 WXSS animation 一次迭代结束时触发 
animationend会在一个 WXSS animation 动画完成时触发 
touchforcechange在支持 3D Touch 的 iPhone 设备,重按时会触发

 

  现在就拿tap为例,tap如列表所示,是一个冒泡事件,那么bindtap和catchtap的区别是什么呢?

  想要理解区别,首先从bind和catch本身的中文含义理解比较简单,bind就是绑定的意思,catch就是抓获的意思。所以bindtap只是会检测组件有没有触发tap,而catchtap不仅会检测tap,而且还会抓获tap,使其不会继续向上冒泡。

  说到底,bindtap和catchtap并非是在用户按下按钮的那一霎那响应,而是在冒泡的过程中响应的,真正在抓获用户按下去那一霎那响应其实是要写成capture-bind:或是capture-catch:,抓获阶段在冒泡阶段的前面,同理,若在抓获阶段使用了catch则后面的过程都会中止。

  附上官方的例子:

  

在下面的代码中,点击 inner view 会先后调用handleTap2handleTap4handleTap3handleTap1

<view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2">
  outer view
  <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
    inner view
  </view>
</view>

如果将上面代码中的第一个capture-bind改为capture-catch,将只触发handleTap2

<view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2">
  outer view
  <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
    inner view
  </view>
</view>
### 微信小程序冒泡事件的参数传递机制 在微信小程序中,事件冒泡是一种常见的行为模式,允许子组件触发的事件沿着 DOM 树向上传递给父级组件。这种机制可以通过 `bind` `catch` 关键字来控制事件的行为以及参数的传递。 #### 1. **事件冒泡的基础** 事件冒泡是指当一个子节点上的事件被触发时,该事件会依次传播到其所有的祖先节点上[^1]。如果希望某个特定事件只影响当前节点而不向上冒泡,则可以使用 `catch` 来捕获并停止事件进一步传播。 #### 2. **参数传递的方式** 在微信小程序中,事件对象通常携带了一个名为 `detail` 的属性,用于存储自定义数据。开发者可以在 WXML 中通过设置 `data-*` 属性或者直接绑定动态变量的形式,在事件发生时将这些数据作为参数传递给处理函数。 以下是具体的实现方式: - 使用 `data-*` 自定义属性: 可以在标签内添加类似于 HTML5 的 `data-*` 数据集属性,并将其赋值为字符串或其他简单类型的值。 - 动态绑定表达式: 如果需要更复杂的逻辑运算或模型驱动的数据流管理,可以直接利用 Mustache 表达式的语法 `${}` 把 JavaScript 对象成员嵌入模板之中。 #### 3. **代码示例** 下面是一个完整的例子展示如何在一个按钮点击事件中通过冒泡机制完成跨层次间的信息交换过程: ```html <!-- index.wxml --> <view bindtap="handleParentEvent"> Parent View <button catchtap="handleChildEvent" data-id="childButton">Click Me</button> </view> ``` ```javascript // index.js Page({ handleParentEvent(e) { console.log('Parent Event Triggered:', e.detail); }, handleChildEvent(e) { const id = e.currentTarget.dataset.id; this.triggerEvent('customBubble', { messageId: 'Message from child' }, {}); // 向外抛出自定义事件 // 或者手动构造 detail 并重新分发新的事件供上级监听器消费 let newDetail = Object.assign({}, e.detail, { customDataField: true }); wx.event.dispatch(this, 'bubbleUpward', newDetail); return false; // 阻断后续默认动作链路执行路径 } }); ``` 上述案例展示了两个层面的操作——子控件内部先做局部响应再主动发起新一轮带有额外负载的消息广播;此同时由于采用了 `catchtap` 而不是普通的 `bindtap` ,所以能够有效抑制不必要的二次触碰反馈现象出现。 #### 4. **注意事项** 需要注意的是,尽管 Vue 等框架支持 `.stopPropagation()` 方法用来显式终止事件扩散链条,但在微信小程序环境下并不适用此 API 。取而代之的做法就是采用前述提到过的基于关键字区分策略(`bind vs catch`)来进行精细化调控[^2]。 另外提醒一点关于性能优化方面的小技巧:尽量减少无谓的深层结构布局设计以免造成过多冗余计算开销从而拖慢整体渲染速度。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值