微信小程序:事件绑定(bindtap和catchtap的区别)

您所在的位置:网站首页 小程序二级菜单是什么意思 微信小程序:事件绑定(bindtap和catchtap的区别)

微信小程序:事件绑定(bindtap和catchtap的区别)

2024-04-25 16:48| 来源: 网络整理| 查看: 265

一、事件介绍

小程序中绑定事件,通过bind关键字来实现。如bindinput,bindtap(绑定点击事件),bindchange等。

什么是事件

事件是视图层到逻辑层的通讯方式。 事件可以将用户的行为反馈到逻辑层进行处理。 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。 事件对象可以携带额外信息,如 id, dataset, touches

事件的使用方式

1、在组件中绑定一个事件处理函数。

如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。

Click me!

2、在相应的Page定义中写上相应的事件处理函数,参数是event。

Page({ tapName: function(event) { console.log(event) } })

可以看到log出来的信息大致如下:注意view标签的id属性值为e.currentTarget.id,自定义属性hi值为:e.currentTarget.dataset.hi,

{ "type":"tap", "timeStamp":895, "target": { "id": "tapTest", "dataset": { "hi":"Weixin" } }, "currentTarget": { "id": "tapTest", "dataset": { "hi":"Weixin" } }, "detail": { "x":53, "y":14 }, "touches":[{ "identifier":0, "pageX":53, "pageY":14, "clientX":53, "clientY":14 }], "changedTouches":[{ "identifier":0, "pageX":53, "pageY":14, "clientX":53, "clientY":14 }] } 二、事件分类

事件分为冒泡事件和非冒泡事件:

冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。

WXML的冒泡事件列表:

touchstart:手指触摸动作开始

touchmove:手指触摸后移动

touchcancel:手指触摸动作被打断,如来电提醒,弹窗

touchend:手指触摸动作结束

tap:手指触摸后马上离开

longpress:手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发

longtap:手指触摸后,超过350ms再离开(推荐使用longpress事件代替)

transitionend:会在 WXSS transition 或 wx.createAnimation 动画结束后触发

animationstart:会在一个 WXSS animation 动画开始时触发

animationiteration:会在一个 WXSS animation 一次迭代结束时触发

animationend:会在一个 WXSS animation 动画完成时触发

touchforcechange:在支持 3D Touch 的 iPhone 设备,重按时会触发

注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的submit事件,input 的input事件,scroll-view 的scroll事件,(详见各个组件)

bindtap和catchtap的区别

bindtap 和 catchtap 都属于点击事件,绑定之后,点击组件是可以触发这个函数的。

bindtap  :子元素使用bindtap绑定事件后,执行的时候,会冒泡到父元素(触发父元素上绑定的bingtap事件)。

catchtap  :不会冒泡到父元素上,阻止事件冒泡。

举例如下:

wxml

view out view middle view inner

js

inner: function(){ console.log('inner button'); }, middle:function(){ console.log('middle button'); }, out:function(){ console.log('out button'); }

效果如下:

 

 点击view inner,控制台打印如下:

 

 若将中间的bindtap,改为catchtap,

view out view middle view inner

点击middle button会打印如下:

 

即没有向上冒泡

三、绑定输入事件bindinput

1、 需要给input标签绑定input事件,这个事件bindinput在当值改变时就会触发。

2、 编写input事件的执行逻辑。

3、 通过事件源对象(e)来获取输入框中的值(e.detail.value),然后赋值给num.

 

 

把输入框的值赋值给data当中使用setData方法。

获取输入框的值(e.detail.value)和自定义属性(e.currentTarget.dataset .xxx)都是从事件源对象(e)获取的。

获取data数据模型中的值是通过this.data.xx来获取的。注意:微信小程序中获取数据模型中的值和给数据模型中的属性赋值都与vue中的不一样。

四、绑定单击事件bindtap

绑定事件的时候不能直接进行传参,否则会将方法名连同参数一起当作方法名。只能通过自定义属性的方式传参。

自定义属性 operation,

 

 获取输入框的值:e.detail.value;获取自定义属性的值:e.currentTarget.dataset.xxx;给data中的属性赋值:this.setData();获取data数据模型中的值:this.data.xxx;

 绑定事件时不能带参数,不能带括号。事件传值通过自定义属性的方式。在事件触发时获取数据。

五、绑定手指触摸动作开始bindtouchstart和结束bindtouchend

touches:数组,触摸事件,当前停留在屏幕中的触摸点信息的数组;touches 是一个数组,每个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点。

changedTouches:数组,触摸事件,当前变化的触摸点信息的数组;changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。

index.wxml中代码:

外层循环显示一级菜单,点击一级菜单时触发isOpen函数并传递id,且刚开始时,二级菜单时隐藏的状态;一开始时数据模型中的hidden属性为true,即一级菜单右侧显示的都是扩展的图标,

