【小程序】中的事件处理详解

不念不忘少年蓝@ 2024-04-27 15:55 136阅读 0赞

文章目录

    • 小程序的事件处理
      • ?小程序的事件监听
      • ?常见事件类型划分
      • ?事件对象属性分析
      • ?事件参数传递方法
      • ?事件传递案例练习
      • ?事件冒泡事件捕获
      • ?知识点补充mark

小程序的事件处理

?小程序的事件监听

什么时候会产生事件呢?

小程序需要经常和用户进行某种交互,比如点击界面上的某个按钮或者区域,比如滑动了某个区域;

事件是视图层到逻辑层的通讯方式;

事件可以将用户的行为反馈到逻辑层进行处理;

事件可以绑定在组件上,当触发事件时,就会执行逻辑层中对应的事件处理函数;

事件对象可以携带额外信息,如 id, dataset, touches;

事件时如何处理呢?

事件是通过bind/catch这个属性绑定在组件上的(和普通的属性写法很相似, 以key=“value”形式);

key以bind或catch开头, 从1.5.0版本开始, 可以在bind和catch后加上一个冒号;

同时在当前页面的Page构造器中定义对应的事件处理函数, 如果没有对应的函数, 触发事件时会报错;

比如当用户点击该button区域时,达到触发条件生成事件tap,该事件处理函数会被执行,同时还会收到一个事件对象event

事件的基本使用

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

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

  1. <!-- 绑定上onBtnTap事件 -->
  2. <button size="mini" bindtap="onBtnTap">按钮</button>
  3. // index.js
  4. // 在对应的 Page 中找到相应的事件处理函数
  5. Page({
  6. onBtnTap() {
  7. console.log("按钮点击");
  8. }
  9. })
  • 当某个事件触发时, 在相应的 Page 中对应的事件处理函数, 会产生一个事件对象, 并且这个对象被传入到该回调函数中,参数是event。

    // index.js

    Page({

    1. onBtnTap(event) {
    2. console.log(event);
    3. }

    })

  • console.log打印出来的event大致信息如下

    {

    “type”:”tap”,
    “timeStamp”:895,
    “target”: {

    1. "id": "tapTest",
    2. "dataset": {
    3. "hi":"Weixin"
    4. }

    },
    “currentTarget”: {

    1. "id": "tapTest",
    2. "dataset": {
    3. "hi":"Weixin"
    4. }

    },
    “detail”: {

    1. "x":53,
    2. "y":14

    },
    “touches”:[{

    1. "identifier":0,
    2. "pageX":53,
    3. "pageY":14,
    4. "clientX":53,
    5. "clientY":14

    }],
    “changedTouches”:[{

    1. "identifier":0,
    2. "pageX":53,
    3. "pageY":14,
    4. "clientX":53,
    5. "clientY":14

    }]
    }

?常见事件类型划分

某些组件会有自己特有的事件类型,大家可以在使用组件时具体查看对应的文档

比如input特有的bindinput/bindblur/bindfocus

比如scroll-view特有的bindscrolltowpper/bindscrolltolower

这里我讲解几个所有组件都有的, 并且也比较常见的事件类型














































类型 触发条件 最低版本
touchstart 手指触摸动作开始
touchmove 手指触摸后移动
touchcancel 手指触摸动作被打断,如来电提醒,弹窗
touchend 手指触摸动作结束
tap 手指触摸后马上离开
longpress 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 1.5.0
longtap 手指触摸后,超过350ms再离开(推荐使用 longpress 事件代替)

?事件对象属性分析

我们刚刚有简单演示, 当某个事件触发时, 会产生一个事件对象, 并且这个对象被传入到回调函数中, 事件对象有哪些常见的属性呢?

如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数必定会收到一个事件对象。

BaseEvent 基础事件对象属性列表:










































属性 类型 说明 基础库版本
type String 事件类型
timeStamp Integer 事件生成时的时间戳
target Object 触发事件的组件的一些属性值集合
currentTarget Object 当前组件的一些属性值集合
mark Object 事件标记数据 2.7.1

这里我重点讲解一下target和currentTarget的区别

target

触发事件的源组件(当前触发事件的组件)。





















属性 类型 说明
id String 事件源组件的id
dataset Object 事件源组件上由data-开头的自定义属性组成的集合

currentTarget

事件绑定的当前组件(处理事件的组件)。





















属性 类型 说明
id String 当前组件的id
dataset Object 当前组件上由data-开头的自定义属性组成的集合

例如我们有如下一个wxml结构

  1. <!-- index.wxml -->
  2. <view id="view" bindtap="onViewTap" class="box">
  3. <button id="btn" size="mini" type="primary">按钮</button>
  4. </view>

给view添加如下样式

  1. /* index.wxss */
  2. .box {
  3. width: 400rpx;
  4. height: 400rpx;
  5. background-color: skyblue;
  6. }

展示效果如下

在这里插入图片描述

我们监听view的点击事件, 在相应的page文件中打印target和currentTarget

  1. // index.js
  2. Page({
  3. onViewTap(event) {
  4. console.log(event.target);
  5. console.log(event.currentTarget);
  6. }
  7. })

