views:

920

answers:

4

I was reading the great article about binding and unbinding events (because I am a js beginner using jQuery) on Karl Swedberg's blog, and I became totally puzzled at this part of the code (simplified for brevity):

    function addItemUnbind() {
      $Add a button but it won't have it's event added;
      addItemUnbind();
  });

Why is it that by putting the same function within itself it doesn't keep executing into an infinite loop? However, it is used to re-bind the event to the element...!?

+9  A: 

As far as i can tell your example will. However your example is not the same as the example on the website you reference.

function addItemUnbind() {
  $('#list6 li.special button')
    .unbind('click')
    .bind('click', function() {
      var $newLi = $('<li class="special">special and new <button>I am new</button></li>');
      $(this).parent().after($newLi);
      addItemUnbind();
  });
}

In this example the 'addItemUnbind' is called when the user clicks on the button.

Greg Dean
+3  A: 

Because the call is within an internal function.

E.g. He does some stuff in addItemUnbind() and one of those things is to bind a function to a button click.

This function is then declared e.g. within addItemUnbind() there is:

.bind('click', function() {
  var $newLi = $('<li class="special">special and new <button>I am new</button></li>');
  $(this).parent().after($newLi);
  addItemUnbind();
  }

The code within the braces here isn't evaluated when addItemUnbind() is called but rather when the click happens.

Graphain
A: 

The answer is hiding in part of the code you took out. What you've posted is indeed an infinite loop. However, here's a more complete (but still simplified) example, modified from the linked blog post:

function addItemUnbind() {
  bind('click', function() {
    addItemUnbind();
  });
}

The call to addItemUnbind is inside a closure--a new anonymous function that's separate from the addItemUnbind function that created it. Rather than being called right away, a reference to the new function is being passed into the bind function. So if the bind function looked like this:

function bind(eventName, eventHandler) {
  eventHandler();
}

then you'd have an infinite loop, because the call to eventHandler would lead back into addItemUnblind. But if it looks like this:

function bind(eventName, eventHandler) {
  this.events[eventName] = eventHandler; // save the event handler to call when an event happens
}

then there's no problem. It doesn't call addItemUnbind, it just saves a reference to a function that will call it later on.

Moss Collum
A: 

Ah.... as in a lot of things.... "observation Daniel!". Admittedly too there was an anomaly in the way I had thought event handling worked which caused me to skim the article over what I thought I already knew. I see clearly now thanks to your careful explanations.

Daniel