微信小程序为DOM无缝增加open-type开放能力

213 阅读3分钟

微信小程序为DOM无缝增加open-type开放能力

前言

最近在尝试 Vue Mini 这个框架,来开发一个小程序,祝我成功(因为半途而废的项目真的太多太多了)

期间遇到一个场景,就是需要用户点击cell单元格组件时调用微信小程序提供的开放能力。比如,点击cell时打开意见反馈的页面。

遇到的问题 - 必须存在的Button

首先,微信小程序为了安全起见,是不支持JS模拟点击的操作的,即我是无法通过JS来打开意见反馈的功能。这也很好理解,因为比如用户手机号、头像等隐私信息如果可以通过JS来获取,那么你只要一登录该小程序,你的信息就被拿完了,而你却浑然不知。

所以,页面上是必须存在button组件的,这里简单解释一下,微信小程序提供的能力都是放在button组件上的,比如刚才的意见反馈页面的打开,就只需要在button组件上加上open-type="feedback"即可,更多开放能力可以参考微信小程序官方文档

但是为了页面统一,笔者这里是使用的cell,而这里又需要button,有没有办法让其共存呢,即样式展示的cell,而点击效果是触发的button。当然有,这里是本文接下来要讲到的。

解决问题 - CSS隐藏Button

既然提到样式,很容易的想到使用CSS来解决,我们先找个位置放上这个button,这里笔者使用button套用cell组件,像下面这样:

<button open-type="feedback" >
	<t-cell title="意见反馈" leftIcon="chat-message" hover arrow />
</button>

此时页面的效果如下:

可以看到携带了一些button组件的自带样式,比如左右paddingborder之类的,这里我们去除button自带的默认样式:

<button class="no-style-btn" open-type="feedback" >
	<t-cell title="意见反馈" leftIcon="chat-message" hover arrow />
</button>
.no-style-btn {
  padding: 0;
}

.no-style-btn::after {
  display: none;
}

这是现在的效果:

新的问题 - 消失的Cell点击反馈

也支持点击跳转到意见反馈的页面了,看着没效果,但是稍微注意一下就会发现此时点击cell组件的点击反馈消失了,之前是会有这个置灰效果的(这里用上面的cell点击做演示):

分析问题 - 事件未传递给Cell

通过绑定buttoncell组件打印日志:

<button class="no-style-btn" open-type="feedback" bind:tap="handleBtnTap" >
	<t-cell title="意见反馈" leftIcon="chat-message" hover arrow bind:tap="handleCellTap" />
</button>

我们可以清楚的看到我们在点击意见反馈时,handleCellTap根本没有触发,这也很好理解,事件被父元素的button给捕获了,自然不会传递给下面的子组件cell

解决问题 - pointer-events自定义事件触发

这里笔者稍微问了一个Claude,它给出了pointer-events方法来解决,简单来说,就是让button不进行事件捕获,让cell来捕获事件,然后通过事件冒泡的机制,自动向上传递。

最终其实就这三句代码:

.no-style-btn {
  padding: 0;
  pointer-events: none; /* 让按钮不捕获鼠标事件 */
}

.no-style-btn > view {
  pointer-events: auto; /* 让按钮内的元素捕获鼠标事件 */
}

.no-style-btn::after {
  display: none;
}

此时我们的意见反馈cell也有了对应的点击反馈,同时也能触发 open-type 的开放能力了: