目录
2、CustomEvent 自定义事件对象属性列表(继承 BaseEvent):
3、TouchEvent 触摸事件对象属性列表(继承 BaseEvent):
一、什么是事件
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset, touches。
二、事件分类
1、WXS原生事件
以bind
或catch
开头,然后跟上事件的类型,如bindtap
、catchtouchstart
。
2、自定义事件
bind
和catch
后可以紧跟一个冒号,如bind:tap
、catch:touchstart
。
注意:根据目前我遇到的情况得出一个结论——截止目前版本,所谓的自定义事件,只是把WXS原生事件的bind后加了一个冒号,做形式上的区别,感觉没卵用,净是花拳绣腿。
3、冒泡事件
当一个组件上的事件被触发后,该事件会向父节点传递。
4、非冒泡事件
当一个组件上的事件被触发后,该事件不会向父节点传递。
三、事件 冒泡
bind
事件绑定不会阻止冒泡事件向上冒泡;catch
事件绑定可以阻止冒泡事件向上冒泡。
四、事件 捕获
- 触摸类事件支持捕获阶段;
- 捕获阶段位于冒泡阶段之前;
- 需要在捕获阶段监听事件时,可以采用
capture-bind
、capture-catch
关键字,后者将中断捕获阶段和取消冒泡阶段。
案列:
在下面的代码中,点击 inner view 会先后调用handleTap2
、handleTap4
、handleTap3
、handleTap1
。
<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>
五、事件对象
1、BaseEvent 基础事件对象属性列表:
属性 | 类型 | 说明 |
---|---|---|
type | String | 事件类型 |
timeStamp | Integer | 事件生成时的时间戳 |
target | Object | 触发事件的组件的一些属性值集合 |
currentTarget | Object | 当前组件的一些属性值集合 |
mark | Object | 事件标记数据 |
2、CustomEvent 自定义事件对象属性列表(继承 BaseEvent):
属性 | 类型 | 说明 |
---|---|---|
detail | Object | 额外的信息 |
3、TouchEvent 触摸事件对象属性列表(继承 BaseEvent):
属性 | 类型 | 说明 |
---|---|---|
touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
4、特殊事件
canvas 中的触摸事件不可冒泡,所以没有 currentTarget。
5、 target 和 currentTarget 的区别
target 是 触发事件的源组件。
属性 | 类型 | 说明 |
---|---|---|
id | String | 事件源组件的id |
dataset | Object | 事件源组件上由data- 开头的自定义属性组成的集合 |
currentTarget 是 事件绑定的当前组件。
属性 | 类型 | 说明 |
---|---|---|
id | String | 当前组件的id |
dataset | Object | 当前组件上由data- 开头的自定义属性组成的集合 |
target 和 currentTarget 的使用案列,请戳这里:https://juejin.im/post/59f16ffaf265da43085d4108
六、WXS响应事件
1、获取dom元素节点
可以参考这里:https://juejin.im/post/5be7df8ff265da61590b3169
wx.createSelectorQuery() 可以用于获取节点属性、样式、在界面上的位置等信息。
- 返回值是一个 SelectorQuery 对象实例。
- 在自定义组件或包含自定义组件的页面中,应使用
this.createSelectorQuery()
来代替。
SelectorQuery 查询节点信息的对象
方法 | 描述 |
SelectorQuery SelectorQuery.in(Component component) | 将选择器的选取范围更改为自定义组件 component 内。(初始时,选择器仅选取页面范围的节点,不会选取任何自定义组件中的节点)。 |
NodesRef SelectorQuery.select(string selector) | 在当前页面下选择第一个匹配选择器 selector 的节点。返回一个 NodesRef 对象实例,可以用于获取节点信息。 |
NodesRef SelectorQuery.selectAll(string selector) | 在当前页面下选择匹配选择器 selector 的所有节点。 |
NodesRef SelectorQuery.selectViewport() | 选择显示区域。可用于获取显示区域的尺寸、滚动位置等信息。 |
NodesRef SelectorQuery.exec(function callback) | 执行所有的请求。请求结果按请求次序构成数组,在callback的第一个参数中返回。 |
案例
const query = wx.createSelectorQuery()
query.select('#the-id').boundingClientRect()
query.selectViewport().scrollOffset()
query.exec(function(res){
res[0].top // #the-id节点的上边界坐标
res[1].scrollTop // 显示区域的竖直滚动位置
})
2、WXS响应事件
引自:https://developers.weixin.qq.com/miniprogram/dev/framework/view/interactive-animation.html
- 使用 WXS 函数用来响应小程序事件,目前只能响应内置组件的事件,不支持自定义组件事件。
- WXS 函数的除了纯逻辑的运算,还可以通过封装好的
ComponentDescriptor
实例来访问以及设置组件的 class 和样式,对于交互动画,设置 style 和 class 足够了。
案例:
var wxsFunction = function(event, ownerInstance) {
console.log('----------event', JSON.stringify(event));
var instance = ownerInstance.selectComponent('.classSelector') // 返回组件的实例
instance.setStyle({
"font-size": "14px" // 支持rpx
})
instance.getDataset()
instance.setClass(className)
// ...
return false // 不往上冒泡,相当于调用了同时调用了stopPropagation和preventDefault
}
- 入参 event:是小程序事件对象基础上多了
event.instance
来表示触发事件的组件的ComponentDescriptor
实例。 - 入参ownerInstance:是触发事件的组件所在的组件的
ComponentDescriptor
实例,如果触发事件的组件是在页面内的,ownerInstance
表示的是页面实例。
ComponentDescriptor
实例对象
方法 | 参数 | 描述 |
---|---|---|
selectComponent | selector对象 | 返回组件的 ComponentDescriptor 实例。 |
selectAllComponents | selector对象数组 | 返回组件的 ComponentDescriptor 实例数组。 |
setStyle | Object/string | 设置组件样式,支持rpx 。设置的样式优先级比组件 wxml 里面定义的样式高。不能设置最顶层页面的样式。 |
addClass/removeClass/ hasClass | string | 设置组件的 class。设置的 class 优先级比组件 wxml 里面定义的 class 高。不能设置最顶层页面的 class。 |
getDataset | 无 | 返回当前组件/页面的 dataset 对象 |
callMethod | (funcName:string, args:object) | 调用当前组件/页面在逻辑层(App Service)定义的函数。funcName表示函数名称,args表示函数的参数。 |
requestAnimationFrame | Function | 和原生 requestAnimationFrame 一样。用于设置动画。 |
getState | 无 | 返回一个object对象,当有局部变量需要存储起来后续使用的时候用这个方法。 |
triggerEvent | (eventName, detail) | 和组件的triggerEvent一致。 |
3、如何定义wxs事件
<wxs module="test" src="./test.wxs"></wxs>
<view change:prop="{{test.propObserver}}" prop="{{propValue}}" bindtouchmove="{{test.touchmove}}" class="movable"></view>
// test.wxs
module.exports = {
touchmove: function(event, instance) {
console.log('log event', JSON.stringify(event))
},
propObserver: function(newValue, oldValue, ownerInstance, instance) {
console.log('prop observer', newValue, oldValue)
}
}
上面的change:prop
(属性前面带change:前缀)是在 prop 属性被设置的时候触发 WXS 函数,值必须用{{}}
括起来。类似 Component 定义的 properties 里面的 observer 属性,在setData({propValue: newValue})
调用之后会触发。
注意:WXS函数必须用{{}}
括起来。当 prop 的值被设置 WXS 函数就会触发,而不只是值发生改变,所以在页面初始化的时候会调用一次WxsPropObserver
的函数。
七、常用WXS事件
1、bindtap点击事件
案例:
// index.wxml
<view>
<view class="tab_btn " bindtap="tabClick">标签1</view>
</view>
// index.wxs
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 自定义函数
*/
tabClick(){
console.log('1111111111111111111');
},
})