Событие клика не работает на динамически созданных элементах
Описание проблемы:
Я пытаюсь создать новый элемент с классом test внутри тега <h2> при нажатии на кнопку. У меня также есть определенное событие клика, связанное с классом test. Однако событие не срабатывает.
Вот упрощенный код:
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("button").click(function() {
$("h2").html("<p class='test'>click me</p>");
});
$(".test").click(function(){
alert();
});
});
</script>
</head>
<body>
<h2></h2>
<button>generate new element</button>
</body>
</html>
Когда я нажимаю на кнопку, внутри тега <h2> появляется новый элемент <p> с классом test, но клик по этому элементу не вызывает никакого действия. Можете помочь разобраться, почему событие не работает?
5 ответ(ов)
on() может делегировать событие как для текущих, так и для будущих элементов.
Ваш код должен выглядеть следующим образом:
Внутри $(document).ready:
$('.test').on('click', function() {
alert('clicked');
});
Снаружи $(document).ready:
$(document).on('click', '.test', function() {
alert('Clicked');
});
Причина:
В jQuery метод click() выполняет прямое связывание, что означает, что обработчик события прикрепляется к элементу только в том случае, если этот конкретный элемент (HTML-код) существует на странице (после загрузки страницы).
Динамические элементы создаются с помощью JavaScript или jQuery (а не в HTML).
Они не учитывают будущие элементы (динамические), которые создаются после загрузки страницы.
Таким образом, обычное событие click не сработает на динамически добавленном элементе.
Решение:
Для этого мы должны использовать функцию on(). Она может делегировать событие как для текущих, так и для будущих элементов.
Делегированные события имеют преимущество, так как позволяют прикрепить обработчик к элементам, которые будут добавлены в документ в будущем.
Примечание: функции delegate(), live() и on() имеют преимущества по сравнению с элементами DOM. Начиная с jQuery 1.7, функции delegate() и live() устарели (не используйте их).
Таким образом, on() может делегировать событие как для текущих, так и для будущих элементов.
Чтобы добавить указанную функцию в ваш файл JavaScript, выполните следующие шаги. Эта функция будет работать во всех браузерах.
- Убедитесь, что у вас подключена библиотека jQuery. Вы можете использовать следующий тег
scriptдля этого:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
- Затем добавьте следующий код в ваш JavaScript файл или в
<script>теге перед закрывающим тегом</body>:
$(function() {
$(document).on("click", '#mydiv', function() {
alert("Вы только что кликнули на элемент.");
});
});
- Не забудьте добавить элемент
divна вашу веб-страницу, чтобы функция сработала:
<div id='mydiv'>Div</div>
Теперь, когда вы нажмете на div, появится соответствующее сообщение. Этот код будет работать во всех современных браузерах.
Попробуйте методы .live() или .delegate().
Ваш элемент .test был добавлен после вызова метода .click(), поэтому к нему не было прикреплено событие. Методы live и delegate связывают событие с родительскими элементами, которые проверяют своих детей, поэтому все, что добавляется позже, будет работать. Я думаю, что live проверяет весь документ, тогда как delegate можно привязать к конкретному элементу, что делает delegate более эффективным.
Дополнительная информация:
http://www.alfajango.com/blog/the-difference-between-jquerys-bind-live-and-delegate/
Я нашел два решения в документации jQuery:
Первое: используйте метод delegate на body или document.
Например:
$("body").delegate('.test', 'click', function() {
alert('test');
});
Почему? Метод delegate позволяет привязывать обработчик к одному или нескольким событиям для всех элементов, соответствующих селектору, сейчас или в будущем, основываясь на определенном наборе корневых элементов.
Ссылка: http://api.jquery.com/delegate/
Второе: используйте функцию на $(document), используя on, и привязывайте её к элементу, который вы хотите активировать. Первый параметр – это "обработчик события", второй: элемент, и третий: функция.
Например:
$(document).on('click', '.test', function() {
alert('test');
});
Почему? Обработчики событий привязываются только к текущим выбранным элементам; они должны существовать на странице в момент вызова вашего кода с on(). Чтобы гарантировать, что элементы присутствуют и могут быть выбраны, выполняйте привязку событий внутри обработчика document ready для элементов, находящихся в HTML-разметке страницы. Если новый HTML добавляется на страницу, выберите элементы и привяжите к ним обработчики событий после добавления нового HTML. Или используйте делегированные события для привязки обработчика событий, как описано выше...
Ссылка: https://api.jquery.com/on/
Для обработки событий на динамически созданном контенте лучше всего использовать делегирование событий. Это позволяет привязывать обработчики событий к родительскому элементу, который существует в момент привязки, и таким образом реагировать на события, возникающие на дочерних элементах, добавленных в дальнейшем.
Пример кода будет выглядеть следующим образом:
$(document).on("click", ".test", function() {
// Здесь разместите код, который должен выполняться при клике
});
В этом примере обработчик события click привязан к документу. Когда происходит клик по элементу с классом .test, обработчик сработает, даже если этот элемент был добавлен в DOM позже. Таким образом, делегирование событий упрощает работу с динамически изменяемым содержимым.
jQuery событие Keypress: Как узнать, какая клавиша была нажата?
Установить значение по умолчанию в выпадающем списке с помощью jQuery
Прокрутка к элементу с использованием jQuery
Как определить нажатие клавиши Esc?
Как выполнить код после сброса HTML-формы с помощью jQuery?