admin管理员组文章数量:1201375
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();
I keep seeing click in the console, so the click does not unbind.
But if I remove the bind()
call the click is unbinded. Does anyone know why? I need a way to be able to change "this" inside my test function, that's why I'm 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();
I keep seeing click in the console, so the click does not unbind.
But if I remove the bind()
call the click is unbinded. Does anyone know why? I need a way to be able to change "this" inside my test function, that's why I'm using bind()
.
6 Answers
Reset to default 6The problem is that this._click.bind()
creates a new function every time it's called. In order to detach a specific event handler, you need to pass in the original function that was used to create the event handler and that's not happening here, so the handler is not removed.
If there are only going to be a few bubble
s in your app, you could and simply not use this
. That will remove a lot of the confusion about what this
is referring to and ensure that each bubble
retains a reference to its own click
function that can be used to remove the event as needed:
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();
See how this frees you from using contrivances like .bind()
and underscore-prefixed methods.
One option would be to namespace the event:
$(document).on('click.name', test.bind(this));
$(document).off('click.name');
Example Here
try use jQuery's proxy to get a unique reference of your function.
In this way, when you call $.proxy(test, this), it will check if this function has already been referenced before. If yes, proxy will return you that reference, otherwise it will create one and return it to you. So that, you can always get your original function, rather than create it over and over again (like using bind).
Therefore, when you call off(), and pass it the reference of your test function, off() will remove your function from click event.
And also, your test function should be declared before use it.
var test = function(){
console.log('click');
};
$(document).on('click', $.proxy(test, this));
$(document).off('click', $.proxy(test, this));
http://jsfiddle.net/aw50yj7f/
Please read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
bind creates a new function therefore doing $(document).on('click', test.bind(this));
is like $(document).on('click', function(){});
and each time you execute it you invoke a new anonymous function thus you dont have a reference to unbind.
If you would do something like:
var test = function(){
console.log('click');
};
var newFunct = test.bind(this);
$(document).on('click', newFunct );
$(document).off('click', newFunct );
It should work fine
e.g: http://jsfiddle.net/508dr0hv/
Also - using bind is not recommended, its slow and not supported in some browsers.
rather than binding this to the event, send this as a parameter:
$("#DOM").on("click",{
'_this':this
},myFun);
myFun(e){
console.info(e.data._this);
$("#DOM").off("click",myFun);
}
If you've run into this problem when using classes, an alternative I found is to replace the handler definition with an assignment to a bound function:
//Replace this
onclick(e) {
//...
}
//With this:
onclick = function(e) {
//...
}.bind(this);
It's not very pretty, but it does save a refactor if you've already written the code.
本文标签: javascriptjQuery off() is not unbinding events when using bindStack Overflow
版权声明:本文标题:javascript - jQuery off() is not unbinding events when using bind - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738579323a2101065.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论