Почему этот javascript (jQuery) не заходит в бесконечный цикл?

Я читал замечательную статью о связывании и развязывании событий (потому что я новичок в js, использующий jQuery) в блоге Карла Сведберга , и я полностью озадачился этой частью кода (упрощенной для краткости):

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

Почему, помещая одну и ту же функцию в себя, она не продолжает выполняться в бесконечном цикле? Однако он используется для повторного связывания события с элементом ...!?

11.12.2008 03:13:26
4 ОТВЕТА
РЕШЕНИЕ

Потому что вызов внутри внутренней функции.

Например, он делает некоторые вещи в addItemUnbind (), и одна из этих вещей - привязать функцию к нажатию кнопки.

Затем эта функция объявляется, например, внутри addItemUnbind ():

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

Код в фигурных скобках здесь не оценивается при вызове addItemUnbind (), а когда происходит щелчок.

3
11.12.2008 03:23:07

Насколько я могу сказать, ваш пример будет. Однако ваш пример не совпадает с примером на веб-сайте, на который вы ссылаетесь.

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

В этом примере addItemUnbind вызывается, когда пользователь нажимает кнопку.

9
11.12.2008 21:40:14

Ответ скрывается в части кода, который вы вынули. То, что вы опубликовали, действительно бесконечный цикл. Тем не менее, вот более полный (но все еще упрощенный) пример, модифицированный из ссылки в блоге:

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

Вызов addItemUnbind находится внутри замыкания - новой анонимной функции, которая отделена от функции addItemUnbind, которая ее создала. Вместо непосредственного вызова ссылка на новую функцию передается в функцию связывания. Так что, если функция связывания выглядела так:

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

тогда у вас будет бесконечный цикл, потому что вызов eventHandler приведет к addItemUnblind. Но если это выглядит так:

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

тогда нет проблем. Он не вызывает addItemUnbind, он просто сохраняет ссылку на функцию, которая вызовет ее позже.

0
11.12.2008 03:31:23

Ах .... как во многих вещах .... "наблюдение Даниэль!" По общему признанию, в том, как я думал, что обработка событий работала, была аномалия, из-за которой я пролистал статью над тем, что, как мне казалось, я уже знал. Теперь я ясно вижу, благодаря вашим осторожным объяснениям.

0
11.12.2008 04:27:33