Привязка событий к динамически создаваемым элементам?

У меня есть немного кода, где я перебираю все поля выбора на странице и привязываю к ним событие .hover, чтобы немного изменить их ширину на mouse on/off.

Это происходит на странице готово и работает просто отлично.

У меня проблема в том, что любые поля выбора, которые я добавляю через Ajax или DOM после начального цикла, не будут иметь привязанного события.

Я нашел этот плагин ( jQuery Live Query Plugin ), но прежде чем я добавлю еще 5k на мои страницы с помощью плагина, я хочу посмотреть, если кто-нибудь знает способ сделать это, либо с помощью jQuery напрямую, либо с помощью другого варианта.

вопрос задан 14.10.2008
Eli
56376 репутация

23 ответов


  • 1840 рейтинг

    По состоянию на jQuery 1. 7 , вы должны использовать jQuery.fn.on :

    $(staticAncestors).on(eventName, dynamicChild, function() {});
    

    До этого рекомендуемый подход состоял в том, чтобы использовать live() :

    $(selector).live( eventName, function(){} );
    

    Однако live() устарела в 1. 7 в пользу on(), и полностью удален в 1. 9. Подпись live():

    $(selector).live( eventName, function(){} );
    

    . , , можно заменить на следующую on() подпись:

    $(document).on( eventName, selector, function(){} );
    

    Например, если бы ваша страница динамически создавала элементы с именем класса dosomething, вы бы привязали событие к родительскому объекту, который уже существует (это здесь проблема, вам нужно что-то, что существует для привязки, не ' Привязка к динамическому контенту), это может быть (и самый простой вариант) document. Хотя имейте в виду , document может оказаться не самым эффективным вариантом .

    $(document).on('mouseover mouseout', '.dosomething', function(){
        // what you want to happen when mouseover and mouseout 
        // occurs on elements that match '.dosomething'
    });
    

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

    $('.buttons').on('click', 'button', function(){
        // do something here
    });
    

    будет применяться к

            
    ответ дан dev.e.loper, с репутацией 20502, 30.07.2009
  • 310 рейтинг

    В документации к jQuery.fn.on есть хорошее объяснение.

    Короче:

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

    Таким образом, в следующем примере #dataTable tbody tr должен существовать до генерации кода.

    $("#dataTable tbody tr").on("click", function(event){
        console.log($(this).text());
    });
    

    Если новый HTML-код внедряется в страницу, предпочтительно использовать делегированные события для присоединения обработчика событий, как описано далее.

    Делегированные события имеют то преимущество, что они могут обрабатывать события от элементов-потомков, которые будут добавлены в документ позднее. Например, если таблица существует, но строки добавляются динамически с использованием кода, ее обработают следующие:

    $("#dataTable tbody").on("click", "tr", function(event){
        console.log($(this).text());
    });
    

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

    Подход с делегированными событиями (второй пример кода) присоединяет обработчик событий только к одному элементу, tbody, и событие должно подниматься только на один уровень (от нажатых tr до tbody).

    Примечание: Делегированные события не работают для SVG .

    ответ дан Ronen Rabinovici, с репутацией 4285, 9.08.2013
  • 163 рейтинг

    Это решение на уровне JavaScript без каких-либо библиотек или плагинов:

    document.addEventListener('click', function (e) {
        if (hasClass(e.target, 'bu')) {
            // .bu clicked
            // Do your thing
        } else if (hasClass(e.target, 'test')) {
            // .test clicked
            // Do your other thing
        }
    }, false);
    

    , где hasClass -

    function hasClass(elem, className) {
        return elem.className.split(' ').indexOf(className) > -1;
    }
    

    Live demo

    Кредит идет к Дейву и Симе Видас

    Используя более современный JS, hasClass может быть реализован как:

    function hasClass(elem, className) {
        return elem.classList.contains(className);
    }
    
    ответ дан Ram Patra, с репутацией 9569, 9.12.2014
  • 59 рейтинг

    Вы можете добавлять события к объектам при их создании. Если вы добавляете одни и те же события к нескольким объектам в разное время, создание именованной функции может оказаться подходящим вариантом.

    var mouseOverHandler = function() {
        // Do stuff
    };
    var mouseOutHandler = function () {
        // Do stuff
    };
    
    $(function() {
        // On the document load, apply to existing elements
        $('select').hover(mouseOverHandler, mouseOutHandler);
    });
    
    // This next part would be in the callback from your Ajax call
    $("")
        .append( /* Your 
    ответ дан nickf, с репутацией 362144, 14.10.2008
  • 42 рейтинг

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

    function addCallbacks(eles){
        eles.hover(function(){alert("gotcha!")});
    }
    
    $(document).ready(function(){
        addCallbacks($(".myEles"))
    });
    
    // ... add elements ...
    addCallbacks($(".myNewElements"))
    
    ответ дан Greg Borenstein, с репутацией 1206, 14.10.2008
  • 37 рейтинг

    Попробуйте использовать .live() вместо .bind(); .live() свяжет .hover с вашим флажком после выполнения Ajax-запроса.

    ответ дан user670265, с репутацией 399, 21.03.2011
  • 21 рейтинг

    Вы можете использовать метод live () для привязки элементов (даже недавно созданных) к событиям и обработчикам, таким как событие onclick.

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

    
    
        
    Untitled Document
    
        
    ответ дан Fazi, с репутацией 2714, 21.12.2011
  • 18 рейтинг

    Привязка событий к динамически создаваемым элементам

    Один элемент:

    $(document.body).on('click','.element', function(e) {  });
    

    Детский элемент:

     $(document.body).on('click','.element *', function(e) {  });
    

    Обратите внимание на добавленный *. Событие будет запущено для всех дочерних элементов этого элемента.

    Я заметил, что:

    $(document.body).on('click','.#element_id > element', function(e) {  });
    

    Это больше не работает, но раньше работало. Я использовал jQuery из Google CDN , но я не знаю, изменили ли они его.

    ответ дан MadeInDreams, с репутацией 993, 22.01.2016
  • 16 рейтинг

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

    var myElement = $('', {
        text: 'Go to Google!'
    });
    
    myElement.bind( 'click', goToGoogle);
    myElement.append('body');
    
    
    function goToGoogle(event){
        window.location.replace("http://www.google.com");
    }
    
    ответ дан Martin Da Rosa, с репутацией 342, 7.10.2015
  • 16 рейтинг

    Я предпочитаю использовать селектор и применяю его к документу.

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

    Например:

    $(document).on("click", $(selector), function() {
        // Your code here
    });
    
    ответ дан Vatsal, с репутацией 1012, 21.11.2015
  • 11 рейтинг

    Вы можете прикрепить событие к элементу при динамическом создании, используя jQuery(html, attributes) .

    По состоянию на jQuery 1. 8 , любой метод экземпляра jQuery (метод jQuery.fn) может использоваться как свойство объекта, передаваемого в Второй параметр:

    function handleDynamicElementEvent(event) {
      console.log(event.type, this.value)
    }
    // create and attach event to dynamic element
    jQuery("
    ответ дан guest271314, с репутацией 1, 5.04.2017
  • 11 рейтинг

    Обратите внимание на класс «MAIN», в котором находится элемент, например,

    • First
    • Second
    
    

    В приведенном выше сценарии MAIN-объект, который jQuery будет наблюдать, является «контейнером».

    Тогда у вас будут в основном имена элементов в контейнере, такие как ul, li и select:

    $(document).ready(function(e) {
        $('.container').on( 'click',".select", function(e) {
            alert("CLICKED");
        });
     });
    
    ответ дан Aslan Kaya, с репутацией 359, 26.03.2016
  • 10 рейтинг

    вы могли бы использовать

    $('.buttons').on('click', 'button', function(){
        // your magic goes here
    });
    

    или

    $('.buttons').delegate('button', 'click', function() {
        // your magic goes here
    });
    

    эти два метода эквивалентны, но имеют другой порядок параметров.

    см .: jQuery Delegate Event

    ответ дан Mensur Grišević, с репутацией 329, 11.08.2016
  • 7 рейтинг

    Любой p , который не существует в то время, когда событие связано, и если ваша страница была , динамически создавая элементы с именем класса , кнопка , вы бы связали событие с родительским объектом, который уже существует

    $(document).ready(function(){
      //Particular Parent chield click
      $(".buttons").on("click","button",function(){
        alert("Clicked");
      });  
      
      //Dynamic event bind on button class  
      $(document).on("click",".button",function(){
        alert("Dymamic Clicked");
      });
      $("input").addClass("button");  
    });
    
    
    
     
    
    ответ дан Ankit Kathiriya, с репутацией 957, 18.12.2015
  • 7 рейтинг

    Вот почему динамически созданные элементы не реагируют на клики:

    var body = $("body");
    var btns = $("button");
    var btnB = $("");
    // `` is not yet in the document.
    // Thus, `$("button")` gives `[]`.
    // Only `` gets a click listener.
    btns.on("click", function () {
      console.log(this);
    });
    // Too late for ``...
    body.append(btnB);
    
    
    

    В качестве обходного пути, вы должны прослушать все клики и проверить элемент источника:

    var body = $("body");
    var btnB = $("");
    var btnC = $("");
    // Listen to all clicks and
    // check if the source element
    // is a ``.
    body.on("click", function (ev) {
      if ($(ev.target).is("button")) {
        console.log(ev.target);
      }
    });
    // Now you can add any number
    // of ``.
    body.append(btnB);
    body.append(btnC);
    
    
    

    Это называется «делегирование события». Хорошие новости, это встроенная функция в jQuery :-)

    var i = 11;
    var body = $("body");
    body.on("click", "button", function () {
      var letter = (i++).toString(36).toUpperCase();
      body.append($(""));
    });
    
    
    
    ответ дан leaf, с репутацией 10727, 16.09.2017
  • 5 рейтинг

    Попробуй вот так -

    $(document).on( 'click', '.click-activity', function () { ... });
    
    ответ дан Rohit Suthar, с репутацией 2409, 30.06.2016
  • 3 рейтинг

    Используйте .on() метод jQuery http: // api. JQuery. com / on / , чтобы прикрепить обработчики событий к активному элементу.

    Также с версии 1. 9 .live() метод удален.

    ответ дан Kalpesh Patel, с репутацией 2219, 30.11.2016
  • 1 рейтинг

    Привязать событие к родительскому объекту, который уже существует:

    $(document).on("click", "selector", function() {
        // Your code here
    });
    
    ответ дан truongnm, с репутацией 921, 8.06.2018
  • 1 рейтинг

    Более гибкое решение для создания элементов и событий привязки ( источник )

    // creating a dynamic element (container div)
    var $div = $("
    ", {id: 'myid1', class: 'myclass'}); //creating a dynamic button var $btn = $("

    ответ дан Prasad De Silva, с репутацией 171, 18.04.2017
  • 0 рейтинг

    Я искал решение, чтобы $.bind и $.unbind работали без проблем в динамически добавленных элементах.

    Поскольку on () делает трюк для прикрепления событий, чтобы создать фальшивую отмену привязки к тем, к кому я пришел:

    const sendAction = function(e){ ... }
    // bind the click
    $('body').on('click', 'button.send', sendAction );
    
    // unbind the click
    $('body').on('click', 'button.send', function(){} );
    
    ответ дан Evhz, с репутацией 3274, 18.05.2018
  • 0 рейтинг

    Это делается делегированием события. Событие будет привязано к элементу класса-оболочки, но будет делегировано элементу класса-селектора. Вот как это работает.

    $('.wrapper-class').on("click", '.selector-class', function() {
        // Your code here
    });
    

    Примечание:

    Элемент класса-оболочки может быть чем угодно, например. документ, тело или ваша обертка. Оболочка уже должна существовать.

    ответ дан Must keem, с репутацией 605, 14.06.2018
  • 0 рейтинг

    Я предпочитаю, чтобы прослушиватели событий развертывались модульно, а не в сценариях прослушивателя событий уровня document. Итак, мне нравится ниже. Обратите внимание, что вы не можете переподписать элемент с одним и тем же прослушивателем событий, поэтому не беспокойтесь о подключении прослушивателя более одного раза - только одна палка.

    var iterations = 4;
    var button;
    var body = document.querySelector("body");
    
    for (var i = 0; i < iterations; i++) {
        button = document.createElement("button");
        button.classList.add("my-button");
        button.appendChild(document.createTextNode(i));
        button.addEventListener("click", myButtonWasClicked);
        body.appendChild(button);
    }
    
    function myButtonWasClicked(e) {
        console.log(e.target); //access to this specific button
    }
    ответ дан Ron Royston, с репутацией 5124, 8.06.2018
  • -1 рейтинг
    
        
    HTML Document
    
        
    Hello World
    ответ дан Fakhrul Hasan, с репутацией 44, 27.09.2017