').html(content...">

JQuery off () does not separate 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(); 

I continue to see the click in the console, so the click does not untie. But if I remove the bind() call, the click will not be attached. Does anyone know why? I need a way to change "this" inside my test function, so I use bind() .

+8
javascript jquery javascript-events jquery-events bind
source share
4 answers

The problem is that this._click.bind() creates a new function every time it is called. To separate a specific event handler, you need to pass the original function that was used to create the event handler, and this does not happen here, so the handler is not deleted.

If your application has only a few bubble , you can go along the Douglas Crockford route and simply not use this . This will eliminate a lot of confusion as to what this refers to, and make sure each bubble maintains a link to its own click function, which can be used to remove the event as needed:

 function bubble(content, tiggerElm) { 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 it frees you from tricks like the .bind() and underscore prefix methods.

+5
source share

One option would be a namespace event :

 $(document).on('click.name', test.bind(this)); $(document).off('click.name'); 

Example here

+5
source share

try using a jQuery proxy to get a unique link to your function.

Thus, when you call $ .proxy (test, this), it checks to see if this function has already been mentioned. If so, the proxy will return this link to you, otherwise it will create it and return it to you. Thus, you can always get your original function, rather than create it again and again (for example, using bind).

Therefore, when you call () and pass it a link to your test function, the off () function will remove your function from the click event.

In addition, before using it, your test function must be declared.

 var test = function(){ console.log('click'); }; $(document).on('click', $.proxy(test, this)); $(document).off('click', $.proxy(test, this)); 

http://jsfiddle.net/aw50yj7f/

+4
source share

Please read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

bind creates a new function, so $(document).on('click', test.bind(this)); similar to $(document).on('click', function(){}); , and each time you execute it, you call a new anonymous function, so you have no reference to unbind.

If you 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

for example: http://jsfiddle.net/508dr0hv/

Also - using bind is not recommended, it is slow and not supported in some browsers.

+3
source share

All Articles