el-table
实现行单击
和行双击
事件,但是发现每次行双击
都会触发2次行单击
事件。于是,在事件中添加防抖机制
(setTimeout
异步实现)
加入防抖机制
后,代码报错如下:
Uncaught TypeError: Cannot read properties of null (reading 'hasAttribute')
at getAttributeValue (clipboard.js?b311:299)
at Clipboard.defaultAction (clipboard.js?b311:220)
at Clipboard.onClick (clipboard.js?b311:203)
at handleClipboard (VM61884 clipFunc.js:24)
at eval (DetailList.vue?0edb:126)
逗逼博主无奈求助度娘,却迟迟找不到对的解决方法,被导师逼着不停想解决方法QAQ:
el-table 行单击和行双击冲突
》Cannot read properties of null
》js 双击不触发单击
》setTimeout event 消失
》setTimeout的坑
》event.currentTarget 文档
》event.currentTarget生命周期
异步操作setTimeout
中event.currentTarget
会置空的问题,需要单独保存它的值。
const tmp = e.currentTarget // ! 保存e.currentTarget
导师询问原因,又开始一轮疯狂检索:
event.currentTarget 文档
》event.currentTarget生命周期
最终发现原因:event
产生的时候会注册currentTarget
,等该event绑定的主线程中的事件顺序执行结束后,立刻会将它置为null。所以只要在顺序事件执行结束前,单独保存event.currentTarget
就可以了。
function func (e) {
console.log(1, e.currentTarget===null) // false
sleep(2000)
console.log(2, e.currentTarget===null) // false
const tmp = e.currentTarget // ! 保存e.currentTarget
timeOut= setTimeout(function () {
console.log('单击');
console.log(3, e.currentTarget===null) // true
console.log('tmp', tmp===null) // false
}, time)
console.log(4, e.currentTarget===null) // false
}
function sleep(d){
let t = Date.now();
while(Date.now() - t <= d);
}
1 false // 同步函数 start
2 false // sleep(2000)
4 false // 同步函数end
'单击'
3 true // 延迟器的异步输出
'tmp' false // 单独保存
class Event {
constructor(type, target) {
this.type = type
this.target = target
this.currentTarget = null
}
static fire(type, target, currentTarget) {
const event = new Event(type, target)
// 事件触发时, 将 currentTarget 绑定到事件对象中
event.currentTarget = currentTarget
// 执行监听的函数
event.currentTarget.eventListener[type].forEach(fn => fn(event))
// 事件处理结束后,再将 currentTarget 移除
event.currentTarget = null
}
}