🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
>[success] # 小程序事件 1. 小程序需要经常和**用户进行某种交互**,比如点击界面上的某个按钮或者区域,比如滑动了 个区域; 2. 事件是**视图层到逻辑层的通讯方式**; 3. 事件**可以将用户的行为反馈到逻辑层进行处理**; 4. 事件**可以绑定在组件上,当触发事件时,就会执行逻辑层中对应的事件处理函数**; 5. 事件对象**可以携带额外信息**,如 id, dataset, touches; >[danger] ##### 图解处理过程 * [# 微信小程序的基本原理](https://juejin.cn/post/7024872361048408077) ![](https://img.kancloud.cn/22/9a/229a002582a8f91291d059ec5e76ab79_807x566.png) >[danger] ##### 如何使用 1. 事件是通过`bind/catch`这个属性绑定在组件上的(和普通的属性写法很相似, 以key=“value”形式); 2. `key`以`bind`或`catch`开头, 从1.5.0版本开始, 可以在`bind`和`catch`后加上一个冒号; 3. 同时在当前页面的`Page`构造器中定义对应的事件处理函数, 如果没有对应的函数, 触发事件时会报错; 4. 当用户点击该button区域时,达到触发条件生成事件tap,该事件处理函数会被执行,同时还会收到一个事件对象`event` | 类型 | 触发条件 | 最低版本 | | --- | --- | --- | | touchstart | 手指触摸动作开始 | | | touchmove | 手指触摸后移动 | | | touchcancel | 手指触摸动作被打断,如来电提醒,弹窗 | | | touchend | 手指触摸动作结束 | | | tap | 手指触摸后马上离开 | | | longpress | 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 | [1.5.0](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html) | | longtap | 手指触摸后,超过350ms再离开(推荐使用 longpress 事件代替) | | | transitionend | 会在 WXSS transition 或 wx.createAnimation 动画结束后触发 | | | animationstart | 会在一个 WXSS animation 动画开始时触发 | | | animationiteration | 会在一个 WXSS animation 一次迭代结束时触发 | | | animationend | 会在一个 WXSS animation 动画完成时触发 | | | touchforcechange | 在支持 3D Touch 的 iPhone 设备,重按时会触发 | [1.9.90](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html) | 5. 某些组件会有自己特性的事件类型,比如**input**有**bindinput/bindblur/bindfocus**等,**scroll-view**有**bindscrolltowpper/bindscrolltolower**等 >[danger] ##### 简单案例 * index.wxml ~~~html <!-- 使用 tap 手指触摸后马上离开(等同于click点击) --> <view bindtap="tapAddCount"> tap 点击事件 {{count}} </view> ~~~ * index.js ~~~js Page({ /** * 页面的初始数据 */ data: { count:0, }, tapAddCount(){ let count = ++ this.data.count this.setData({ count:count }) } }) ~~~ >[info] ## 事件中的event 对象 1. 当某个事件触发时, 会产生一个事件对象, 并且这个对象被传入到回调函数中 ![](https://img.kancloud.cn/d6/fd/d6fdec1b81b52d18cd342c3e404552ef_695x241.png) | 属性 | 类型 | 说明 | 基础库版本 | | --- | --- | --- | --- | | [type](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html#type) | String | 事件类型 | | | [timeStamp](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html#timeStamp) | Integer | 事件生成时的时间戳 | | | [target](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html#target) | Object | 触发事件的组件的一些属性值集合 | | | [currentTarget](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html#currenttarget) | Object | 当前组件的一些属性值集合 | | | [mark](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html#mark) | Object | 事件标记数据 | [2.7.1](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html) | >[danger] ##### currentTarget和target 属性说明 1. `target `作为触发事件的元素 2. `currentTarget` 作为处理事件的元素,从这取值最靠谱 * 在非冒泡的情况下 二者是一样的,下面打印结果都为`t` ~~~html <!-- currentTarget和target 在非冒泡的情况下 --> <view bindtap="tapTarget" id="t"> currentTarget和target </view> ~~~ ~~~js Page({ tapTarget(e){ const tId = e.target.id const cId = e.currentTarget.id console.log(tId) // t console.log(cId) // t } }) ~~~ * 冒泡触发的情况下 ![](https://img.kancloud.cn/48/a9/48a9380516b68e2db3428755c84970d9_246x214.png) ~~~ <!-- 冒泡情况下 currentTarget和target--> <view id="outter" bindtap="tapTarget" style="height: 200px;width:200px;background-color: red;display: flex;justify-content: center;align-items: center;" > <view id="inner" style="height: 50px;width:50px;background-color: yellowgreen;"> </view> </view> ~~~ ~~~js Page({ tapTarget(e){ const tId = e.target.id const cId = e.currentTarget.id console.log(tId) // inner console.log(cId) // outter } }) ~~~ >[danger] ##### touches和changedTouches的区别 1. `touches `当前屏幕上所有触摸点的列表 2. `changedTouches` 触发事件时改变的触摸点的集合 ![](https://img.kancloud.cn/48/d9/48d95e2965b291d9389d5c08496e2c29_627x459.png) >[info] ## 事件参数的传递 1. 当视图层发生事件时,某些情况需要事件携带一些参数到执行的函数中, 这个时候就可以通过`data-`属性来完成 2. 获取:`e.currentTarget.dataset.属性的名称` 来获取 3. 在 WXML 中,这些自定义数据以`data-`开头,多个单词由连字符`-`连接。这种写法中,连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。如: * `data-element-type`,最终会呈现为`event.currentTarget.dataset.elementType`; * `data-elementType`,最终会呈现为`event.currentTarget.dataset.elementtype` >[danger] ##### 案例一 ~~~html <!-- 事件触发案例 --> <button bindtap="getParams" data-name="w" data-age="12"> 点击传参 </button> ~~~ ~~~ Page({ getParams(e){ const {name,age} = e.currentTarget.dataset console.log(name,age) // w 12 } }) ~~~ >[danger] ##### 案例二 ![](https://img.kancloud.cn/10/d3/10d34f998615ce580cf5a91f99db07dd_465x67.png) ~~~html <!-- 做一个tab 切换 --> <view class="tab"> <block wx:for="{{tabs}}" wx:key="item"> <view class="tab-item" bindtap="tapTab" data-index="{{index}}"> <text class="tab-item-text {{ index==tabIndex? 'active':''}}">{{item}}</text> </view> </block> </view> ~~~ * index.js ~~~ Page({ data: { tabs:["数学","语文","英语","物理"], tabIndex:0 }, tapTab(e){ const {index} = e.currentTarget.dataset this.setData({ tabIndex:index }) }, }) ~~~ * index.wxss ~~~ .tab{ display: flex; line-height: 32px; height: 32px; } .tab-item{ flex: 1; text-align: center; } .tab-item-text{ padding: 5px; } .tab-item-text.active{ border-bottom: 2px solid yellowgreen; } ~~~ >[info] ## 事件冒泡 1. 使用`bind` 去绑定事件会产生事件冒泡,如果想产生的是事件捕获可以用`capture-bind`绑定事件 ![](https://img.kancloud.cn/7e/da/7edaf757ee1aed319e7d6867fe34dacd_922x714.png) 2. 使用 `mark` 属性获取冒泡上的所有值,事件冒泡路径上所有的`mark`会被合并,并返回给事件回调函数。(即使事件不是冒泡事件,也会`mark`。) ![](https://img.kancloud.cn/0e/62/0e62f0dc5d5c1581a669830b0bc6ebb7_396x33.png) ~~~html <view mark:myMark="last" bindtap="bindViewTap"> <button mark:anotherMark="leaf" bindtap="bindButtonTap">按钮</button> </view> ~~~ ~~~js Page({ bindViewTap: function(e) { console.log( e.mark ) }, bindButtonTap(){}, }) ~~~ >[danger] ##### 案例 ~~~html <view class="view1" capture-bind:tap="onView1CaptureTap" bindtap="onView1Tap"> <view class="view2" capture-bind:tap="onView2CaptureTap" bindtap="onView2Tap"> <view class="view3" capture-bind:tap="onView3CaptureTap" bindtap="onView3Tap"></view> </view> </view> ~~~