当前位置: 首页 > news >正文

交互的脉络:小程序事件系统详解

交互的脉络:小程序事件系统详解

所属专栏:《微信小程序-实战笔记30讲》
作者:码力无边

前言

在前面的课程中,我们已经学会了使用bindtap来响应用户的点击事件。这就像我们学会了在家里的电灯开关上贴一个“开灯”的标签,按下它,灯就会亮。这解决了最基本的需求。

但是,如果家里的布局很复杂呢?比如,你按下了客厅的总开关,是只希望客厅的灯亮,还是希望整个房子的灯都跟着亮?如果你想在开灯的同时,顺便告诉控制中心“是我按的,现在是晚上8点”,又该怎么做?

这些更复杂的交互场景,背后都依赖于一套清晰的规则,这就是小程序的事件系统。理解事件系统,就如同掌握了整个交互世界的“交通规则”。

今天,我们将深入事件系统的三大核心:

  1. 事件绑定与事件对象:重新审视我们熟悉的bindtap,并解剖事件触发时传递的event对象。
  2. bind vs catch:揭秘事件冒泡机制,以及如何利用它或阻止它。
  3. 传递自定义参数:学习如何通过data-*属性,在事件中携带额外的信息。

掌握这些,你将能够设计出更精妙、更高效的用户交互逻辑。

一、再探事件绑定与事件对象

我们先回顾一下事件处理流程:

  1. WXML中绑定:在组件上使用bindcatch加上事件类型(如bindtap)来指定事件处理函数。
  2. JS中处理:在页面的.js文件中定义同名函数,该函数会自动接收一个event对象作为参数。

这个event对象,就是事件发生时的“现场快照”,它包含了关于这次事件的所有关键信息。让我们来解剖一下它里面有什么宝贝。

动手实践
WXML:

<button bindtap="handleTap">点我查看Event对象</button>

JS:

Page({handleTap: function(event) {console.log(event);}
})

点击按钮后,在控制台展开打印出的event对象,你会看到很多属性,我们重点关注以下几个:

  • type: string,事件的类型,这里是'tap'
  • timeStamp: number,事件生成时的时间戳。
  • target: object,触发事件的源头组件。即使事件冒泡,target也永远是最初那个被点击的组件。
    • event.target.id: 源头组件的id
    • event.target.dataset: 源头组件上所有data-*属性组成的集合。
  • currentTarget: object当前正在处理事件的组件。在事件冒泡过程中,currentTarget会变化,而target不会。
    • event.currentTarget.id: 当前组件的id
    • event.currentTarget.dataset: 当前组件上所有data-*属性组成的集合。

targetcurrentTarget的区别非常重要,我们将在下一节的事件冒泡中看到它们的威力。

二、事件冒泡:bindcatch 的博弈

什么是事件冒泡?

想象一下,你往一个平静的湖里扔一颗石子,水波会从落点(target)开始,一圈圈向外扩散。

在WXML的嵌套结构中,事件的触发也类似。当你点击一个内部组件时,这个事件不仅会通知它自己,还会像气泡一样,从水底(内层组件)不断向上(外层组件)浮起,依次触发所有父级组件上绑定的同类型tap事件,直到文档的根节点。这个过程,就叫做事件冒泡

bind:放行者
使用bind绑定的事件,默认会参与冒泡。它会执行自己的处理函数,然后把事件继续向上传递。

catch:终结者
使用catch绑定的事件,是一个“霸道”的捕获者。它会执行自己的处理函数,然后立即终止事件的冒泡过程,后续的父级组件将收不到这个事件。

动手实践 - 理解冒泡与阻止冒泡:
WXML:

<!-- 使用 bind -->
<view class="outer-box" bindtap="handleOuterTap">Outer Box (bind)<view class="inner-box" bindtap="handleInnerTap">Inner Box (bind)</view>
</view><!-- 使用 catch -->
<view class="outer-box" bindtap="handleOuterTap" style="margin-top: 20rpx;">Outer Box (catch)<view class="inner-box" catchtap="handleInnerTap">Inner Box (catch)</view>
</view>

JS:

Page({handleOuterTap: function() {console.log('触发了 Outer Box 的 tap 事件');},handleInnerTap: function() {console.log('触发了 Inner Box 的 tap 事件');}
})

实验结果:

  1. 点击第一个例子中的“Inner Box (bind)”,你会发现控制台依次打印了“Inner Box”和“Outer Box”的日志。这就是事件冒泡。
  2. 点击第二个例子中的“Inner Box (catch)”,你会发现控制台只打印了“Inner Box”的日志。“Outer Box”的事件被catch阻止了。

应用场景:

  • 事件委托:当一个列表有很多个子项都需要点击事件时,你不需要给每个子项都绑定bindtap。你可以在它们的父容器上绑定一个bindtap,然后通过event.target来判断用户具体点击的是哪个子项。这可以极大地提升性能。
  • 防止误触:在一个弹窗上,通常我们会给遮罩层绑定一个catchtap来关闭弹窗,同时阻止点击事件穿透到下方的页面内容。

