双击事件与单击事件的那些事
前言
项目遇到了双击事件会同时触发单击事件的bug,还是简单记录一下。
心里话:日更太累了。以前都是单独花好几天的时间去看别人的博客,看很多博客后再慢慢输出。现在是边输入边输出(有时候为了能偷懒还把一长篇拆成两部分),薅完这次全勤羊毛,之后随缘参加日更活动了(再这样下去,感觉写博客的初心都快变了)
问题重现
1 2 3
| <el-button type="primary" @click="myclick" @dblclick="mydblclick"> test </el-button>
|
1 2 3 4 5 6 7
| function myclick() { console.warn("单击事件"); }
function mydblclick() { console.error("双击事件"); }
|
合情合理,双击事件也是两次点击事件,所以同时会触发单击事件click
和双击事件dblclick
。但是需求是单击和双击不同的处理,所以双击的时候不应该触发单击事件。
解决方案
思路:可以使用函数防抖的做法,单击事件触发后,开启一个定时器,双击事件触发的话就清除定时器。
1 2 3 4 5 6 7 8 9 10 11 12
| let timer;
function myclick() { timer = setTimeout(() => { console.warn("单击事件"); }, 300); }
function mydblclick() { clearTimeout(timer); console.error("双击事件"); }
|
可以发现还是有问题,双击事件还是会触发一次单击事件。
但这个问题实际上是定时器的使用上有点问题。先看个小案例。
1 2 3 4 5 6 7 8 9 10 11
| let timer;
timer = setTimeout(() => { console.log(1); });
timer = setTimeout(() => { console.log(2); });
clearTimeout(timer);
|
这个案例中,会打印1
。也就是说实际上只清楚了第二个定时器,所以我们之前的代码还需要清除第一个定时器才行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| let timer;
function myclick() { clearTimeout(timer);
timer = setTimeout(() => { console.warn("单击事件"); }, 300); }
function mydblclick() { clearTimeout(timer); console.error("双击事件"); }
|
大功告成。
el-checkbox使用注意点
双击事件和单击事件的问题处理完了,再加上一下下项目的踩坑点。
el-checkbox
没有事件对象,平常的事件对象在el-checkbox
上是布尔值,表示是否选中。但是原生版本是有的。
1 2
| <el-checkbox @change="mychange"></el-checkbox> <input type="checkbox" @click="mychange" />
|
1 2 3
| function mychange(e) { console.log(e); }
|
另外,直接修改checkbox
绑定的值,不会触发change
事件。
change事件直接修改值不会触发。
1 2
| <input type="checkbox" v-model="checked" @click="mychange" /> <button @click="myclick">change</button>
|
1 2 3 4 5 6 7 8 9 10 11
| import { ref } from "@vue/reactivity";
const checked = ref(true);
function mychange(e) { console.log(e); }
function myclick() { checked.value = !checked.value; }
|
可以在直接修改绑定值的同时,手动调用change
事件的处理函数来模拟触发change
事件,不过,事件对象的传参就不太好模拟了。当然,如果使用的是el-checkbox
的话,因为它没有事件对象,而是布尔值,所以只需要把checkbox
当前绑定的值传过去即可。