2012-03-07 2 views
27

Я пытаюсь выполнить некоторые условные манипуляции с элементами, которые динамически добавляются в какой-либо контейнер на странице, но мне не хватает события.jQuery при загрузке динамического элемента

Скажем, у меня есть контейнер:

<div id="container"></div> 

Я могу легко привязать обработчик события к функции мыши для всех новых элементов, используя

$('#container').on('click', '.sub-element', function() { ... }); 

Но что я связываю с тем чтобы получить «одноразовый» крючок, когда элемент добавлен к #container. Я пытался связать с ready и load безрезультатно. Есть ли способ сделать это, или мне нужно придумать другое решение моей проблемы?

This fiddle contains my non-working example.

+1

* Во всех браузерах событие загрузки не пузырится. В Internet Explorer 8 и ниже события вставки и сброса не пузырятся. Такие события не поддерживаются для использования с делегированием, но они могут использоваться, когда обработчик событий напрямую привязан к элементу, генерирующему событие. * (Http://api.jquery.com/on/) Теперь о том, как работайте вокруг этого ... – Corbin

+0

Было бы проблемой удалить функциональность «load», которую вы пытаетесь выполнить вместе, и вместо этого манипулировать html после того, как элемент добавлен «цепочкой»? $ ('# container'). Append ('

No worky!
') .html ('yaay!'); – Ohgodwhy

+0

@ Ohgodwhy это не то, что я не могу придумать обход (и тем более для этого глупого примера), я просто хочу знать, есть ли какое-то событие, которое я пропустил, которое может быть использовано для этой цели. описания. –

ответ

31

Вы можете вызвать пользовательское событие на вновь добавленный элемент DOM, который может быть снимаемого с помощью обработчика событий JQuery:

//bind to our custom event for the `.sub-element` elements 
$('#container').on('custom-update', '.sub-element', function(){ 
    $(this).html('<b>yaay!</b>'); 
}); 

//append a new element to the container, 
//then select it, based on the knowledge that it is the last child of the container element, 
//and then trigger our custom event on the element 
$('#container').append('<div class="sub-element">No worky!</div>').children().last().trigger('custom-update'); 

Вот демо: http://jsfiddle.net/ggHh7/4/

Этот метод позволяет делать что-то глобально, даже если вы загружаете динамический контент с помощью разных методов.

Update

Я не уверен в поддержке браузера (я предполагаю, что IE8 и старше не поддерживаю это), но вы можете использовать событие DOMNodeInserted мутации обнаружить при добавлении DOM элемента:

$('#container').on('DOMNodeInserted', '.sub-element', function(){ 
    $(this).html('<b>yaay!</b>'); 
}) 

$('#container').append('<div class="sub-element">No worky!</div>'); 

Вот демо: http://jsfiddle.net/ggHh7/7/

UPDATE

Существует новый API для Тхи s как DOMNodeInserted амортизируется в настоящее время. Я не смотрел на нее, но это называется MutationOvserver: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

+0

Интересно, +1, и все ... поэтому вы говорите, что я не могу быть уведомлен, когда какой-либо сторонний плагин добавляет элемент в какой-либо контейнер. Если я не тот, кто ее добавляет, я ввернута? –

+3

Вы можете настроить интервал, который так часто проверяет новые элементы DOM. В противном случае существуют события мутации, возможно, что «DOMNodeInserted» - это то, что вы хотите, но поддержка браузера может быть не такой, как вам нужно: https://developer.mozilla.org/en/DOM_Client_Object_Cross-Reference/DOM_Events (посмотрите на мутацию и мутацию name events types '). См. Мое ** обновление ** для примера использования 'DOMNodeInserted'. – Jasper

+0

Вам понадобится использовать такой метод, как Long Polling, для отслеживания элемента для изменения длины, если длина изменится, а затем получить разницу в длине. Это даст вам любой «объект». Это нетрадиционно, но это сработает. – Ohgodwhy

6

После прочтения выше ответа теперь я использую это успешно:

$('body').on({ 
    DOMNodeInserted : function(){ 
     alert('I have been added dynamically'); 
    }, 
    click : function(){ 
     alert('I was clicked'); 
    }, 
    '.dynamicElements' 
}); 

Теперь все мои dynamicElements может делать такие вещи, как они загружены, используя самым awesome .on() карта событий.

Смежные вопросы