- 小程序初级指南--视图层--事件
事件 代码片段 https://developers.weixin.qq.com/s/nH9Z5Umd70dz DOM 事件 DOM 事件被发送用于通知代码相关的事情已经发生了。每个事件都是继承自[代码]Event[代码] 类的对象,可以包括自定义的成员属性及函数用于获取事件发生时相关的更多信息。事件可以表示从基本用户交互到渲染模型中发生的事件的自动通知的所有内容。 小程序事件 小程序是没有DOM的 官方-小程序没有 DOM 接口,原因竟然是……? 事件文档 官方文档 事件是视图层到逻辑层的通讯方式。 事件可以将用户的行为反馈到逻辑层进行处理。 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。 事件对象可以携带额外信息,如 id, dataset, touches。 使用方式 [代码]bindtap[代码] [代码]bind:tap[代码] bindtap 等同于bind:tap; 自基础库版本 1.5.0 起,在大多数组件和自定义组件中, [代码]bind[代码] 后可以紧跟一个冒号,其含义不变,如 [代码]bind:tap[代码] 。基础库版本 2.8.1 起,在所有组件中开始提供这个支持。 [代码]<view class="item" bindtap="bindtap" data-type='bindtap'>bindtap</view> <view class="item" bind:tap='bindtap' data-type='bind:tap'>bind:tap</view> // 页面的 this.data.handlerName 必须是一个字符串,指定事件处理函数名;如果它是个空字符串,则这个绑定会失效(可以利用这个特性来暂时禁用一些事件)。 <view class="item" data-type="handler" bindtap="{{handlerName}}"> handlerName </view> <view class="item" bindtap="disableHandler"> handlerName方法开关 </view> [代码] [代码]Page({ data: { handlerName: 'handlerName' }, onLoad: function () {}, bindtap(e){ let type = e.currentTarget.dataset.type; wx.showToast({ title: `我被点击了,类型是${type}`, icon: 'none' }) }, handlerName(e){ let type = e.currentTarget.dataset.type; wx.showToast({ title: `我被点击了,类型是${type}`, icon: 'none' }) }, disableHandler(){ let handlerName = this.data.handlerName; handlerName.length == 0 ? handlerName = 'handlerName' : handlerName = '' this.setData({ handlerName: handlerName },()=>{ handlerName.length == 0 ? wx.showToast({ title: `禁用handlerName方法`, icon: 'none' }) : wx.showToast({ title: `启用handlerName方法`, icon: 'none' }) }) } }) [代码] 事件分类 事件分为冒泡事件和非冒泡事件: 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。[代码]bind[代码] 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。 [代码]catch[代码] [图片] 互斥事件 [代码]mut-bind[代码] 自基础库版本 2.8.2 起,除 [代码]bind[代码] 和 [代码]catch[代码] 外,还可以使用 [代码]mut-bind[代码] 来绑定事件。一个 [代码]mut-bind[代码] 触发后,如果事件冒泡到其他节点上,其他节点上的 [代码]mut-bind[代码] 绑定函数不会被触发,但 [代码]bind[代码] 绑定函数和 [代码]catch[代码] 绑定函数依旧会被触发。 换而言之,所有 [代码]mut-bind[代码] 是“互斥”的,只会有其中一个绑定函数被触发。同时,它完全不影响 [代码]bind[代码] 和 [代码]catch[代码] 的绑定效果。ps: 这个还没有遇到过使用场景, 直接抄官方demo [代码]// 点击 inner view 会先后调用 handleTap3 和 handleTap2 // 点击 middle view 会调用 handleTap2 和 handleTap1 。 <view id="outer" mut-bind:tap="handleTap1"> outer view <view id="middle" bindtap="handleTap2"> middle view <view id="inner" mut-bind:tap="handleTap3"> inner view </view> </view> </view> [代码] 事件的捕获阶段 项目中没有使用,只贴一下介绍。详情看官方文档。 自基础库版本 1.5.0 起,触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用[代码]capture-bind[代码]、[代码]capture-catch[代码]关键字,后者将中断捕获阶段和取消冒泡阶段 事件对象 当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。 属性 类型 说明 等级 基础库版本 type String 事件类型 🌟 timeStamp Integer 事件生成时的时间戳 🌟 target Object 触发事件的组件的一些属性值集合 🌟🌟🌟 currentTarget Object 当前组件的一些属性值集合 🌟🌟🌟 mark Object 事件标记数据 🌟🌟🌟 2.7.1 target 触发事件的源组件。就是你点谁了。 属性 类型 说明 id String 事件源组件的id dataset Object 事件源组件上由[代码]data-[代码]开头的自定义属性组成的集合 dataset 在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。 在 WXML 中,这些自定义数据以 [代码]data-[代码] 开头,多个单词由连字符 [代码]-[代码] 连接。 这种写法中,连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。如: [代码]data-element-type[代码] ,最终会呈现为 [代码]event.currentTarget.dataset.elementType[代码] ; [代码]data-elementType[代码] ,最终会呈现为 [代码]event.currentTarget.dataset.elementtype[代码] 。 连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符 连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符 连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符 重要的事情说三遍 👆 mark 没有关注文档,不知到何时偷偷更新的小可爱 [代码]mark[代码] 在基础库版本 2.7.1 以上,可以使用 [代码]mark[代码] 来识别具体触发事件的 target 节点。此外, [代码]mark[代码] 还可以用于承载一些自定义数据(类似于 [代码]dataset[代码] )。 当事件触发时,事件冒泡路径上所有的 [代码]mark[代码] 会被合并,并返回给事件回调函数。(即使事件不是冒泡事件,也会 [代码]mark[代码] 。) [代码]<view mark:myMark="last" bindtap="bindViewTap"> <button mark:anotherMark="leaf" bindtap="bindButtonTap">按钮</button> </view> [代码] [代码]// 如果按钮被点击,将触发 bindViewTap 和 bindButtonTap 两个事件。 // 事件携带的 event.mark 将包含 myMark 和 anotherMark 两项 Page({ bindViewTap: function(e) { e.mark.myMark === "last" // true e.mark.anotherMark === "leaf" // true } }) [代码] 区别 [代码]mark[代码] 会包含从触发事件的节点到根节点上所有的 [代码]mark:[代码] 属性值; 存在同名的 [代码]mark[代码] ,父节点的 [代码]mark[代码] 会被子节点覆盖。 在自定义组件中接收事件时, [代码]mark[代码] 不包含自定义组件外的节点的 [代码]mark[代码] [代码]dataset[代码] 仅包含一个节点的 [代码]data-[代码] 属性值; [代码]mark[代码] 不会做连字符和大小写转换; detail 自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息。 [代码]bindKeyInput: function (e) { this.setData({ inputValue: e.detail.value }) } [代码] 小结 事件应该是前端基本的入门操作,但是小程序和其他框架实现有所不同,文档还是要认真阅读的。比如 [代码]dataset[代码] 连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符,没有仔细看文档的话第一次遇到一脸懵。又比如新增 [代码]mark[代码]互斥事件 这些不是很常用但是很有效的方法。
2019-12-26 - 【小程序取值和传值】—你也可能遇到的坑系列
前言 小程序真的很好用,非常的便捷,并且我们可以很轻松的开发属于自己的一款小程序,但是在我们开发写代码的时候难免会遇到一些小坑,然后就是各种的疑问???我整理一些我遇到的坑,说不定你也遇到过哈哈哈 取值和传值 在我们开发一个程序的时候,大概率会涉及到要得到一些节点的值或是需要在页面跳转的时候传一些值过去以完成一些事情,我总结三点 普通的取值 页面传值 from表单取值 虽然看上去很简单但是偶尔会有一些小坑等着我们 普通的取值 通常情况下我们都是先给组件绑定事件,按照文档的说法,如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。 比如我们给一个组件绑定了一个点击事件叫getValue,然后我们有一个函数如下,其中event就是事件对象 [代码]<view bindtap="getValue"></view> [代码] [代码]getValue:function(event){ // do someing } [代码] 这个event事件对象是基本的对象事件他其中包括了一些属性,对于我们获得想要的值很重要 [图片] 🆗,到这之后我们可以知道target,和currentTarget对我们很重要了,所以接下来继续看看文档给了我们什么信息 target [图片] currentTarget [图片] 初看可能觉得两个没什么区别,但是这就是坑啊,这两个是有一些区别的,target是触发事件的源组件,也就是说你在button上绑定一个事件那么target就是指向这个button不会变的,而currentTarget就不一样,它指向的是触发事件监听的对象, 注意理解 触发事件监听”的对象与“添加(注册)监听事件”的对象是不一样的!前者是能够触发该事件但没有绑定事件,后者指绑定了事件 填坑 1、如果绑定的事件所在组件没有子元素,则用e.target===e.currentTarget一样; 2、如果事件绑定在父元素中,且该父元素有子元素,当用e.currentTarget时,不管点击父元素所在区域还是子元素(当前事件),都正确执行,若用e.target时,点击父元素所在区域无错,点击子元素区域,执行报错,报错的原因是事件没绑定在子元素上,是在父元素上,子元素要用e.currentTarget才正确 上面内容中有引用此博客 https://blog.csdn.net/syleapn/article/details/81289337 官方文档传送 https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html 上面说了很多,但是还没有说到底怎么取值,其实看完上面也差不多了,下面需要提的是dataset 文档的解释: 在组件中可以定义数据,这些数据将会通过事件传递给 SERVICE。 书写方式: 以data-开头,多个单词由连字符-链接,不能有大写(大写会自动转成小写)如data-element-type,最终在 event.currentTarget.dataset 中会将连字符转成驼峰elementType。 简单的理解就是我们可以把想要获取的值通过data-定义到组件上,当我们在触发一个事件的时候我们可以通过event.currentTarget.dataset.XX来获取 [代码]// 像这样 <view> <button bindtap='info' data-value='5555'>点击</button> </view> [代码] [代码]// e和event等价 info:function(e){ console.log('value:'+e.currentTarget.dataset.value) } [代码] 结果:当我们点击按钮的时候就可以得到我们预先定义好的值了 页面传值 页面传值的使用还是比较多的,特别是我们需要做一些详情页面的时候,经常涉及到需要将上一个页面的某一些值带到第二个页面来。这个坑要少一点,我们一步一步来说吧 首先说跳转吧 仅有两种,其他方法欢迎讨论 wx.navigateTo(Object object) navigator 传参数 虽然有两种跳转的方式,但是它们传递参数的方式是一样的,url后拼接?id(参数名字)=要传递的值 注意 (如果多个参数用&分开 &name=value&…….) [代码]<navigator url="pages/detail/detail?value="123"> 跳转 </navigator> [代码] [代码]wx.navigateTo({ url:"pages/detail/detail?value="123", success: function (res) { // success }, fail: function () { // fail }, complete: function () { // complete } }) [代码] 获得参数 在跳转到的界面的一些生命周期的函数中有一个options,它是包含url地址中参数的对象,可以通过它直接点获取。 [代码]onLoad:function(options){ console.log(options.value) } [代码] from表单取值 这里首先要铺垫一下deatil deatil是event事件对象的一个属性,它包括一些额外的信息 ok,接下来要说取值了,常规的做法是通过 <form bindsubmit=“formSubmit”> 与 <button formType=“submit”> 标签配合使用,然后给input一个name属性,我们在js中就可以使用e.deatil.value.name来获取了 [代码]<form bindsubmit="formSubmit"> <input name="detail" placeholder="详情地址" /> <input name="realname" placeholder="收件人姓名" /> <input name="mobile" placeholder="手机号码" type="number"/> <button formType="submit" type="primary">Submit</button> </form> [代码] 对新手来说这里有一点小坑,新手可能会有疑惑 为什么没有给button绑定事件呢,是不是需要在绑定一个事件,其实不用,<form bindsubmit=“formSubmit”> 已经绑定了事件,我们在 js 中只需要写一个叫 formSubmit 的函数就好了 [代码]formSubmit: function(e) { // detail var detail = e.detail.value.detail; // realname var realname = e.detail.value.realname; // mobile var mobile = e.detail.value.mobile; } [代码] 此处有引用 https://www.cnblogs.com/lrgupup/p/7609118.html 结语 好记性不如烂笔头,记录一下自己犯过的一些小错❤
2020-03-24