Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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();

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().

like image 340
Elfy Avatar asked Mar 02 '15 00:03

Elfy


People also ask

Does jQuery remove unbind events?

jQuery unbind() MethodThe unbind() method removes event handlers from selected elements. This method can remove all or selected event handlers, or stop specified functions from running when the event occurs.

What is the purpose of using bind () method in jQuery?

bind() method is used for attaching an event handler directly to elements. Handlers are attached to the currently selected elements in the jQuery object, so those elements must exist at the point the call to .

Which jQuery function can be used to override events in jQuery?

Projects In JavaScript & JQuery Use the off() method to override jQuery event handlers. This method is used to remove an event handler. The on() method is used to attach one or more event handler.

How do you turn off a function in jQuery?

jQuery off() MethodThe off() method is most often used to remove event handlers attached with the on() method. As of jQuery version 1.7, the off() method is the new replacement for the unbind(), die() and undelegate() methods.


1 Answers

The 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 bubbles 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.

like image 163
JLRishe Avatar answered Sep 19 '22 17:09

JLRishe