Jquery - (пере) подключение динамически генерируемых элементов

Часто у меня есть элементы, привязанные к дополнительной функциональности, например:

$('.myfav').autocomplete();
$('.myfav').datepicker();
$('.myfav').click(somefunction);

Но когда с помощью какого-то кода динамически генерируется больше экземпляров этого класса, новые $('.myfav') мертвы и нуждаются в перемонтаже, поэтому я делаю следующее:

$("#somelink").click(function(){
     //generate 10 new $('.myfav') and append them to the DOM
     //re-wire them again as in the block above
     $('.myfav').autocomplete();
     $('.myfav').datepicker();
     $('.myfav').click(somefunction);
});

Это означает, что в итоге у меня есть 2 идентичных блока кода: 1 для начальной загрузки страницы и один для перепрограммирования новых элементов, которые генерируются динамически. Это не СУХОЙ код и не очень эффективный.

Это действительно единственный способ сделать это или есть другая лучшая практика? Моя интуиция подсказывает мне, что должно быть что-то более эффективное, чем это (также чтобы помочь высушить код).

обновить

Похоже, .live хорошо работает с .click, как объяснил Клетус.

$('.myfav').live("click", somefunction);

Но я попробовал это с пользовательскими плагинами, такими как .autocomplete, и это не сработало. Я пробовал это:

$('.myfav').live("click", autocomplete("somefile.php", {max: 15, mustMatch: true}));

Так что live не выглядит так, как будто он может обрабатывать эти пользовательские плагины (конечно, я могу ошибаться, пожалуйста, обновите, если вы что-то знаете)


person Chris    schedule 17.10.2009    source источник


Ответы (4)


В документации .live() говорится...

.live не поддерживает обратный вызов без событий, который предоставляет liveQuery. Только обработчики событий могут быть привязаны к .live.

Итак, я взглянул на liveQuery и думаю, что он сделает именно то, что вам нужно. как следующее:

$('.myfav').livequery(function() {
  $(this).autocomplete();
  $(this).datepicker();
  $(this).click(somefunction);
});

Кажется удобным!

person No Surprises    schedule 17.10.2009
comment
Выглядит многообещающе. Попробую и вернусь - person Chris; 17.10.2009

Используйте live():

$(".myfav").live("click", somefunction);

Это привяжет этот обработчик событий к элементам, динамически созданным после вызова live().

person cletus    schedule 17.10.2009
comment
Я тоже думал о live, но будет ли он работать с привязкой плагина, такой как $('.myfav').datepicker(); или $('.myfav').autocomplete(); Как должен выглядеть синтаксис в этом случае? $('.myfav').live("click", autocomplete("somefile.php"));? и что, если у меня есть много вариантов, таких как $('.myfav').autocomplete("somefile.php", {max: 15, mustMatch: true}); Любой дополнительный ввод по синтаксису в этом последнем случае в качестве примера? - person Chris; 17.10.2009
comment
live() работает с обработчиками событий, а не с плагинами вроде datepicker(). Для них нет другого выбора, кроме привязки при создании/добавлении элементов в DOM. - person cletus; 17.10.2009

Я думаю, что вы можете использовать live();, но не так, как вы это написали.

Ваша текущая реализация:

$('.myfav').live("click", autocomplete("somefile.php", {max: 15, mustMatch: true}));

Это выполнит автозаполнение немедленно, а не тогда, когда jQuery найдет новый элемент с class="myfav"

Вы должны использовать этот синтаксис:

$('.myfav').live("click", function () {
    $('.myfav').autocomplete("somefile.php", {max: 15, mustMatch: true})
});

Вы можете использовать весь обычный синтаксис, функции и т. д. внутри анонимной функции.

Я думаю, что это сработает, но я не проверял. Что он делает, так это отправляет jQuery функцию для выполнения позже, когда срабатывает событие щелчка.

person Ryan Doherty    schedule 17.10.2009
comment
Я изменил его на $('.myfav').autocomplete(somefile.php, {max: 15, mustMatch: true}) внутри анонимной функции, я думаю, что это была проблема. - person Ryan Doherty; 17.10.2009

В таких случаях я обычно использую функцию инициализации, которая выполняет привязку/отвязку, а затем вызывает ее в ajaxComplete или тому подобное. В этом случае, вероятно, это будет выглядеть так:

function init()
{
    $('.myfav').unbind('click');
    $('.myfav').autocomplete('disable');
    $('.myfav').datepicker('disable');
    $('.myfav').autocomplete();
    $('.myfav').datepicker();
    $('.myfav').click(somefunction);
}

Конечно, в зависимости от плагина отвязка может выглядеть по-разному, я полагаю, что jQueryUI использует, например, $('.myfav').draggable('destroy') .

person Kristoffer Sall-Storgaard    schedule 17.10.2009