刚刚在写页面时出现的一个问题,记录一下
~ 问题复现:
首先在html结构中创建一个btn按钮,然后引入jQuery,并获取到指定的btn按钮ID,然后绑定事件,点击时输出测试内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<title>清除方法测试</title>
</head>
<body>
<button id="btn" type="button">
我是按钮
</button>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script>
let btn = $(`#btn`)
btn.click(btnClick)
function btnClick () {
console.log('按钮被点击了')
}
</script>
</html>
类似一个这样的结构,不过在特殊条件下需要对按钮的事件进行清除,我也是理所当然在需要的地方加上了
btn.click(null)
但是方法仍然在执行,但是当时的确没找到问题的关键。
~ 问题解决:
首先是jQuery的click()方法:
先看官方文档,
概述
触发每一个匹配元素的click事件。
这个函数会调用执行绑定到click事件的所有函数。
参数
fn
在每一个匹配元素的click事件中绑定的处理函数。
[data],fn
data
:click([Data], fn) 可传入data供函数fn处理。
fn
:在每一个匹配元素的click事件中绑定的处理函数。
文档中也指出了是执行绑定在匹配元素的“所有”函数,当执行这行时,其实是在click后新添加了一个新的方法,和原生中直接将指定的方法清空不同
btn.click(null)
可以通过测试,来查看结果,script部分代码:
let btn = $(`#btn`)
btn.click(function () {
console.log('按钮被点击了')
})
btn.click(function () {
console.log("我是第二个测试方法");
})
执行结果:
这里可以看出,原来的方法并没有被替换,而是在后面新添加了一个新的方法,调用顺序就是代码的先后顺序,所以当click(null)时,也是添加了一个null的函数,原来的函数并没有清空
~ 解决方式:
使用jQuery中提供的off()方法进行选中内容的方法的清除可以看下文档给出的定义:
在选择元素上移除一个或多个事件的事件处理函数。
off() 方法移除用
.on()
绑定的事件处理程序。有关详细信息,请参阅该网页上delegated和directly绑定事件。特定的事件处理程序可以被移除元素上提供事件的名称,命名空间,选择器,或处理函数名称的组合。
当有多个过滤参数,所提供的参数都必须匹配的事件处理程序被删除。
要删除特定的委派事件处理程序,提供一个selector 的参数。选择器字符串必须是完全匹配递到.on()事件处理程序附加的选择器。要删除非委托元素上的所有事件,使用特殊值 “**” 。
处理程序也可以删除handler参数指定名称的函数。当jQuery的绑定一个事件处理程序,它分配一个唯一的ID给处理函数。函数用
jQuery.proxy()
代理或类似有相同的唯一ID机制(代理函数),因此,通过代理处理程序.off 可能会删除比预期更多的处理程序。在这些情况下,最好是附加和移除事件处理程序,使用命名空间。
和.on()一样,你可以传递一个 events-map>参数明确的指定而不是用events 和 handler作为单独参数。键事件和/或命名空间;值是处理函数或为false的特殊价值。
所以使用off()进行清除才是正解,最终代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<title>清除方法测试</title>
</head>
<body>
<button id="btn" type="button">
我是按钮
</button>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script>
let btn = $(`#btn`)
btn.click(btnClick)
function btnClick () {
console.log('按钮被点击了')
}
btn.off('click',btnClick)
</script>
</html>
end