Javascript добавление элемента события

События для динамически добавленных в 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’)

SergeTkach

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++; >);

Jakim

Ребятки, добавляем такой кусок кода в js и ловим все события как на телефоне так и на ПК, кроссбраузерно кроссплатформенно.
Не ищите других способов, ибо кто пишет про .delegate() или .live() давно не читали доку jQuery.

jQuery работает с элементами, которые были на странице на момент инициализации кода.

Если добавляются новые элементы — при помощи ajax’а или функций типа append() — то события не затрагивают их.

Как же работать с новыми созданными элементами DOM?

Оказывается для динамических элементов используется делегированная обработка событий.

Если кратко, то смысл делегирования в том, что обработчики «навешиваются» не на отсутствующие в dom элементы, а на существующий родительский объект.

Таким образом, при срабатывании соответствующего события, будет вызван данный обработчик для всех элементов, соответствующих селектору, даже если этих элементов не было во время объявлении обработчика (например при загрузке страницы).

Источник

Как отследить появление новых элементов в DOM?

Есть div, в который по нажатию кнопки сторонним плагином добавляются новые элементы DOM (создаётся модальное окно), и после того как оно появилось, нужно сразу же произвести пару действий. Например, заменить значение в текстовом поле и изменить значение атрибута. Проблема в том, как отследить, что это текстовое поле появилось, и как изменить его атрибуты после того как оно появилось?

P.S. Лезть в плагин сторонний нет возможности, так как он обновляется и всё слетит после обновления.

mlnkv

// выбираем нужный элемент 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 добавится другой элемент. Можете поиграть с консолью браузера. Под запрос топикстартера другое и не требуется.

Petroveg

Евгений Петров: У топикстартера просьба сильно проще, чем решение по вашей ссылке.
Также MutationObserver требует IE >= 11, а MutationEvent лишь >= 9 (хоть в вашем решении и есть полифил).

Petroveg

Я повторю то, что написал вам — не рекомендуется использовать Mutation Events, если клиент поддерживает MutationObserver. Если уровень подготовки ТС не слишком высок,это не означает, что ему надо предлагать не самый лучший вариант.

Евгений Петров: основная проблема MutationEvent — это попытка синхронно менять DOM в обработчике всплывающего Mutation события. Да, это может привести к зацикливанию или тормозам. Но топикстартер будет слушать DOMNodeInserted и не будет добавлять новые элементы (по его словам) в обработчике, только менять атрибуты, соответственно, его эта проблема tuj не коснется. А так вы конечно правы, сам я по возможности использую MutationObserver.

Источник

Event при появлении/создании div

Когда я вешаю событие на удаление Modal , оно срабатывает, но не срабатывает при создании элемента. Как повесить событие на создание

, чтобы к нему можно было повесить обработчик с помощью addEventListener ?

@Regent document.getElementById(‘modal1’).addEventListener(‘hide’,function()<. >) работает, а вот document.getElementById(‘modal1’).addEventListener(‘show’,function()<. >) нет. А вешаю перед закрытием

@Regent, ну как бы модалок много может быть. А событие необходимо только для, например, первого. Может быть и modal2 . На закрытии они все работают.

@Regent обработчики добавляются в конце файла, т.е. после всех функций с Modal.prototype . Файл подключен перед закрытием .

А зачем, кстати, вам вообще события show и hide ? А то я подготовил примеры, начал было писать ответ, а потом осознал, что цель этих событий мне не ясна. Что там за код такой, который нельзя просто вызвать в конце функций .prototype.show и prototype.hide ?

1 ответ 1

Первый подход с использованием глобальных (в примере используется document , но можно использовать любого статичного родителя создаваемых -ов. Однако лучше использовать ближайшего такого родителя) обработчиков событий:

document.addEventListener("show", function(event) < if (event.target.id.indexOf('modal') == 0) < console.log(event.target.id + " is shown"); >>); document.addEventListener("hide", function(event) < if (event.target.id.indexOf('modal') == 0) < console.log(event.target.id + " is hidden"); >>); function show(id) < var div = document.createElement('div'); div.id = "modal" + id; document.getElementsByTagName('body')[0].appendChild(div); var event = new Event('show', < "bubbles": true >); div.dispatchEvent(event); > function hide(id) < var div = document.getElementById("modal" + id); var event = new Event('hide', < "bubbles": true >); div.dispatchEvent(event); document.getElementsByTagName('body')[0].removeChild(div); > show(1); setTimeout(function() < show(2); >, 1000); setTimeout(function() < hide(2); >, 2000); setTimeout(function() < hide(1); >, 3000);

При таком подходе важно иметь возможность отфильтровать в обработчиках событий только события для нужных элементов. Также необходимо указывать < "bubbles": true >при создании события для того, чтобы событие «всплыло» до родителя. По той же причине удалять элемент со страницы можно только после вызова события.

Второй подход с использованием глобального обработчика show и обработчика события hide только для конкретного элемента, добавляемого при создании элемента:

document.addEventListener("show", function(event) < if (event.target.id.indexOf('modal') == 0) < console.log(event.target.id + " is shown"); >>); function show(id) < var div = document.createElement('div'); div.id = "modal" + id; document.getElementsByTagName('body')[0].appendChild(div); var event = new Event('show', < "bubbles": true >); div.dispatchEvent(event); div.addEventListener("hide", function() < console.log(div.id + " is hidden"); >); > function hide(id) < var div = document.getElementById("modal" + id); document.getElementsByTagName('body')[0].removeChild(div); var event = new Event('hide'); div.dispatchEvent(event); >show(1); setTimeout(function() < show(2); >, 1000); setTimeout(function() < hide(2); >, 2000); setTimeout(function() < hide(1); >, 3000);

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

function onShown(element) < if (element.id.indexOf('modal') == 0) < console.log(element.id + " is shown"); >>; function onHidden(element) < if (element.id.indexOf('modal') == 0) < console.log(element.id + " is hidden"); >>; function show(id) < var div = document.createElement('div'); div.id = "modal" + id; document.getElementsByTagName('body')[0].appendChild(div); onShown(div); >function hide(id) < var div = document.getElementById("modal" + id); document.getElementsByTagName('body')[0].removeChild(div); onHidden(div); >show(1); setTimeout(function() < show(2); >, 1000); setTimeout(function() < hide(2); >, 2000); setTimeout(function() < hide(1); >, 3000);

Источник

Читайте также:  Joomla весь html код
Оцените статью