最近有个需求,需要在点击时切换图片来产生点击效果。
比如,不点击时显示图片A,手指按下时显示图片B,手指抬起再显示回图片A。
于是我就用touchstart和touchend来做,如下:
wxml:
<view class="backIcon" bindtouchstart="TouchStart" bindtouchend="TouchEnd" >
<image src="{
{backicon}}" style="width: 100%; height: 100%;"></image>
</view>
js:
TouchStart:function()
{ this,setData({backicon : ""}) //显示图片B
}
TouchEnd:function()
{ this,setData({backicon : ""}) //显示图片A
}
分别在手指按下和离开时,显示不同的图片。结果发现touchend 时而触发,时而不触发
百度一搜,遇到类似问题的不少。我觉得如果是BUG的话,就太明显了,官方不可能不修复。
最后才发现原来是因为我在TouchStart方法里使用了this.setData。由于小程序的逻辑层和视图层是双线程,用了setData似乎对脚本产生了阻塞。
解决方法:
1. 分别定义按下和离开的样式,用hover-class代替touchstart和touchend,图片用background-img显示
如下:
<view class="backIcon" hover-class="touchbackIcon">
<!--不要image标签-->
</view>
分别将 backIcon 和 touchbackIcon 里的 background-img定义为离开和按下时需要显示的图片。
.backIcon
{
background-img: url() //显示图片A
background-size: 90rpx 90rpx
}
.touchbackIcon
{
background-img: url() //显示图片B
background-size: 90rpx 90rpx
}
但是这会导致一个问题,background-img如果要显示本地图片,需要使用base64格式,这会导致样式表里需要显示一长串字符,而且以后维护和二次开发时,每次都要转换base64,十分不方便
2. 使用wxs(推荐)
我们用wxs定义两个方法handleTouchStart 和 handleTouchEnd,分别让bindtouchstart 和 bindtouchend去调用,而handleTouchStart 和 handleTouchEnd则去调用js里的TouchStart 和 TouchEnd
如下:
<wxs module="touch">
function handleTouchStart(e, ins)
{
ins.callMethod("touchstart",{}); //调用js里的方法
}
function handleTouchEnd(e, ins)
{
ins.callMethod("touchend",{}); //调用js里的方法
}
module.exports = {
handleTouchStart : handleTouchStart,
handleTouchEnd : handleTouchEnd
}
</wxs>
<view class="backIcon" bindtouchstart="{ {touch.handleTouchStart}}" bindtouchend="{ {touch.handleTouchEnd}}" >
<image src="{ {backicon}}" style="width: 100%; height: 100%;"></image>
</view>
完美解决这个问题