微信小程序从入坑到放弃二十九:一个小场景搞懂冒泡事件bindtap和catchtap的区别

摘要:
在微信小程序中,bindtap事件会产生冒泡,若不加以拦截,会一直冒泡到顶端。在某些情况下,一次点击会触发若干点击事件。为了防止冒泡,使用catchtap即可解决问题。在有全屏半透明背景的弹出层效果中,可以使用catchtouchmove来阻止页面滚动发生穿透。

微信小程序从入坑到放弃二十九:一个小场景搞懂冒泡事件bindtap和catchtap的区别

    • 一、起因
    • 二、相关知识点
    • 三、实战代码
      • 3.1、项目文件列表
      • 3.2、/index/index.wxml 中的代码
      • 3.3、/index/index.js 中的源码
      • 3.4、为什么是catchtap而不是bindtap?
      • 3.5、页面滑动时也要处理
    • 四、demo源码

一、起因

昨天下午,微信上一个近半年未联系的好友突然发消息问我问题。如图:微信小程序从入坑到放弃二十九:一个小场景搞懂冒泡事件bindtap和catchtap的区别_第1张图片
近一步沟通过后,了解了她的需求。大白话就是:点击非红框框区域时隐藏这个框框。

二、相关知识点

她的这个需求实际上跟弹出层差不多,点击非操作区域时都隐藏功能。这里有两个知识点:

  1. 事件冒泡;
  2. 页面滚动穿透(遮罩层背景时用到,此处顺带提一笔)。
    在微信小程序项目开发中,事件冒泡是家常便饭,也略有小坑。废话不多说,直接上代码。

三、实战代码

为了更直观的复现问题,暂时不封装组件,直接在/index/index.wxml页面中写代码。

3.1、项目文件列表

  • 微信小程序项目根目录
    • index /* 项目首页 */
      • index.wxml /* 模板页 */
      • index.js /* js */
      • index.wxss /* 样式文件 */
      • index.json /* 配置文件 */
    • … /* 其他文件 */

3.2、/index/index.wxml 中的代码


  页面内容区
  
    23小时前删除
  
    
      ...
      
        取消
        评论
      
    
  

3.3、/index/index.js 中的源码

var app = getApp();
Page({
  data: {
    isShow: false /* 弹窗显隐 */
  },
  onLoad: function () {},
  /* 点击时显示弹出评论功能 */
  handleShowPingLun() {
    this.setData({
      isShow: !this.data.isShow
    })
  },
  /* 禁止向上冒泡(非操作区域时关闭弹窗) */
  handleCatchTap() {
    if (this.data.isShow) {
      this.setData({
        isShow: false
      })
    }
  },
  /* 滑屏(页面滚动时也关闭弹窗) */
  handleTouchmove() {
    this.handleCatchTap()
  }
});

wxss的代码就不写了,注意上面的catchtap事件,这是实现功能的关键!

3.4、为什么是catchtap而不是bindtap?

首先我们看最里面的事件:catchtap=“handleShowPingLun”,可能很多看官这里会把catchtap写成bindtap。如果这里写成了bindtap,那么当用户点击时,事件会正常一层层向上冒泡,一直冒到当前代码的最外层,也就是view.page这个标签上。当用户在view.page上也添加了tap点击事件时,此时一次点击就会至少触发两次点击。若是这样,我们的业务代码就极有可能存在隐藏bug!当向上的层级树上也有tap点击事件时,此时一次点击就会触若干其他的功能,后果不堪设想!如图:微信小程序从入坑到放弃二十九:一个小场景搞懂冒泡事件bindtap和catchtap的区别_第2张图片
为了防止事件向上冒泡,触发不必要的功能,我们可以把bindtap改为catchtap,也就是示例代码那样,现在我们再来点击看控制台的打印情况。如图:微信小程序从入坑到放弃二十九:一个小场景搞懂冒泡事件bindtap和catchtap的区别_第3张图片
同理,view.pinglun-tool的子级view.pinglun__link也要进行冒泡拦截,就是把bindtap改为catchtap。至于原因,仔细回味下上面几张配图应该能理解。
关于事件,请参见微信官方文档的描述:事件的使用方式
最后我们来看一个gif动图演示,如图:catchtap成功阻止事件向上冒泡微信小程序从入坑到放弃二十九:一个小场景搞懂冒泡事件bindtap和catchtap的区别_第4张图片
怎么样,功能已经实现了,那是不是就结束了呢?

3.5、页面滑动时也要处理

事情并没有至此结束。虽然我们已经做到了点击非评论弹层区域时隐藏弹层的功能,但页面滚动时呢???所以,我们还需要解决页面滚动时的情况。这时,bindtouchmovecatchtouchmove就出场了,具体使用哪个也要看实际的场景。若项目中有一个弹层且带有全屏的半透明背景,那就需要使用catch来禁止页面滚动。示例参见文章:微信小程序从入坑到放弃二十二:完美兼容安卓和ios手机的底部评论框
本文这里可以使用bind,也就是bindtouchmove

现在,我们算是大功告成了。在实际项目中,评论弹层通常会被封装成一个组件,那么此时的防冒泡处理和滑屏处理就需要写在父级组件或根组件中,具体怎样要看开发者的代码构造。

四、demo源码

demo源码已上传到了github上,如果看官需要研究源码,可以点击下面的链接进行访问并下载。
分支dev-bindtap-and-catchtap-20200605
源码中会有必要注释和本篇文章中的示例。若有疑问可与艺灵联系,方式见下方二维码或右侧。

文章来源
原文首发于:艺灵设计,转载请注明来源。

你可能感兴趣的:(微信小程序-日常踩坑)