обработчик событий для динамически добавленных элементов
доброго времени суток всем, на jquery есть метод .on() который вешает обрабочик даже на динамически созданные элементы, как это сделать на чистом javascript? копал в сторону addEventListener, но почему-то не срабатывает
var modify = document.querySelectorAll('.modify'); for (var i = 0; i < mod2.length; i++) { mod2[i].addEventListener('click', function() { alert(1); }); } // правильно ли навешал обработчик на элементы с одинаковым классом ? подумал реализовать через так: при добавлении нового элемента удалить обработчик через removeEventListener, потом снова добавить на все, но не знаю правильно ли так сделать, если нет, то как правильнее? если да, то покажите как правильно реализовать это с ремувом, благодарю заранее) |
Цитата:
<html> <head> </head> <body> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <script> var mod2 = document.querySelectorAll('.modify'); for (var i = 0; i < mod2.length; i++) { mod2[i].addEventListener('click', function() { alert(1); }); } </script> </body> </html> И, кстати, при таокм раскладе лучше делать вот так <html> <head> </head> <body> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <div class="modify">div</div> <script> f=function(){alert(1)} var mod2 = document.querySelectorAll('.modify'); for (var i = 0; i < mod2.length; i++) { mod2[i].addEventListener('click', f); } </script> </body> </html> дабы не засирать память бестолку |
Цитата:
|
Цитата:
Цитата:
кстати, за это время попробад сделать вот так для не ещё несозданных элементов: function modify() { alert(1); } function addModEvent() { var mod = document.querySelectorAll('.modify'); for (var i = 0; i < mod.length; i++) { mod[i].addEventListener('click', modify); } } addModEvent(); // для уже сущесвующих function removeModEvent() { var mod = document.querySelectorAll('.modify'); for (var i = 0; i < mod.length; i++) { mod[i].removeEventListener('click', modify); } } // для ещё не созданных parentElem.appendChild(newElem); // ну условно removeModEvent(); addModEvent(); |
Tecvid,
Цитата:
Цитата:
|
рони,
я как раз перед этим вопросом прочитал этот урок) но либо он не подходит для моей задачи, либо я не смог адаптировать его под неё задача такая, есть один контейнер - див, в нём множество одинаковых дивов с одинаковым классом, и каждый из них имеет кнопку (див) с классом modify, без какого либо id или ещё что-то который уникален, то есть мне кажется что по любому надо перебирать в цикле, либо я что-то недопонял |
Tecvid,
подходит именно делегирование под условие вашей задачи. ставите на контейнер клик в клике определяите источник -- если источник имеет класс modify запускаите функцию |
рони,
хм понятно, спасибо большое) |
Tecvid,
для вашей задачи цикл ненужен |
рони,
тогда получается что target нужно вставить внутри handler при addEventListener? function hasClass(elem, cls) { // ... return true; } function modify() { var event = e || window.event; var target = event.target || event.srcElement; if (hasClass(target, 'modify')) { addModEvent(); } } function addModEvent() { parentElem.addEventListener('click', modify); } addModEvent(); так верно будет? |
Tecvid,
проверяйте ... если класс один то можно так if (target.className == 'modify') |
рони,
я не про способ проверки, но не важно) разобрался) спасибо большое, всё теперь работает ка надо :) |
Помогите плиз с помощью ajax добавляю ссылку на открытие модального окна:
//Модальное окно ДОБАВИТЬ $(document).ready(function() { // запускаем скрипт после загрузки всех элементов /* засунем сразу все элементы в переменные, чтобы скрипту не приходилось их каждый раз искать при кликах */ var overlay = $('#overlay'); // подложка, должна быть одна на странице var open_modal = $('.open_add'); // все ссылки, которые будут открывать окна var close = $('.modal_close, #overlay'); // все, что закрывает модальное окно, т.е. крестик и оверлэй-подложка var modal = $('.modal_add'); // все скрытые модальные окна open_modal.click( function(event){ // ловим клик по ссылке с классом open_modal event.preventDefault(); // вырубаем стандартное поведение var div = $(this).attr('href'); // возьмем строку с селектором у кликнутой ссылки overlay.fadeIn(400, //показываем оверлэй function(){ // после окончания показывания оверлэя $(div) // берем строку с селектором и делаем из нее jquery объект .css('display', 'block') .animate({opacity: 1, top: '50%'}, 200); // плавно показываем }); }); close.click( function(){ // ловим клик по крестику или оверлэю modal // все модальные окна .animate({opacity: 0, top: '45%'}, 200, // плавно прячем function(){ // после этого $(this).css('display', 'none'); overlay.fadeOut(400); // прячем подложку } ); }); }); Не открывается до обновления страницы |
Цитата:
$('body').on('click' , '.open_add', function(event){ }) |
Цитата:
Так как в JavaScript только начинаю разбиратся:blink: Дбавляю ссылку ajax: function call() { var msg = $('#Vhod').serialize(); $.ajax({ type: 'POST', url: 'logIn.php', data: msg, success: function(data) { var responseData = jQuery.parseJSON(data); switch(responseData.status){ case 'error': $('#logIn').html(responseData.message) break; case 'success': $('#logIn').html(responseData.message), $('#overlay').trigger('click'), $('#logInHeader').html(responseData.statusLogin); break; } }, error: function(xhr, str){ alert('Возникла ошибка: ' + xhr.responseCode); } }); }; |
andrey3681,
//Модальное окно ДОБАВИТЬ $(function() { // запускаем скрипт после загрузки всех элементов /* засунем сразу все элементы в переменные, чтобы скрипту не приходилось их каждый раз искать при кликах */ var overlay = $('#overlay'); // подложка, должна быть одна на странице $('body').on('click' , '.open_add', function(event){ // ловим клик по ссылке с классом open_modal event.preventDefault(); // вырубаем стандартное поведение var div = $(this).attr('href'); // возьмем строку с селектором у кликнутой ссылки overlay.fadeIn(400, //показываем оверлэй function(){ // после окончания показывания оверлэя $(div) // берем строку с селектором и делаем из нее jquery объект .css('display', 'block') .animate({opacity: 1, top: '50%'}, 200); // плавно показываем }); }); $('body').on('click' , '.modal_close, #overlay', function(){ // ловим клик по крестику или оверлэю $('.modal_add') // все модальные окна .animate({opacity: 0, top: '45%'}, 200, // плавно прячем function(){ // после этого $(this).css('display', 'none'); overlay.fadeOut(400); // прячем подложку } ); }); }); |
рони,
Все по прежнему, не работает:cray: |
рони,
Большущее спасибо! Разобрался, в ссылке изменил class на open_add, и все заработало!!!:dance: Все моя невнимательность:( |
Друзья, помогите пожалуйста разобраться, почему-то не снимается событие.
Проверил - условие выполняется. var items = document.querySelector('.page-content'); var fnCounter = function (e) { var target = e.target; if (target.classList.contains('item-actions__cart')) { items.removeEventListener('click', fnCounter); } }; items.addEventListener('click', {handleEvent: fnCounter, e: event}); |
alecto,
А что такое items ? |
var items = document.querySelector('.page-content');
я вешаю обработчик на родителя, затем ловлю на каком элементе происходит событие. когда событие наступает - нужно снять обработчик. а он не снимается. подозреваю, что проблема в передаче функции через handler в addEventLiustener. |
Dilettante_Pro,
строка 1 и строка 5 ??? |
Dilettante_Pro,
я и не передаю, всего лишь отслеживаю на каком элементе произошло событие, и при всплытии срабатывает обработчик. на этом этапе у меня все работает. проблема только в снятии события. пример выше у меня не работает ни на сайте, ни после перетягивания в редактор :( стурктура элементов в вашем примере была правильная page-content - родитель item-actions__cart - вложенные элементы |
рони, спасибо, я уже заметил.
Не снимается. <div class = 'page-content'>page-content <div >Content</div> <div class = 'item-actions__cart'>Content Cart</div> <div >Content</div> </div> <script> var fnCounter = function (e) { var target = e.target; alert(target.textContent); if (target.classList.contains('item-actions__cart')) { items.removeEventListener('click', fnCounter); } }; var items = document.querySelector('.page-content'); items.addEventListener('click', {handleEvent: fnCounter, e: event}); </script> |
Вот так снимается
<div class = 'page-content'>page-content <div >Content</div> <div class = 'item-actions__cart'>Content Cart</div> <div >Content</div> </div> <script> var fnCounter = function (e) { var target = e.target; alert(target.textContent); if (target.classList.contains('item-actions__cart')) { items.removeEventListener('click', fnCounter); } }; var items = document.querySelector('.page-content'); items.addEventListener('click', fnCounter); </script> Очевидно, EventListener считает, что fnCounter и handleEvent: fnCounter - разные функции |
Dilettante_Pro,
да, у меня тоже самое происходит. событие срабатывает, но снять его не могу. |
alecto,
Пост 25 видели? |
да, теперь увидел.
решение оказалось очень простым. спасибо огромное, ваш сайт просто незаменимый ресурс по JS! |
alecto,
Цитата:
|
Часовой пояс GMT +3, время: 15:15. |