jQuery中常用的事件绑定方式有以下几种:
我们以click事件为例
$(selector).on("click", eventHandler);
$(selector).bind("click", eventHandler);
$(selector).click(eventHandler);
// 上面三种写法实际上都是一样的
// 事件委托(主要用于动态加载的元素)
$(parent).on("click", selector, eventHandler);
那上面两类所对应的事件解绑,需要这么写:
// 元素本身注册事件的方式
$(selector).off("click");
// 事件委托的方式
$(parent).off("click", selector);
这样,我们就可以实现事件的解绑了。
但是,如果我们有这样的需求,比如:某种情况下要把解绑的事件再回复回去时,那就我们就得需要获取绑定的事件句柄了(这里实际上有个小问题:对于委托事件的父元素selector,不同元素事件可能不一样,这样导致我们没办法统一方法处理。我个人呢是把事件统一委托在了document上来避免父元素不一致问题)
// 获取元素事件句柄
function getEventHandler (selector) {
let targetHandler;
// 优先从document委托上找对应元素事件
let eventHandlers = $._data(document, "events");
$.each(eventHandlers, function (eventName, handlers) {
// 过滤click事件
if (eventName == "click") {
$.each(handlers, function (index, handler) {
// 找到对应元素后,得到事件句柄
if (handler.selector == selector) {
targetHandler = handler.handler
}
});
}
})
// 如果document上没有,再找元素本身注册的事件
if(!targetHandler){
eventHandlers = $._data($(selector)[0], "events");
$.each(eventHandlers, function(eventName, handlers) {
// 同样过滤click事件
if(eventName == "click"){
$.each(handlers, function(index, handler) {
// 直接获取事件句柄
targetHandler = handler.handler
});
}
})
}
return targetHandler;
}
代码中这样调用即可:
const selector = "#clickBtn";
const clickEventHandler = getEventHandler(selector); // 获取事件句柄
这样,我们就能获取元素的事件句柄了,如果想给它再重新绑定,直接用就可以,这几种写法都是可以的。
$(selector).on("click", clickEventHandler);
$(selector).bind("click", clickEventHandler);
$(selector).click(clickEventHandler);
$(parent).on("click", selector, clickEventHandler);