События для динамически добавленных в DOM элементов?
Есть страница, в js которой вешаются события определенным элементам, примерно следующим образом:
$(document).ready(function() .
$('.clickable-elements a').click(function() //Какое-то действие
>);
.
>);
Далее, в какой-то момент происходит AJAX запрос к серверу, который возвращает HTML-код, который вставляется в DOM примерно так:
.
$('.clickable-elements element').html('HTML с сервера');
.
Соответственно, в нашем HTML-коде могут появиться теги к которым нужно привязать тоже самое событие, что и другим.
Есть ли способ делать это не через OnClick=«my_function()» в HTML который отдает сервер?
Оценить 2 комментария
Если без абстрактных примеров, то вот:
Было:
$('.block').on('click', 'a.left', function() < alert('Click'); >);
После получения AJAX, получаем
То есть сначала никаких элементов вобще не было, потом появились.
Клик не работает
$(‘.clickable-elements element’) — тут в селекторе должен быть элемент, внутри которого появляются новые динамические, в вашем случае $(‘div.outer’)
relic: А как быть с ситуацией, когда после добавления элемента, он должен использовать autocomplete?
По факту надо выбирать категории для вновь добавленных элементов
// Category $('body .select-category').each(function() < $(this).autocomplete(< 'source': function(request, response) < $.ajax(< url: 'index.php?route=catalog/category/autocomplete&token=&filter_name=' + encodeURIComponent(request), dataType: 'json', success: function(json) < var arr = []; arr['category_id'] = 0; arr['name'] = 'Без категории'; json.push(arr); response($.map(json, function(item) < return < label: item['name'], value: item['category_id'] >>)); > >); >, 'select': function(item) < var label = item['label'].split('>'); label = label[label.length - 1]; label = label.trim(); $(this).val(label); // key = $(this).data('category-target'); $('#input-category-name' + $(this).data('category-target') ).val(label); $('#input-category-id' + $(this).data('category-target') ).val(item['value']); > >); >); // rows var specific_formula_row_n = ; //$('.btn-add-block').click(function()< //$('.btn-add-block').on('click', function () < $(document).on('click', '.btn-add-block', function (e) < $.ajax(< url: 'index.php?route=extension/module/seo_tags_generator&token&token=&getSpecificFormulasForJS', dataType: 'html', success: function(html) < html = html.replace(//g, specific_formula_row_n); html = '' + html + "" ; $('#specific-formulas-container').append(html); > >); specific_formula_row_n++; >);
Ребятки, добавляем такой кусок кода в js и ловим все события как на телефоне так и на ПК, кроссбраузерно кроссплатформенно.
Не ищите других способов, ибо кто пишет про .delegate() или .live() давно не читали доку jQuery.
jQuery работает с элементами, которые были на странице на момент инициализации кода.
Если добавляются новые элементы — при помощи ajax’а или функций типа append() — то события не затрагивают их.
Как же работать с новыми созданными элементами DOM?
Оказывается для динамических элементов используется делегированная обработка событий.
Если кратко, то смысл делегирования в том, что обработчики «навешиваются» не на отсутствующие в dom элементы, а на существующий родительский объект.
Таким образом, при срабатывании соответствующего события, будет вызван данный обработчик для всех элементов, соответствующих селектору, даже если этих элементов не было во время объявлении обработчика (например при загрузке страницы).
Как отследить появление новых элементов в DOM?
Есть div, в который по нажатию кнопки сторонним плагином добавляются новые элементы DOM (создаётся модальное окно), и после того как оно появилось, нужно сразу же произвести пару действий. Например, заменить значение в текстовом поле и изменить значение атрибута. Проблема в том, как отследить, что это текстовое поле появилось, и как изменить его атрибуты после того как оно появилось?
P.S. Лезть в плагин сторонний нет возможности, так как он обновляется и всё слетит после обновления.
// выбираем нужный элемент var target = document.querySelector('#some-id'); // если jQuery var target = $('#some-id')[0]; // создаем новый экземпляр наблюдателя var observer = new MutationObserver(function(mutations) < mutations.forEach(function(mutation) < console.log(mutation.type); >); >); // создаем конфигурации для наблюдателя var config = < attributes: true, childList: true, characterData: true >; // запускаем механизм наблюдения observer.observe(target, config); // позже, если надо, прекращаем наблюдение observer.disconnect();
А зачем городить столько нативного кода при наличии Jquery? Тем более просят наблюдать лишь за добавлением нового элемента.
Илья Шатохин: А чем вам тут jQuery поможет? тут обзервер, будет реагировать вообще на все. Вы же листенер навесили.
Сергей Протько: В смысле? В моем примере событие будет услышано только, когда в elem добавится другой элемент. Можете поиграть с консолью браузера. Под запрос топикстартера другое и не требуется.
Евгений Петров: У топикстартера просьба сильно проще, чем решение по вашей ссылке.
Также MutationObserver требует IE >= 11, а MutationEvent лишь >= 9 (хоть в вашем решении и есть полифил).
Я повторю то, что написал вам — не рекомендуется использовать Mutation Events, если клиент поддерживает MutationObserver. Если уровень подготовки ТС не слишком высок,это не означает, что ему надо предлагать не самый лучший вариант.
Евгений Петров: основная проблема MutationEvent — это попытка синхронно менять DOM в обработчике всплывающего Mutation события. Да, это может привести к зацикливанию или тормозам. Но топикстартер будет слушать DOMNodeInserted и не будет добавлять новые элементы (по его словам) в обработчике, только менять атрибуты, соответственно, его эта проблема tuj не коснется. А так вы конечно правы, сам я по возможности использую MutationObserver.
Event при появлении/создании div
Когда я вешаю событие на удаление Modal , оно срабатывает, но не срабатывает при создании элемента. Как повесить событие на создание
@Regent document.getElementById(‘modal1’).addEventListener(‘hide’,function()<. >) работает, а вот document.getElementById(‘modal1’).addEventListener(‘show’,function()<. >) нет. А вешаю перед закрытием
@Regent, ну как бы модалок много может быть. А событие необходимо только для, например, первого. Может быть и modal2 . На закрытии они все работают.
@Regent обработчики добавляются в конце файла, т.е. после всех функций с Modal.prototype . Файл подключен перед закрытием