小程序的事件处理

345 阅读2分钟

1. 基本事件相关

1.1 事件的监听

  • 什么时候会产生事件呢?

    • 小程序需要经常和用户进行某种交互,比如点击界面上的某个按钮或者区域,比如滑动了某个区域
    • 事件是视图层到逻辑层的通讯方式
    • 事件可以将用户的行为反馈到逻辑层进行处理
    • 事件可以绑定在组件上,当触发事件时,就会执行逻辑层中对应的事件处理函数
    • 事件对象可以携带额外信息,如 id, dataset, touches
  • 事件时如何处理呢?

    • 事件是通过bind/catch这个属性绑定在组件上的(和普通的属性写法很相似, 以key=“value”形式)
    • key以bind或catch开头, 从1.5.0版本开始, 可以在bind和catch后加上一个冒号
    • 同时在当前页面的Page构造器中定义对应的事件处理函数, 如果没有对应的函数, 触发事件时会报错
    • 比如当用户点击该button区域时,达到触发条件生成事件tap,该事件处理函数会被执行,同时还会收到一个事件对象event。

1.2 组件的特殊事件

  • 某些组件会有自己特有的事件类型

    • 比如input有bindinput/bindblur/bindfocus等

    • 比如scroll-view有bindscrolltoupper/bindscrolltolower等

  • 常见的事件类型

2. Event对象

  • 当某个事件触发时, 会产生一个事件对象, 并且这个对象被传入到回调函数中, 事件对象些常见的属性如下:

    image.png

  • target/currentTarget的区别

    • target: 触发事件的源组件
    • currentTarget: 事件绑定的当前组件
    <!-- 点击inner target为inner currentTarget为outer -->
    <view id="outer" class="outer" data-name="xxx" bindtap="onOuterViewTap">
      <view id="inner" class="inner"></view>
    </view>
    
  • touches/changedTouches区别(了解)

    1. 在touchend中不同
    2. 多手指触摸时不同
    <view
      bindtap="onTouchTap"
      bindlongpress="onLongPress"
      bindtouchend="onTouchEnd"
    >
      多指触摸
    </view>
    
    onTouchTap(event) {
      console.log("tap:", event);
    },
    onLongPress(event) {
      console.log("long:", event);
    },
    onTouchEnd(event) {
      console.log("end:", event);
    },
    

    image.png

3. 事件传递参数

  • data-*传递

  • event.currentTarget.dataset.index

    <view class="tab-control">
      <block wx:for="{{ titles }}" wx:key="*this">
        <view 
          class="item {{index === currentIndex ? 'active': ''}}"
          bindtap="onItemTap"
          data-index="{{index}}"
        >
          <text class="title">{{ item }}</text>
        </view>
      </block>
    </view>
    

4. 捕获和冒泡过程

<!-- 点击view3 依次捕获 冒泡 -->
<view class="view1" capture-bind:tap="onView1CaptureTap" bindtap="onView1Tap">
  <view class="view2" capture-bind:tap="onView2CaptureTap" bindtap="onView2Tap">
    <view class="view3" capture-bind:tap="onView3CaptureTap" bindtap="onView3Tap"></view>
  </view>
</view>
onView1CaptureTap() {
  console.log("onView1CaptureTap");
},
onView2CaptureTap() {
  console.log("onView2CaptureTap");
},
onView3CaptureTap() {
  console.log("onView3CaptureTap");
},
onView1Tap() {
  console.log("onView1Tap");
},
onView2Tap() {
  console.log("onView2Tap");
},
onView3Tap() {
  console.log("onView3Tap");
},

image.png

5. catch和mark

  • catch阻止进一步传递
  • mark也可以传递参数
<view
  bindtap="onMarkTap"
  mark:name="kobe"
  mark:age="30"
>
 <!-- 点击text {address: "洛杉矶", age: "30", name: "kobe"} -->
 <text mark:address="洛杉矶" class="title">mark</text>
</view>
onMarkTap(event) {
  console.log(event);

  const data = event.mark
  console.log(data); // {age: "30", name: "kobe"}
}