小程序事件基础
什么是事件
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset, touches。
事件的使用方式
- 在组件中绑定一个事件处理函数。 如 bindtap,当用户点击该组件的时候会在该页面对应的 Page中找到相应的事件处理函数。
- 在页面wxml中添加标签绑定事件处理函数。
<view bindtap='run'> Click me! </view>
在页面js中添加事件处理函数
run: function(){
console.log("run");
}
事件绑定的写法
- 事件绑定的写法同组件的属性,以 key、value 的形式。
- key 以bind或catch开头,然后跟上事件的类型,如bindtap, catchtouchstart
- value 是一个字符串,需要在对应的 Page 中定义同名的函数。不然当触发事件的时候会报错。
- bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。
事件的类型
- touchstart 手指触摸
- touchmove 手指触摸后移动
- touchcancel 手指触摸动作被打断,如弹窗和来电提醒
- touchend 手指触摸动作结束
- tap 手指触摸后离开
- longtap 手指触摸后后,超过350ms离开
事件对象的参数
其中event事件对象携带的参数有
其中target与currentTarget的属性成员有
- id —事件源组件的id
- tagName—当前组件的类型
- dataset—事件源组件上由data-开头的自定义属性组成的集合
其中touches的属性成员有
- identifier — 触摸点的标识符
- pageX, pageY — 距离文档左上角的距离,文档的左上角为原点
- clientX, clientY — 距离页面可显示区域(屏幕除去导航条)左上角距离
<image src='../../images/i.jpg' id="tapTest" data-hi="WeChat" bindtap="tapName"> </image>
事件对象内容:
{
"type": "tap", //事件类型
"timeStamp":895, //事件生成时的时间戳
"target": { //触发事件的组件
"id": "tapTest",
"dataset": {"hi": "WeChat" }
},
"currentTarget " : { //当前组件,有些事件是冒泡的, currentTarget有时与target为不同对象
"id": "tapTest",
"dataset": { "hi": "WeChat" }
},
"touches": [{
"pageX": 30,
"pageY": 12,
"clientX": 30,
"clientY": 12}],
"detail": {
"x": 30,
"y": 12
}
}
将自定义属性值传递到事件函数中
- 在组件中,自定义数据的书写的方式则为:以 data- 开头,多个单词由连字符 - 链接,大写无效,到函数中会自动转为小写驼峰式命名。如 data-element-type,在函数中获取到的属性名称会被转换为 elementType。而该属性,会存在于事件函数的事件对象event的currentTarget对象的dataset属性中。默认下currentTarget里面的 dataset是没有数据的。为了方便我们添加我们自定义data-开头的属性数据。
- 如果要传递数值999,我们可以这样:
<text class="user-motto" catchtap="onTextTap" data-number="999">{{motto}}</text>
而在事件函数中,我们可以这样获取:
事件冒泡
事件分类
- 事件分类 :事件分为冒泡事件和非冒泡事件
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
冒泡事件列表
WXML的冒泡事件列表
注:除上表之外的其他组件自定义事件都是非冒泡事件,如 <form/>
的 submit 事件, <input/>
的 input事件, <scroll-view/>
的 scroll 事件,以后讲组件时再去讲这些事件。
示例:
<image src='../../images/1.jpg' bindtouchstart='touchstart' bindtouchmove='touchmove' bindtouchcancel='touchcancel' bindtouchend='touchend'/>
touchstart:function (event) {
console.log("touchstart");
},
……
事件绑定bind与catch
- bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。
<view id="outter" bindtap="handleTap1">
outer view
<view id="middle" bindtap="handleTap2">
middle view
<view id="inner" bindtap="handleTap3">
inner view
</view>
</view>
</view>
handleTap1: function (event) {
console.log("handleTap1最外层");
},
handleTap2: function (event) {
console.log("handleTap2中间层");
},
handleTap3: function (event) {
console.log("handleTap3最里层");
}
将上面中间的bindtap改成catchtap,则发现冒泡到中间,不再往上冒泡。
<view id="middle" catchtap="handleTap2">
总结:
bind绑定的事件不会阻止事件往上冒泡。
catch绑定的事件会阻止事件往上冒泡。
触控事件
- 单击(tap)
- 双击(dbtap)
- 长按(longtap)
- 滑动
- 多点触控
单击事件(tap)
单击事件由touchstart、touchend组成,touchend后触发tap事件。
<view>
<button type="primary" bindtouchstart="mytouchstart" bindtouchend="mytouchend" bindtap="mytap">点我吧</button>
</view>
mytouchstart: function(e){
console.log(e.timeStamp + '- touch start')
},
mytouchend: function(e){
console.log(e.timeStamp + '- touch end')
},
mytap: function(e){
console.log(e.timeStamp + '- tap')
}
双击事件
双击事件由两个单击事件组成,两次间隔时间小于300ms认为是双击;微信官方文档没有双击事件,需要开发者自己定义处理。
<view>
<button type="primary" bindtap="mytap">点我吧</button>
</view>
长按事件
- 长按事件手指触摸后,超过350ms再离开。
<view>
<button type="primary" bindtouchstart="mytouchstart" bindlongtap="mylongtap"
bindtouchend="mytouchend" bindtap="mytap">点我吧</button>
</view>
mytouchstart: function(e){
console.log(e.timeStamp + '- touch start')
},
//长按事件
mylongtap: function(e){
console.log(e.timeStamp + '- long tap')
},
mytouchend: function(e){
console.log(e.timeStamp + '- touch end')
},
mytap: function(e){
console.log(e.timeStamp + '- tap')
}
单击、双击、长按小结
单击、双击、长按属于点触事件,会触发touchstart、touchend、tap事件,touchcancel事件只能在真机模拟,不多说了。
滑动事件
手指触摸屏幕并移动,为了简化起见,下面以水平滑动和垂直滑动为例。 滑动事件由touchstart、touchmove、touchend组成。
<view>
<buttontype="primary"bindtouchstart="mytouchstart"bindtouchmove="mytouchmove">点我吧</button>
</view>
mytouchstart: function (e) {
var that = this;
//开始触摸,获取触摸坐标
console.log(e)
that.setData({ startpoint: [e.touches[0].pageX, e.touches[0].pageY] });
},
//触摸点移动
mytouchmove: function (e) {
//当前触摸点坐标
var that = this;
var curPoint = [e.touches[0].pageX, e.touches[0].pageY];
var startpoint = that.data.startpoint;
console.log(startpoint)
console.log(curPoint)
//比较pagex值
if (curPoint[0] < startpoint[0]) {
if (Math.abs(curPoint[0] - startpoint[0]) >= Math.abs(curPoint[1] - startpoint[1])) {
console.log(e.timestamp + '-touch left move')
that.setData({
dellStyle: "dellList"
})
} else {
if (curPoint[1] >= startpoint[1]) {
console.log(e.timestamp + '-touch down move')
} else {
console.log(e.timestamp + '-touch up move')
}
}
}
else {
if (Math.abs(curPoint[0] - startpoint[0] >= Math.abs(curPoint[1] - startpoint[1]))) {
console.log(e.timestamp + '-touch right move')
that.setData({
dellStyle: "modList"
})
} else {
if (curPoint[1] >= startpoint[1]) {
console.log(e.timestamp + '-touch down move')
} else {
console.log(e.timestamp + '-touch up move')
}
}
}
},
多点触控
由于模拟器尚不支持多点触控,暂不介绍。
小程序函数的分类及用法
小程序函数的分类
- 按函数的不同调用方式
- 生命周期函数(app.js和页面.js)
- 自定义函数
- 事件处理函数
- API函数
自定义函数的分类
按自定义函数不同的调用位置分为
- 在util.js模块里的函数
- 在app.js定义的全局函数
- 在页面定义的函数
函数
定义函数的格式
函数名:function(参数){
函数体
return 5;
}
参数可没有,也可以有多个
小程序定义函数的形式
函数名:function(参数){
函数体
return 值;
}
参数可没有,也可以有多个
可以没有return,也可以有return和值。
无参函数
dd:function (){
return 5;
}
在需要调用函数的地方有this.函数名()的方法调用函数,当函数有返回值时一般要有一个变量来存放函数的返回值。
var m2=this.dd();
有参函数
dd:function(n){
n=n+1
return n;
}
var m2=this.dd(6);调用函数的方式