jQuery 使用 bind 时 off() 不是解除绑定事件
jQuery off() is not unbinding events when using bind
function bubble(content, triggerElm){
this.element = $('<div class="bubble" />').html(content);
this.element.css(.....) // here is positioned based on triggerElm
}
bubble.prototype.show = function(){
$(document).on('click', this._click.bind(this));
this.element.css(....)
};
bubble.prototype.hide = function(){
$(document).off('click', this._click.bind(this));
this.element.css(....)
};
bubble.prototype._click = function(event){
console.log('click', this);
if(this.element.is(event.target) || (this.element.has(event.target).length > 0))
return true;
this.hide();
};
var b = new bubble();
b.show();
b.hide();
我一直在控制台看到点击,所以点击并没有解除绑定。
但是,如果我删除 bind()
调用,点击将被解除绑定。有谁知道为什么?我需要一种能够在我的测试函数中更改 "this" 的方法,这就是我使用 bind()
.
的原因
一个选择是 namespace the event:
$(document).on('click.name', test.bind(this));
$(document).off('click.name');
请阅读https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
bind 创建一个新函数,因此 $(document).on('click', test.bind(this));
就像 $(document).on('click', function(){});
,每次执行它时都会调用一个新的匿名函数,因此您没有对 unbind 的引用。
如果你会这样做:
var test = function(){
console.log('click');
};
var newFunct = test.bind(this);
$(document).on('click', newFunct );
$(document).off('click', newFunct );
它应该可以正常工作
例如:http://jsfiddle.net/508dr0hv/
另外 - 不推荐使用绑定,它很慢并且在某些浏览器中不受支持。
尝试使用 jQuery 的代理来获取您的函数的唯一引用。
这样,当你调用$.proxy(test, this)时,它会检查这个函数之前是否已经被引用过。如果是,proxy 将 return 你那个引用,否则它会创建一个并 return 给你。这样一来,您始终可以获得原始功能,而不是一遍又一遍地创建它(例如使用绑定)。
因此,当您调用 off() 并将测试函数的引用传递给它时,off() 将从点击事件中删除您的函数。
此外,您的测试函数应该在使用前声明。
var test = function(){
console.log('click');
};
$(document).on('click', $.proxy(test, this));
$(document).off('click', $.proxy(test, this));
问题是 this._click.bind()
每次调用都会创建一个新函数。为了分离特定的事件处理程序,您需要传入用于创建事件处理程序的原始函数,但此处不会发生这种情况,因此不会删除处理程序。
如果您的应用中只有几个 bubble
,您可以并且根本不使用 this
。这将消除很多关于 this
指的是什么的混淆,并确保每个 bubble
保留对其自己的 click
函数的引用,该函数可用于根据需要删除事件:
function bubble(content, triggerElm) {
var element = $('<div class="bubble" />').html(content);
element.css(.....); // here is positioned based on triggerElm
function click(event) {
console.log('click', element);
if (element.is(event.target) ||
element.has(event.target).length > 0) {
return true;
}
hide();
}
function show() {
$(document).on('click', click);
element.css(....);
}
function hide() {
$(document).off('click', click);
element.css(....);
}
return {
show: show,
hide: hide
};
}
var b1 = bubble(..., ...);
b1.show();
var b2 = bubble(..., ...);
b2.show();
了解这如何使您免于使用 .bind()
和下划线前缀方法等发明。
与其将其绑定到事件,不如将其作为参数发送:
$("#DOM").on("click",{
'_this':this
},myFun);
myFun(e){
console.info(e.data._this);
$("#DOM").off("click",myFun);
}
function bubble(content, triggerElm){
this.element = $('<div class="bubble" />').html(content);
this.element.css(.....) // here is positioned based on triggerElm
}
bubble.prototype.show = function(){
$(document).on('click', this._click.bind(this));
this.element.css(....)
};
bubble.prototype.hide = function(){
$(document).off('click', this._click.bind(this));
this.element.css(....)
};
bubble.prototype._click = function(event){
console.log('click', this);
if(this.element.is(event.target) || (this.element.has(event.target).length > 0))
return true;
this.hide();
};
var b = new bubble();
b.show();
b.hide();
我一直在控制台看到点击,所以点击并没有解除绑定。
但是,如果我删除 bind()
调用,点击将被解除绑定。有谁知道为什么?我需要一种能够在我的测试函数中更改 "this" 的方法,这就是我使用 bind()
.
一个选择是 namespace the event:
$(document).on('click.name', test.bind(this));
$(document).off('click.name');
请阅读https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
bind 创建一个新函数,因此 $(document).on('click', test.bind(this));
就像 $(document).on('click', function(){});
,每次执行它时都会调用一个新的匿名函数,因此您没有对 unbind 的引用。
如果你会这样做:
var test = function(){
console.log('click');
};
var newFunct = test.bind(this);
$(document).on('click', newFunct );
$(document).off('click', newFunct );
它应该可以正常工作
例如:http://jsfiddle.net/508dr0hv/
另外 - 不推荐使用绑定,它很慢并且在某些浏览器中不受支持。
尝试使用 jQuery 的代理来获取您的函数的唯一引用。
这样,当你调用$.proxy(test, this)时,它会检查这个函数之前是否已经被引用过。如果是,proxy 将 return 你那个引用,否则它会创建一个并 return 给你。这样一来,您始终可以获得原始功能,而不是一遍又一遍地创建它(例如使用绑定)。
因此,当您调用 off() 并将测试函数的引用传递给它时,off() 将从点击事件中删除您的函数。
此外,您的测试函数应该在使用前声明。
var test = function(){
console.log('click');
};
$(document).on('click', $.proxy(test, this));
$(document).off('click', $.proxy(test, this));
问题是 this._click.bind()
每次调用都会创建一个新函数。为了分离特定的事件处理程序,您需要传入用于创建事件处理程序的原始函数,但此处不会发生这种情况,因此不会删除处理程序。
如果您的应用中只有几个 bubble
,您可以并且根本不使用 this
。这将消除很多关于 this
指的是什么的混淆,并确保每个 bubble
保留对其自己的 click
函数的引用,该函数可用于根据需要删除事件:
function bubble(content, triggerElm) {
var element = $('<div class="bubble" />').html(content);
element.css(.....); // here is positioned based on triggerElm
function click(event) {
console.log('click', element);
if (element.is(event.target) ||
element.has(event.target).length > 0) {
return true;
}
hide();
}
function show() {
$(document).on('click', click);
element.css(....);
}
function hide() {
$(document).off('click', click);
element.css(....);
}
return {
show: show,
hide: hide
};
}
var b1 = bubble(..., ...);
b1.show();
var b2 = bubble(..., ...);
b2.show();
了解这如何使您免于使用 .bind()
和下划线前缀方法等发明。
与其将其绑定到事件,不如将其作为参数发送:
$("#DOM").on("click",{
'_this':this
},myFun);
myFun(e){
console.info(e.data._this);
$("#DOM").off("click",myFun);
}