三、data-*:事件传递的“秘密信使”

我们经常会遇到这样的需求:一个商品列表中有很多个商品,点击任何一个,都需要跳转到对应的详情页。我们如何知道用户点击的是哪个商品呢?

这时,data-*自定义属性就派上用场了。我们可以将任何需要传递的数据,以data-为前缀,写在组件的属性上。

规则:

  • data-开头,后面跟自定义的名称,如data-product-id
  • 多个单词用连字符-连接。
  • 在事件对象的dataset中,连字符会被自动转换成驼峰命名法(productId)。

动手实践 - 商品列表点击跳转:
JS (先准备数据):

Page({data: {products: [{ id: 'p001', name: '高性能笔记本' },{ id: 'p002', name: '无线机械键盘' },{ id: 'p003', name: '4K显示器' }]}
})

WXML (使用wx:for循环和data-*)

<view class="product-item" wx:for="{{products}}" wx:key="id"bindtap="gotoDetail"data-product-id="{{item.id}}"data-product-name="{{item.name}}"
>{{item.name}}
</view>

在这里,我们为每个商品项绑定了同一个gotoDetail事件,并通过data-product-iddata-product-name把每个商品的独特信息“藏”在了组件上。

JS (处理事件并获取数据):

Page({// ... data 部分 ...gotoDetail: function(event) {// 通过 event.currentTarget.dataset 获取数据const dataset = event.currentTarget.dataset;const productId = dataset.productId; // 注意驼峰命名const productName = dataset.productName;console.log(`用户点击了商品,ID是:${productId},名称是:${productName}`);// 接下来可以执行页面跳转// wx.navigateTo({//   url: `/pages/detail/detail?id=${productId}`// })}
})

点击不同的商品项,看看控制台打印出的ID和名称是不是正确的?通过data-*,我们用一个事件处理函数就优雅地管理了整个列表的点击行为。

结语

今天,我们深入了小程序交互的底层脉络——事件系统。现在,你不仅知道如何响应事件,更理解了事件的传播方式和控制方法。我们回顾一下核心:

  • 事件对象 event 是信息宝库,event.target(源头)和 event.currentTarget(当前处理者)是区分点击来源的关键。
  • 事件冒泡 是默认行为,bind 会放行冒泡,而 catch 会终止它,合理运用可以优化性能和避免误触。
  • data-* 自定义属性 是在WXML向JS传递数据的“秘密信使”,是实现列表类交互的首选方案。

掌握了事件系统,你就拥有了精细化操控用户交互的能力。这为我们构建更复杂的应用打下了坚实的基础。

在下一讲,我们将学习小程序中一个非常强大的特性:列表与条件渲染。我们将学习如何使用wx:forwx:if来动态地生成页面内容,让你的小程序能够根据数据的变化,呈现出千变万化的界面。

我们下篇见!

http://www.dtcms.com/a/402917.html

相关文章:

  • 自助建站免费平台深圳建设管理中心网站首页
  • LVS虚拟调度器学习
  • 【LVS入门宝典】LVS-TUN模式原理与配置:跨越网络界限的负载均衡解决方案
  • 【LVS入门宝典】LVS-TUN模式配置实战以及配置关键点:Real Server的路由表调整、ipip模块加载
  • LVS、Nginx、HAProxy 的区别
  • 是什么让边缘电脑真正工业化?
  • html5手机网站开发环境怎样建设淘宝客导购网站
  • 国检集团官网UI设计展示——专业界面设计实力呈现
  • 【双光相机配准】红外-可见光双光相机的坐标转换原理与实现
  • 图漾相机-ROS2-SDK-Ubuntu 4.X.X版本编译
  • ToF相机之flying pixel
  • 网站建设都需要什么技术人员网站版面做的很好的公司
  • 检测网站是否为WordPress鑫菲互动网站建设公司
  • 小说阅读网站建设微网站在线制作
  • 网站内页百度不收录短视频关键词seo优化
  • SageMaker Studio 高级篇:自动化训练管道与性能优化实战
  • 海誉网站定制做美容一般在哪个网站团购比较好
  • 博山做网站公司岳阳设计网站推荐
  • node怎么做网站秦皇岛网站关键词推广
  • 电子商务网站推广怎么做专业微网站制作
  • 生物科技公司网站建设网站建设在后台哪里查看
  • 华容网站定制怎样在百度打广告
  • 钦州网站建设如何做网站策划案
  • 杭州营销网站建设平台深圳本地做网站
  • 网站域名 空间申请表wordpress 手机发博文
  • 长春网站seo全flash网站
  • 在凡科做网站天津专业制作企业官网
  • 网站中文通用网址域名合肥建设工程招聘信息网站
  • 网站总是打不开济南智能网站建设流程
  • 海通建设集团有限公司网站天津建设工程信息网天津