事件
什么是事件
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset, touches。
事件的使用方式
- 在组件中绑定一个事件处理函数。
如 tap,当用户点击该组件的时候会在该页面对应的 Page 中找到相应的事件处理函数。
<view id="tapTest" data-hi="Transsion" bind:tap="tapName">Click me!</view>
- 在相应的 Page 定义中写上相应的事件处理函数,参数是 event。
Page({
tapName: function (event) {
console.log(event);
},
});
- 可以看到 log 出来的信息大致如下:
{
"currentTarget": {
"dataset": {
"hi": "Transsion"
}
}
}
事件详解
事件分类
事件分为冒泡事件和非冒泡事件:
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
DLT 的冒泡事件列表:
类型 | 触发条件 |
---|---|
touchstart | 手指触摸动作开始 |
touchmove | 手指触摸后移动 |
touchend | 手指触摸动作结束 |
tap | 手指触摸后马上离开 |
注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的 submit 事件,input 的 input 事件,scroll-view 的 scroll 事件,(详见各个组件)
普通事件绑定
事件绑定的写法类似于组件的属性,如:
<view bind:tap="handleTap">Click here!</view>
如果用户点击这个 view ,则页面的 handleTap 会被调用。
绑定并阻止事件冒泡
使用 .stop
来阻止冒泡行为,不让当前元素的事件继续往外触发。
例如在下边这个例子中,点击 inner view 会先后调用 handleTap3 和 handleTap2(因为 tap 事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递),点击 middle view 会触发 handleTap2,点击 outer view 会触发 handleTap1。
<view id="outer" class="item" bind:tap="handleTap1">
outer view
<view id="middle" class="item" bind:tap.stop="handleTap2">
middle view
<view id="inner" class="item" bind:tap="handleTap3">inner view</view>
</view>
</view>
事件的捕获阶段
触摸类事件支持使用 .native.capture
来进行事件捕获。点击事件使用 click.native.capture
来进行事件捕获。捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。同时,如果想在捕获阶段中断和取消冒泡阶段,可以链式使用 .stop
。
例如在下边的例子中,触摸或点击 inner view,会先之行 handleTap1,再执行 handleTap2。
<!-- 触摸 -->
<view id="outer" class="item" bind:touchstart.native.capture="handleTap1">
outer view
<view id="inner" class="item" bind:touchstart.native.capture="handleTap2">
inner view
</view>
</view>
<!-- 点击 -->
<view id="outer" class="item" bind:click.native.capture="handleTap1">
outer view
<view id="inner" class="item" bind:click.native.capture="handleTap2">
inner view
</view>
</view>
如果将上面代码中的第一个 capture 后再链式加上 .stop
,将只执行 handleTap1
<!-- 触摸 -->
<view id="outer" class="item" bind:touchstart.native.capture.stop="handleTap1">
outer view
<view id="inner" class="item" bind:touchstart.native.capture="handleTap2">
inner view
</view>
</view>
<!-- 点击 -->
<view id="outer" class="item" bind:click.native.capture.stop="handleTap1">
outer view
<view id="inner" class="item" bind:click.native.capture="handleTap2">
inner view
</view>
</view>
事件对象
如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。
dataset
在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。
在 DLT 中,这些自定义数据以 data- 开头,多个单词由连字符 - 连接。如:
- data-element-type ,最终会呈现为 event.currentTarget.dataset.elementtype ;
- data-elementtype ,最终会呈现为 event.currentTarget.dataset.elementtype 。
示例:
<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap">
DataSet Test
</view>
Page({
bindViewTap: function (event) {
event.currentTarget.dataset.alphabeta === 1; // - 不会转为驼峰写法
event.currentTarget.dataset.alphabeta === 2; // 大写会转为小写
},
});
touches
touches 是一个数组,每个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点。
Touch 对象
属性 | 类型 | 说明 |
---|---|---|
pageX, pageY | Number | 距离文档左上角的距离,文档的左上角为原点 ,横向为 X 轴,纵向为 Y 轴 |
clientX, clientY | Number | 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为 X 轴,纵向为 Y 轴 |
changedTouches
changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。
detail
自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。