这两天遇到一个bug,每次点击下方键盘时,点击一次数字,文本框中会出现两次重复值,如下所示:
而且console中还有以下报错信息:
查看项目代码,代码如下:
<ul><liv-for="(item, index) in keys":key="index"v-html="item.name"@mousedown="handleKeyboardClick(item.val, index)"@touchstart="handleKeyboardClick(item.val, index)"@mouseup="stateChange(index)"@touchend="stateChange(index)"></li>
</ul>
因为该页面要适配PC和APP,所以绑定了mousedown
和touchstart
两个事件,猜测出现此问题的原因是在某些手机上同时触发了mousedown
和touchstart
事件。
通常事件的处理顺序为:
touchstart touchmove touchend mousemove mousedown mouseup click
经过调试发现确实同时触发了两个事件,下面是解决思路:
1.添加stop
事件修饰符阻止冒泡
@touchstart.stop="handleKeyboardClick(item.val, index)"
结果:console中没有报错信息,但是依然还是会触发两次。
2.添加preventDefault
方法
1)在handleKeyboardClick
方法中添加e.preventDefault();
,只是添加了这一行代码,没有添加参数e
,这样console控制台中会报错,但是文本框中只显示一次。
方案一:
handleKeyboardClick: function(code, index) {e.preventDefault();
}
结果:
方案二:
handleKeyboardClick: function(code, index, e) {e.preventDefault();
}
结果:
2)在touchstart
事件中添加上$event
@touchstart="handleKeyboardClick(item.val, index, $event)”
,console不报错,但是文本框显示两个一样的数字。
3.终极解决方案:把mousedown
和touchstart
两个事件拆开,判断设备,是PC的话调用mousedown
事件,否则调用touchstart
事件,这样可以解决该问题,但是缺点就是增加了重复代码。
<ul v-if="isPC"><liv-for="(item, index) in keys":key="item.val"v-html="item.name"@mousedown="handleKeyboardClick(item.val, index)"@mouseup="stateChange(index)"></li>
</ul>
<ul v-else><liv-for="(item, index) in keys":key="item.val"v-html="item.name"@touchstart="handleKeyboardClick(item.val, index)"@touchend="stateChange(index)"></li>
</ul>