此时点击button组件之外的view组件区域, target和currentTarget是没有任何区别的, 大致打印如下

  1. {
  2. id: "view", offsetLeft: 0, offsetTop: 0, dataset: {
  3. …}}
  4. {
  5. id: "view", offsetLeft: 0, offsetTop: 0, dataset: {
  6. …}}

当我们点击button组件, 会产生冒泡事件, 此时target和currentTarget就会有区别, 大致打印如下

  1. {
  2. id: "btn", offsetLeft: 0, offsetTop: 0, dataset: {
  3. …}}
  4. {
  5. id: "view", offsetLeft: 0, offsetTop: 0, dataset: {
  6. …}}

此时触发事件的是button组件冒泡到view组件, 因此target打印的是button组件

而此时处理事件的组件时view组件 (button组件冒泡到view组件, 由view组件处理事件), 因此currentTarget打印的是view组件


?事件参数传递方法

当视图层发生事件时,某些情况需要事件携带一些参数到执行的函数中, 这个时候就可以通过data-属性来完成

格式:data-属性的名称

获取:event.currentTarget.dataset.属性的名称, 一般是通过currentTarget获取, 某些特殊场景是通过target获取

自定义属性的基本使用

  • wxml文件中通过自定义属性, 将数据传递到对应的事件处理函数中


    参数传递
  • 在对应的事件处理函数中获取到传递的数据

    // index.js

    Page({

    1. onArgumentTap(event) {
    2. console.log(event.currentTarget.dataset.name);
    3. console.log(event.currentTarget.dataset.age);
    4. console.log(event.currentTarget.dataset.height);
    5. }

    })


?事件传递案例练习

我们在小程序中, 做一个下面这样的导航栏, 要求点击哪一个导航栏, 文字颜色就改变, 并且对应的标签会显示一个横条

在这里插入图片描述

  • wxml文件的结构




    {
    { item }}


  • js的逻辑代码

    Page({

    1. data: {
    2. titles: ["衣服", "鞋子", "裤子"],
    3. currentIndex: 0
    4. },
    5. onTitleTap(event) {
    6. this.setData({
    7. currentIndex: event.currentTarget.dataset.index
    8. })
    9. }

    })

  • wxss文件的样式

    .active {

    1. color: pink;
    2. border-bottom: 3px solid pink;

    }

    .box {

    1. display: flex;
    2. justify-content: space-between;

    }

    .box .title {

    1. margin: 0 10px;
    2. padding: 10rpx 40rpx;

    }


?事件冒泡事件捕获

当界面产生一个事件时,事件分为了捕获阶段和冒泡阶段

在js阶段我有写过文章详细讲解事件冒泡和事件捕获, 如果对这两个概念不清楚的可以去了解一下:

https://blog.csdn.net/m0\_71485750/article/details/125112983

在这里插入图片描述

对于冒泡和捕获的概念我就不再过多赘述, 在这里演示一下如何阻止冒泡和捕获

  • bind 外,也可以用 catch 来绑定事件, 与 bind 不同的是, catch 会阻止事件向上冒泡

例如在下边这个例子中,

点击 inner view 会先后调用onViewTap3onViewTap2(因为 tap 事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递)

点击 middle view 会触发onViewTap2

点击 outer view 会触发onViewTap1

  1. <view id="outer" bindtap="onViewTap1">
  2. outer view
  3. <!-- 阻止事件冒泡 -->
  4. <view id="middle" catchtap="onViewTap2">
  5. middle view
  6. <view id="inner" bindtap="onViewTap3">
  7. inner view
  8. </view>
  9. </view>
  10. </view>
  • catch 阻止事件传递, 因此阻止事件捕获也是使用 catch, 捕获是通过capture-bind:tap="事件函数"来监听的


    outer view


    middle view

    inner view



?知识点补充mark

mark是一个比较新的语法, 小程序特有的传递数据的方法 (还是推荐使用data-\来传递数据*)

当事件触发时,事件冒泡路径上所有的 mark 会被合并,并返回给事件回调函数。(即使事件不是冒泡事件,也会 mark 。)

mark基本使用

  • wxml中使用mark传递数据

  • 获取mark传递的数据, 通过event.mark获取

    Page({

    1. onBtnTap(event) {
    2. // 通过event.mark获取
    3. console.log(event.mark);
    4. }

    })

发表评论

表情:
评论列表 (有 0 条评论,136人围观)

还没有评论,来说两句吧...

相关阅读

    相关 事件处理详解

    前言   本文大概整理下绑定事件的几种方式,兼容IE8- 的方式(如果需要的话),事件委托,阻止传播,取消默认行为,event对象等。   之前做的多是手机端页面,监听

    相关 微信程序事件处理

    一、什么是事件? 1.一种用户的行为 用户长按某一张图片,点击某个按钮,这就是用户的行为,也是事件 2.一种通讯方式 为什么说事件也是一种通讯方式呢?因为用户点击按

    相关 JS事件处理程序

    什么是事件和事件处理程序? 事件就是用户或浏览器执行的某些动作,诸如click,load,mouseover等,都是事件的名字,而响应某个事件的函数就是事件处理程序,事件