Это сообщение изначально было опубликовано на webinuse.com
При работе с JavaScript и DOM нам часто приходится динамически создавать некоторые элементы. Особенно при работе с некоторыми таблицами и выборке данных с сервера. Иногда нам приходится привязывать события к динамически создаваемым элементам. И это именно то, что мы собираемся сделать сейчас.
Когда jQuery использовался (он все еще используется сегодня, но не так часто, как раньше), мы просто прикрепляли событие к body
, а затем присоединяли его к элементу. По сути, jQuery найдет для нас этот элемент в дереве DOM и запустит нужную функцию. Давайте посмотрим пример.
$("body").on("click", "dynamic-element", function(){});
В приведенном выше примере jQuery будет прикреплять события к динамически создаваемым элементам или любым элементам, если на то пошло, которые мы передали в качестве параметра.
Привязывайте события к динамически создаваемым элементам с помощью всплывающей подсказки.
Первый способ, который мы собираемся попробовать, — это привязывать события к динамически создаваемым элементам, используя метод всплытия. Что это значит? Это означает, что мы будем нацеливаться на родителя, а не на фактический элемент. А затем мы собираемся проверить, щелкнул ли пользователь по элементу или где-то еще.
<div id="container"> <button class="click-btn">The First Button</button> </div>
<script> /** * First, we select parent element * */ const container = document.querySelector("#container");
/** * After that we add event listener to that element * */ container.addEventListener("click", function(e){ /** * Then, we check if we clicked on an element that has * .click-btn class * */ if (e.target.classList.contains('click-btn')) { /** * If we have clicked on such element we * run some function * */ alert(`You have clicked ${e.target.innerHTML}`); } })
/** * Now let's create our dynamic element * Another button * */ const btn = document.createElement("button"); /** * In order for event bubbling to work, * we have to add the same class as we used * in our eventListener * */ btn.className = "click-btn"; //Then we add some text inside that button btn.innerText = "The dynamically created button"; //And we append it container.appendChild(btn); </script>
Как мы видим в приведенном выше примере, мы добавили eventListener
к родителю, но он будет работать, только если пользователь щелкнет элемент с классом click-btn
.
После того, как мы это сделали, мы динамически создали еще одну кнопку с тем же классом. И по логике вещей, eventListener
будет запускать на этой кнопке ту же функцию, что и на той, которую мы создали в HTML.
Как динамически привязывать события к динамически создаваемым элементам
Второй способ привязки событий к динамически создаваемым элементам — создание функции и запуск этой функции на созданных нами элементах. Звучит запутанно? Давайте создадим несколько примеров.
<div id="container"> <button class="click-btn">The First Button</button> </div>
<script> /** * First let's create a function * */
function dynamicFunction(e) { e.preventDefault(); alert(`You have clicked on ${e.target.innerHTML}`) }
/** * Now let's create our dynamic element * */
//First we select our container const container = document.querySelector("#container");
//Then, we create a button const btn = document.createElement("button"); //Then, we add it the same as their respective siblings btn.className = "click-btn"; //Now, we add it some text btn.innerText = "The dynamically created button"; //Lastly, append it to the container container.appendChild(btn);
/** * Since we are going to attach eventListener to a class * we need a loop * */
//Let's store our elements to variable
const elements = document.querySelectorAll(".click-btn");
//Then, we loop through those elements for(let i = 0; i < elements.length; i++) { //We add eventListener to each element elements[i].addEventListener("click", dynamicFunction); } </script>
Что мы сделали в этом примере, так это то, что вместо того, чтобы установить событие как родительское, мы установили его для точных элементов.
Но есть одна загвоздка. Если бы мы создали нашу кнопку, скажем, после того, как мы сделали .fetch()
, нам нужно было бы снова запустить цикл. Почему? Потому что новые элементы не были частью DOM, когда мы запускаем цикл в первый раз. Так что можно считать это недостатком.
Какой способ лучше?
Они равны, в зависимости от наших предпочтений. Если мы хотим написать функцию один раз, то первый способ лучше. Если мы не против написать один и тот же код несколько раз, то это не беда.
Если у вас есть какие-либо вопросы или что-то еще, вы можете найти меня в моем Твиттере или вы можете прочитать некоторые из моих других статей, таких как Как просто преобразовать любой HTML-шаблон в тему WordPress менее чем за 10 минут?