Событие Click не работает с динамически сгенерированными элементами [дубликат]

этот вопрос уже есть ответ здесь:

  • привязка событий к динамически созданным элементам? 23 ответов
<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>

Я пытался создать новый тег с именем класса test на <h2> при нажатии на кнопку. Я также определил событие click, связанное с test. Но событие не работа.

может кто-нибудь помочь?

20 ответов


The click() привязка, которую вы используете, называется" прямой " привязкой, которая будет присоединять обработчик только к элементам, которые уже есть. Он не будет привязан к элементам, созданным в будущем. Для этого вам нужно будет создать "делегированную" привязку с помощью on().

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

источник

вот что вы ищете:

var counter = 0;

$("button").click(function() {
    $("h2").append("<p class='test'>click me " + (++counter) + "</p>")
});

// With on():

$("h2").on("click", "p.test", function(){
    alert($(this).text());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<h2></h2>
<button>generate new element</button>

выше работает для тех, кто использует jQuery версии 1.7+. Если вы используете более старую версию, обратитесь к предыдущему ответу ниже.


Предыдущий Ответ:

попробуйте использовать live():

$("button").click(function(){
    $("h2").html("<p class='test'>click me</p>")
});   


$(".test").live('click', function(){
    alert('you clicked me!');
});

работал для меня. попытался это С jsFiddle.

или есть новый способ сделать это с delegate():

$("h2").delegate("p", "click", function(){
    alert('you clicked me again!');
});

обновленный jsFiddle.


использовать .on() метод с делегированными событиями

$('#staticParent').on('click', '.dynamicElement', function() {
    // Do something on an existent or future .dynamicElement
});

на .on() метод позволяет делегировать любой желаемый обработчик событий:
настоящее элементы или будущее элементы, добавленные в DOM позже.

P. S: Не используйте .live()! Из jQuery 1.7+ the .live() метод устарел.


причина:

в jQuery нажмите () - присоединяет обработчик событий, только если элемент уже существует в html-коде.

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

динамические элементы создаются с помощью javascript или jquery (не в html).

таким образом, событие click не срабатывает.

решение :

чтобы преодолеть это, мы должны использовать on ()


добавить эту функцию в JS файл. Он будет работать на любом браузере

$(function() {
    $(document).on("click", '#mydiv', function() {
        alert("You have just clicked on ");
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='mydiv'>Div</div>

изменить

 $(".test").click(function(){

до

 $(".test").live('click', function(){

LIVE DEMO

jQuery .live()


вам нужно использовать .жить для этого:

$(".test").live("click", function(){
   alert();
});

или если вы используете jquery 1.7 + use .on:

$(".test").on("click", "p", function(){
   alert();
});

попробовать .live() или .delegate()

http://api.jquery.com/live/

http://api.jquery.com/delegate/

код .test элемент был добавлен после .click() метод, поэтому к нему не было прикреплено событие. Live и Delegate дают этот триггер события родительским элементам, которые проверяют своих детей, поэтому все, что добавлено впоследствии, все еще работает. Я думаю, что Live проверит весь документ, в то время как делегат может быть передан элемент, поэтому делегирование более эффективно.

Подробнее:

http://www.alfajango.com/blog/the-difference-between-jquerys-bind-live-and-delegate/


Я нашел два решения в документации jQuery:

во-первых: используйте делегат на теле или документе

например:

 $("body").delegate('.test', 'click', function(){
 ...
  alert('test');
 });

почему?

ответ: прикрепить обработчик к одному или более событий для всех элементов, которые соответствуют селектор, сейчас или в будущем, на основе определенного набора корневых элементов. ссылка:http://api.jquery.com/delegate/

во-вторых: поместите свою функцию в "$( документ )", используя "на" и прикрепите его к элементу, который вы хотите запустить. Первый параметр - это "обработчик событий", Второй-элемент и третий-функция. Например:

 $( document ).on( 'click', '.test', function () {
 ...
  alert('test');
 });

почему?

ответ: обработчики событий привязаны только к выбранным элементам; они должны существовать на странице во время вызова кода .on (). Чтобы убедиться, что элементы присутствуют и могут быть выберите, выполните привязку событий внутри обработчика готовности документа для элементов, которые находятся в разметке HTML на странице. Если на страницу вводится новый HTML, выберите элементы и присоедините обработчики событий после того, как новый HTML будет помещен на страницу. Или используйте делегированные события для присоединения обработчика событий, как описано далее ... ссылка:https://api.jquery.com/on/


лучший способ применить событие к динамически генерируемому контенту с помощью делегирования.

$(document).on("eventname","selector",function(){
    // code goes here
});

Итак, ваш код теперь такой

$(document).on("click",".test",function(){
    // code goes here
});

$(.surrounding_div_class).on( 'click', '.test', function () {
alert( 'WORKS!' );
});

будет работать только если DIV с классом .surrounding_div_class является непосредственным родителем объекта .тест

Если в div есть другой объект, который будет заполнен, он не будет работать.


проблема заключается в том, что вы пытаетесь привязать класс "test" к событию, прежде чем в DOM. Хотя может показаться, что все это динамично, на самом деле происходит JQuery делает пас над DOM и подключает событие click, когда ready() функция уволена, что происходит до того, как вы создали "нажмите меня" в событии кнопки.

добавив событие" test "Click в обработчик щелчка" button", он будет подключите его после того, как правильный элемент существует в DOM.

<script type="text/javascript">
    $(document).ready(function(){                          
        $("button").click(function(){                                  
            $("h2").html("<p class='test'>click me</p>")                          
            $(".test").click(function(){                          
                alert()                          
            });       
        });                                     
    });
</script>

используя live() (как уже упоминалось) - это еще один способ сделать это, но я чувствовал, что это также хорошая идея, чтобы указать на небольшие ошибки в JS коде. То, что вы написали, не было неправильным, его просто нужно было правильно определить. Схватывая, как DOM и JS works - одна из сложных вещей для многих традиционных разработчиков, чтобы обернуть голову.

live() это более чистый способ справиться с этим и в большинстве случаев-это правильный путь. Он по существу наблюдает за DOM и перемонтировать вещи, когда элементы внутри него меняются.


.живая функция работает отлично.

Это для динамически добавляемых элементов на сцену.

$('#selectAllAssetTypes').live('click', function(event){
                    alert("BUTTON CLICKED");
                    $('.assetTypeCheckBox').attr('checked', true);
                });

Ура, Анкит.


Jquery .on работает нормально, но у меня были некоторые проблемы с рендерингом, реализующим некоторые из решений выше. Моя проблема с использованием .on это то, что каким-то образом он отображал события иначе, чем .hover метод.

просто fyi для всех, кто также может иметь проблему. Я решил свою проблему, повторно зарегистрировав событие hover для динамически добавляемого элемента:

перерегистрируйте событие наведения, потому что наведение не работает для динамически созданного предметы. поэтому каждый раз, когда я создаю новый / динамический элемент, я снова добавляю код наведения. работает отлично

$('#someID div:last').hover(
    function() {
       //...
    },
    function() {
       //...
    }
);

Я не мог получить live или делегировать работу над div в лайтбоксе (tinybox).

я использовал функции setTimeout successfullly, по следующим простым способом:

$('#displayContact').click(function() {
    TINY.box.show({html:'<form><textarea id="contactText"></textarea><div id="contactSubmit">Submit</div></form>', close:true});
    setTimeout(setContactClick, 1000);
})

function setContactClick() {
    $('#contactSubmit').click(function() {
        alert($('#contactText').val());
    })
}

также вы можете использовать onclick="do_something(this)"внутри элемента


Альтернативная и более лаконичная альтернатива (IMHO) - использовать необработанную функцию javascript, которая отвечает на событие on click, а затем передать целевой элемент обратно в jQuery, если хотите. Преимущество этого подхода заключается в том, что вы можете динамически добавлять свой элемент в любом месте, а обработчик click будет "просто работать", и вам не нужно беспокоиться о делегировании управления родительским элементам и т. д.

Шаг 1: обновление динамического html для запуска onclick событие. Обязательно передайте объект "event" в качестве аргумента


    $("button").click(function() {
        $("h2").html("<p class='test' onclick='test(event)'> click me </p>")
    });

Шаг 2: создайте тестовую функцию для ответа на событие click


    function test(e){
        alert();
    });

Шаг 3: учитывая, что вы используете jQuery, я предполагаю, что будет полезно получить ссылку на кнопку источника


    function test(e){
        alert();

        // Get a reference to the button
        // An explanation of this line is available here
        var target = (e.target)? e.target : e.srcElement;

        // Pass the button reference to jQuery to do jQuery magic
        var $btn = $(target);

    });


Я работаю с таблицами, динамически добавляя к ним новые элементы, и при использовании on () единственный способ заставить его работать для меня-использовать нединамический родитель как:

<table id="myTable">
    <tr>
        <td></td> // Dynamically created
        <td></td> // Dynamically created
        <td></td> // Dynamically created
    </tr>
</table>

<input id="myButton" type="button" value="Push me!">

<script>
    $('#myButton').click(function() {
        $('#myTable tr').append('<td></td>');
    });

    $('#myTable').on('click', 'td', function() {
        // Your amazing code here!
    });
</script>

Это действительно полезно, потому что, чтобы удалить события связаны с on (), вы можете использовать off(), и использовать события один раз, вы можете использовать one ().


вы можете добавить щелчок к динамически созданным элементам. Пример ниже. Использование Когда, чтобы убедиться, что это сделано. В моем примере я хватаю div с классом expand, добавляя диапазон" click to see more", а затем используя этот диапазон, чтобы скрыть/показать исходный div.

$.when($(".expand").before("<span class='clickActivate'>Click to see more</span>")).then(function(){
    $(".clickActivate").click(function(){
        $(this).next().toggle();
    })
});

если у вас есть динамически добавленная ссылка на какой-либо контейнер или тело:

var newLink= $("<a></a>", {
        "id": "approve-ctrl",
        "href": "#approve",
        "class": "status-ctrl",
        "data-attributes": "DATA"
    }).html("Its ok").appendTo(document.body);

вы можете взять его необработанный элемент javascript и добавить к нему прослушиватель событий, например клик:

newLink.get(0).addEventListener("click", doActionFunction);

независимо от того, сколько раз вы добавляете этот новый экземпляр ссылки, вы можете использовать его, как если бы вы использовали jquery


используйте "on", поскольку щелчок получает привязку к уже присутствующим элементам.

для электронной.г

$('test').on('click',function(){
    alert('Test');
})

Это поможет.