这两天遇到一个bug,每次点击下方键盘时,点击一次数字,文本框中会出现两次重复值,如下所示:
而且console中还有以下报错信息:
查看项目代码,代码如下:
<ul>
<li
v-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">
<li
v-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>
<li
v-for="(item, index) in keys"
:key="item.val"
v-html="item.name"
@touchstart="handleKeyboardClick(item.val, index)"
@touchend="stateChange(index)">
</li>
</ul>