Событие клика не работает на динамически созданных элементах
Описание проблемы:
Я пытаюсь создать новый элемент с классом 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?