本文详解JavaScript中removeEventListener取消事件监听的原理与常见陷阱。重点分析为何匿名函数无法取消监听,以及如何通过封装函数实现带参回调。针对TypeScript中因参数类型不匹配导致的编译报错,提供使用any类型或正确定义可选参数的解决方案,帮助开发者避免内存泄漏和类型错误。
addEventListener与回调函数传参限制
首先从addEventListener的使用方式谈起,具体代码如下所示。
onMounted(() => {
window.addEventListener("click", ()=>{
doSth(param)//param为参数
})
})在addEventListener中,如果直接传入箭头函数作为回调,该箭头函数本身无法直接接收除event以外的参数。若需传递参数,必须在doSth函数内部处理。另一种做法是将箭头函数替换为普通函数,但该函数同样不能带有参数。
onMounted(() => {
window.addEventListener("click", doSth)//这个doSth就没有参数了
})如果确实需要让doSth接收参数,可以在函数外部再包裹一层函数来实现。
let doSth1=()=>{
doSth(param)
}
onMounted(() => {
window.addEventListener("click", doSth1)//这个doSth1就是外面包装的函数
})removeEventListener取消监听的引用匹配问题
上述原理同样适用于removeEventListener,但在使用removeEventListener时还有一个关键注意点,详见下文。
onMounted(() => {
window.addEventListener("click", () => {
doSth()
})
})
onUnmounted(() => {
window.removeEventListener("click", () => {
doSth()
})
})前文提到的写法无法成功取消监听,因为removeEventListener的第二个参数(即回调函数)必须与addEventListener中传入的回调函数是同一个引用,共享内存地址。采用以下写法即可正确执行。
onMounted(() => {
window.addEventListener("click", doSth)
})
onUnmounted(() => {
window.removeEventListener("click",doSth)
})然而,上述写法依然无法直接传递参数。若需传参,仍需在外层包裹一个函数,具体实现如下。
let doSth = (str: string) => {
console.log(str);
}
let doSth1 = () => {
doSth("haha")
}
onMounted(() => {
window.addEventListener("click", doSth1)
})
onUnmounted(() => {
window.removeEventListener("click", doSth1)
})TypeScript环境下的类型错误与解决方案
如果使用TypeScript,doSth函数的参数可以定义为可选参数,实现方式如下。
let doSth = (str?: string) => {
if (typeof str == "string") {
console.log("传参了");
} else {
console.log("没传参");
}
}
onMounted(() => {
window.addEventListener("click", doSth)
})
onUnmounted(() => {
window.removeEventListener("click", doSth)
})此时编译器会提示一条错误信息。
显示“没有与此调用匹配的重载”。
第1个重载(共2个):(type: "click", listener: (this: Window, ev: MouseEvent) => any, options?: boolean | AddEventListenerOptions | undefined): void,出现以下错误。
第2个重载(共2个):(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void,出现以下错误。
尽管这样在实际运行中并无问题,但报错信息较为繁琐。若希望避免在外层再包裹一层函数,可以直接将doSth的类型定义为any。
let doSth: any = (str: string) => {
if (typeof str == "string") {
console.log("传参了");
} else {
console.log("没传参");
}
}
onMounted(() => {
window.addEventListener("click", doSth)
})
onUnmounted(() => {
window.removeEventListener("click", doSth)
})其根本原因目前尚不明确,后续需进一步研究。
总结
至此,关于JavaScript中removeEventListener取消事件监听的讲解结束。如需了解更多相关内容,可搜索本站往期文章或继续浏览相关文章。感谢大家的支持!