Присоединение событий к динамически генерируемому HTML? - PullRequest
2 голосов
/ 03 февраля 2012

У меня проблема при преобразовании статической таблицы html в таблицу, сгенерированную JavaScript.Ранее мой обработчик щелчков кода js / jQuery для элементов данных в таблице был следующим:

$(function() {
   $('my_table td').click(function(e) {
   ...handler code
});

Это работает нормально, но мне пришлось изменить свою таблицу, чтобы содержимое динамически генерировалось вJavaScript:

// 'table_contents' is "<table><tbody>...</tbody></table>"
$('#my_table').html(table_contents);

Когда я это делаю, я теряю обработчики кликов.Я полагаю, это не удивительно, так как я просто удаляю старый HTML и заменяю его новым HTML.Тем не менее, я не знаю, как справиться с этим правильно.Могу ли я просто дать моей анонимной функции имя и вызывать ее всякий раз, когда я изменяю html, или мне нужно делать что-то еще, например, явно добавлять прослушиватель событий для каждого нового элемента td?И нужно ли что-нибудь делать для очистки после замены старого html, например, освобождая старый обработчик / слушатель?У js есть утечки памяти / ресурсов, которые я должен исправить вручную?

Спасибо.

РЕДАКТИРОВАТЬ

Извините за глупость, но я не могу получить предложенныйна / делегировать решения для работы.Мой тестовый HTML-код:

<div id="date_test">
<table><tbody><td>42</td></tbody></table>
</div>

Я пытался ответить на нажатие td '42' тремя различными способами:

$("#date_test").on("click", "td", function() {
   alert($(this).text());
});

$('#date_test').delegate('td', 'click', function() {
   alert($(this).text());
});

$(function() {
   $('#date_test td').click(function() {
      alert($(this).text());
   })
})

Из них только третийодин работает.Обратите внимание, что это полностью статический код;Это 3 разных теста.для первых двух случаев код никогда не выполняется;Я могу поставить синтаксическую ошибку вместо предупреждения, и это не имеет значения.Есть идеи, что я делаю не так?Я на jQuery 1.7.Спасибо.

Ответы [ 4 ]

7 голосов
/ 03 февраля 2012

Вы можете использовать метод on, чтобы делегировать обработчик события элементу-предку. Предполагая, что #my_table существует в DOM в момент выполнения следующего кода:

$("#my_table").on("click", "td", function() {
    //Do stuff
});

Метод on доступен только в jQuery 1.7+. Если вы используете более старую версию, вы можете использовать delegate.

Это работает, потому что события DOM всплывают из элемента, на котором они возникли через DOM. События фиксируются на предке, и, если источник соответствует селектору, запускается обработчик событий.

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

Обновление (см. Правку на вопрос)

Причина, по которой ваш третий пример работает, заключается в том, что вы завернули код в обработчик событий ready. $(function() { ... }); является сокращением для $(document).ready(function() { ... });.

Это необходимо, поскольку в противном случае элемент #date_test, с которым вы хотите связать обработчик событий, не будет существовать в DOM. Если вы выполняете какие-либо манипуляции с DOM, всегда помещайте код в готовый обработчик событий.

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

1 голос
/ 03 февраля 2012

У меня недавно была такая же проблема. Оказывается, элементы, которые появляются на странице после загрузки JS, не будут иметь прикрепленных к ним событий. Я решил это очень легко, используя делегирование http://api.jquery.com/delegate/.. Оно распространяет событие через родительские элементы, пока они не будут перехвачены и выполнены. Хитрость заключается в том, чтобы убедиться, что вы делегировали событие элементу, который всегда будет присутствовать при первой загрузке js, поэтому любые новые элементы, добавленные в этот контейнер, будут получать свои события.

$('#container').delegate('#my_table td', 'click' (function(e) {...
0 голосов
/ 03 февраля 2012

Вы можете использовать метод on () http://api.jquery.com/on/

$("#my_table td").on("click", function(event){
    alert($(this).text());
});
0 голосов
/ 03 февраля 2012

В зависимости от используемой вами версии jquery, вы можете попробовать использовать jquery .on ()

http://api.jquery.com/on/

, если вы используете более старые версии, тогда .delegate () будетработа для вас:

http://api.jquery.com/delegate/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...