1、点击一级菜单时,先获取被点击菜单的id,获取数据模型中的menuList,遍历menuList,如果某个菜单的id等于当前被点击的菜单的id,则将给菜单item的hidden属性值取反,即由原来的隐藏改为显示,另外一级菜单右侧的扩展图标改为collapse图标

内层循环显示二级菜单,点击二级菜单时,触发menuClick函数并传递name.

1、点击二级菜单时先获取当前被点击菜单的name,如果当前被点击的菜单的name值为“企业信息管理,则通过wx.relaunch()方法跳转到该页面”

{{item.name}} {{items.name}}

index.js中的代码:

bindtouchstart事件给触摸点的定位赋值,bindtouchend将触摸点现在的定位和原来的定位进行比较,从而确定是左滑还是右滑,进而控制菜单是否显示。

1、小程序加载时即从后台获取了menuList,

2、首页(index)页面加载时(onLoad),先从storage中获取menuList,在循环遍历,

先通过父id为0且菜单名称不为首页来过滤得到所有的一级菜单,再将所有的一级菜单的children属性置空,给每个item都添加hidden属性,且值为true。

再对menuList中所有的item进行遍历,如果父id为当前item的id,则将菜单放入当前item的children数组中,再讲当前菜单放入menuList中。最后将menuList赋值个数据模型中的menuList,这样打开首页时,menuList就是已经过滤掉首页的menuList。

3、创建一个动画实例animation

4、将数据模型中的hidden属性置为false,这样,一开始时二级菜单为隐藏状态。

//index.js //获取应用实例 const app = getApp() Page({ data: { hidden:true, menuList:[] }, touchStart:function(e){ this.setData({ "touch.x": e.changedTouches[0].clientX, "touch.y": e.changedTouches[0].clientY }); }, touchEnd:function(e){ let x = e.changedTouches[0].clientX; let y = e.changedTouches[0].clientY; var turn = this.getTouchData(x,y,this.data.touch.x,this.data.touch.y); if(turn == 'left'){ this.animation.translateX(-220).step(); // 在x轴平移-220px,即向左平移220px,调用实例的step()方法来描述动画 this.setData({ animation: this.animation.export() }) // 最后通过动画实例的 export 方法导出动画数据传递给组件的 animation }else if(turn == 'right'){ this.animation.translateX(0).step(); this.setData({ animation: this.animation.export() }) } }, getTouchData:function(endX, endY, startX, startY){ let turn = ""; if (endX - startX > 20 && Math.abs(endY - startY) < 30) { //右滑 turn = "right"; } else if (endX - startX < -20 && Math.abs(endY - startY) < 30) { //左滑 turn = "left"; } return turn; }, isOpen:function(e){ var id = e.currentTarget.dataset.id; // 点击一级菜单时,先获取被点击菜单的id, var menuList = this.data.menuList; // 获取数据模型中的menu, menuList.forEach((item,index) => { // 遍历menuList,如果某个菜单的id等于当前被点击的菜单的id,则将给菜单item的hidden属性值取反,即由原来的隐藏改为显示。 var id2 = item.id; if(id2 == id){ item.hidden = !item.hidden; }else{ item.hidden = true; } }); this.setData({menuList:menuList}); }, menuClick:function(e){ var name = e.currentTarget.dataset.name; // 点击二级菜单时先获取当前被点击菜单的name if(name == '企业信息管理'){ // 如果当前被点击的菜单的name值为“企业信息管理,则跳转到该页面” wx.reLaunch({ url: '/pages/demo/index/index' }) } }, getMenuList:function(list){ var menuList = []; list.forEach((item,index) => { var id = item.id; var name = item.name; var parentId = item.parentId; if(parentId == 0 && name != '首页'){//过滤平台的首页 //第一层级 item.children = []; item.hidden = true; list.forEach((jtem,jndex) => { var parentId2 = jtem.parentId; if(parentId2 == id){ // 如果父id为当前item的id,则将菜单放入当前item的children数组中 //第二层级 item.children.push(jtem); } }); menuList.push(item); } }); this.setData({ menuList: menuList }) }, onLoad: function () { if(app.globalData.token){ //代表从页面跳转过来 var menuList = wx.getStorageSync('menuList'); this.getMenuList(menuList); this.animation = wx.createAnimation(); // 创建一个动画实例animation this.setData({hidden: false}); // 将数据模型中的hidden属性置为false }else{ //代表第一次加载 wx.showLoading({ title: '加载中' }) // 由于 checkBind 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 app.checkBindCallback = res => { wx.hideLoading(); if(res.data.code == 1){ var menuList = wx.getStorageSync('menuList'); this.getMenuList(menuList); this.animation = wx.createAnimation(); this.setData({hidden: false}); } } } } })

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3