javascript add - Associazione di eventi su elementi creati dinamicamente?




listener to (20)

Associazione di eventi su elementi creati dinamicamente

Singolo elemento:

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

Elemento figlio:

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

Si noti l'aggiunta * . Un evento verrà attivato per tutti i bambini di quell'elemento.

Ho notato che:

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

Non funziona più, ma funzionava prima. Ho usato jQuery da Google CDN , ma non so se l'hanno cambiato.

Ho un po 'di codice dove sto facendo il giro di tutte le caselle di selezione in una pagina e .hover un evento .hover a loro per fare un po' di giocherellando con la loro larghezza sul mouse on/off .

Questo succede a pagina pronta e funziona bene.

Il problema che ho è che ogni casella di selezione che aggiungo tramite Ajax o DOM dopo il ciclo iniziale non avrà l'evento associato.

Ho trovato questo plugin ( jQuery Live Query Plugin ), ma prima di aggiungere un altro 5k alle mie pagine con un plugin, voglio vedere se qualcuno sa come farlo, sia con jQuery direttamente che con un'altra opzione.


Preferisco che i listener di eventi siano distribuiti in una funzione modulare anziché utilizzare un listener di eventi a livello di document . Quindi, mi piace di seguito. Nota, non puoi sottoscrivere un elemento in eccesso con lo stesso listener di eventi, quindi non preoccuparti di collegare un listener più di una volta: solo uno stick.

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
}


Puoi aggiungere eventi agli oggetti quando li crei. Se stai aggiungendo gli stessi eventi a più oggetti in momenti diversi, la creazione di una funzione con nome potrebbe essere la soluzione giusta.

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
$("<select></select>")
    .append( /* Your <option>s */ )
    .hover(mouseOverHandler, mouseOutHandler)
    .appendTo( /* Wherever you need the select box */ )
;

Associare l'evento a un genitore già esistente:

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

Questa è una pura soluzione JavaScript senza librerie o plugin:

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);

dove hasClass è

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

Dimostrazione dal vivo

Il merito va a Dave e Sime Vidas

Usando un JS più moderno, hasClass può essere implementato come:

function hasClass(elem, className) {
    return elem.classList.contains(className);
}

Qualsiasi p arente esistente al momento in cui l'evento è associato e se la tua pagina creava dinamicamente elementi con il pulsante del nome della classe dovresti associare l'evento a un genitore che esiste già

$(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");  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="buttons">
  <input type="button" value="1">
  <button>2</button>
  <input type="text">
  <button>3</button>  
  <input type="button" value="5">  
  </div>
<button>6</button>


Prendi nota della classe "MAIN" in cui è posizionato l'elemento, ad esempio

<div class="container">
     <ul class="select">
         <li> First</li>
         <li>Second</li>
    </ul>
</div>

Nello scenario di cui sopra, l'oggetto principale che jQuery guarderà è "contenitore".

Quindi avrai fondamentalmente nomi di elementi sotto contenitore come ul , li , e select :

$(document).ready(function(e) {
    $('.container').on( 'click',".select", function(e) {
        alert("CLICKED");
    });
 });

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

Ecco perché gli elementi creati dinamicamente non rispondono ai clic:

var body = $("body");
var btns = $("button");
var btnB = $("<button>B</button>");
// `<button>B</button>` is not yet in the document.
// Thus, `$("button")` gives `[<button>A</button>]`.
// Only `<button>A</button>` gets a click listener.
btns.on("click", function () {
  console.log(this);
});
// Too late for `<button>B</button>`...
body.append(btnB);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>

Per ovviare al problema, devi ascoltare tutti i clic e controllare l'elemento di origine:

var body = $("body");
var btnB = $("<button>B</button>");
var btnC = $("<button>C</button>");
// Listen to all clicks and
// check if the source element
// is a `<button></button>`.
body.on("click", function (ev) {
  if ($(ev.target).is("button")) {
    console.log(ev.target);
  }
});
// Now you can add any number
// of `<button></button>`.
body.append(btnB);
body.append(btnC);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>

Questo è chiamato "Event Delegation". Buone notizie, è una funzionalità integrata in jQuery :-)

var i = 11;
var body = $("body");
body.on("click", "button", function () {
  var letter = (i++).toString(36).toUpperCase();
  body.append($("<button>" + letter + "</button>"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>


Usa il metodo .on() di jQuery on() per collegare i gestori di eventi all'elemento live.

Anche a partire dalla versione 1.9 il metodo .live() viene rimosso.


Preferisco usare il selettore e lo applico sul documento.

Questo si lega al documento e sarà applicabile agli elementi che verranno renderizzati dopo il caricamento della pagina.

Per esempio:

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

È possibile utilizzare il metodo live () per associare elementi (anche quelli appena creati) ad eventi e gestori, come l'evento onclick.

Ecco un esempio di codice che ho scritto, in cui puoi vedere come il metodo live () lega gli elementi scelti, anche quelli appena creati, agli eventi:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Untitled Document</title>
    </head>

    <body>
        <script src="http://code.jquery.com/jquery-latest.js"></script>
        <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js"></script>

        <input type="button" id="theButton" value="Click" />
        <script type="text/javascript">
            $(document).ready(function()
                {
                    $('.FOO').live("click", function (){alert("It Works!")});
                    var $dialog = $('<div></div>').html('<div id="container"><input type ="button" id="CUSTOM" value="click"/>This dialog will show every time!</div>').dialog({
                                                                                                         autoOpen: false,
                                                                                                         tite: 'Basic Dialog'
                                                                                                     });
                    $('#theButton').click(function()
                    {
                        $dialog.dialog('open');
                        return('false');
                    });
                    $('#CUSTOM').click(function(){
                        //$('#container').append('<input type="button" value="clickmee" class="FOO" /></br>');
                        var button = document.createElement("input");
                        button.setAttribute('class','FOO');
                        button.setAttribute('type','button');
                        button.setAttribute('value','CLICKMEE');
                        $('#container').append(button);
                    });
                    /* $('#FOO').click(function(){
                                                     alert("It Works!");
                                                 }); */
            });
        </script>
    </body>
</html>

Soluzione più flessibile per creare elementi e associare eventi ( source )

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

//creating a dynamic button
 var $btn = $("<button>", { type: 'button', text: 'Click me', class: 'btn' });

// binding the event
 $btn.click(function () { //for mouseover--> $btn.on('mouseover', function () {
    console.log('clicked');
 });

// append dynamic button to the dynamic container
$div.append($btn);

// add the dynamically created element(s) to a static element
$("#box").append($div);

Nota: questo creerà un'istanza del gestore di eventi per ogni elemento (potrebbe influire sulle prestazioni se utilizzato nei loop)


Potresti semplicemente racchiudere il richiamo dell'evento in una funzione e quindi invocarlo due volte: una volta sul documento pronto e una volta dopo l'evento che aggiunge i nuovi elementi DOM. Se lo fai, eviterai di legare lo stesso evento due volte sugli elementi esistenti, quindi è necessario separare gli eventi esistenti o (meglio) legarli solo agli elementi DOM che sono stati appena creati. Il codice sarebbe simile a questo:

function addCallbacks(eles){
    eles.hover(function(){alert("gotcha!")});
}

$(document).ready(function(){
    addCallbacks($(".myEles"))
});

// ... add elements ...
addCallbacks($(".myNewElements"))

Prova così -

$(document).on( 'click', '.click-activity', function () { ... });

Un'altra soluzione è aggiungere il listener durante la creazione dell'elemento. Invece di mettere l'ascoltatore nel corpo, metti l'ascoltatore nell'elemento nel momento in cui lo crei:

var myElement = $('<button/>', {
    text: 'Go to Google!'
});

myElement.bind( 'click', goToGoogle);
myElement.append('body');


function goToGoogle(event){
    window.location.replace("http://www.google.com");
}

È possibile associare un evento all'elemento quando viene creato dinamicamente utilizzando jQuery(html, attributes) .

A partire da jQuery 1.8 , qualsiasi metodo di istanza jQuery (un metodo di jQuery.fn ) può essere utilizzato come una proprietà dell'oggetto passato al secondo parametro:

function handleDynamicElementEvent(event) {
  console.log(event.type, this.value)
}
// create and attach event to dynamic element
jQuery("<select>", {
    html: $.map(Array(3), function(_, index) {
      return new Option(index, index)
    }),
    on: {
      change: handleDynamicElementEvent
    }
  })
  .appendTo("body");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>


Prova a usare .live() invece di .bind() ; il .live() eseguirà il binding. .hover alla casella di controllo dopo l'esecuzione della richiesta Ajax.


potresti usare

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

o

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

questi due metodi sono equivalenti ma hanno un diverso ordine di parametri.

vedere: Evento Delegato jQuery


div = $("<div>").html("Loading......");
$("body").prepend(div);    




javascript jquery events unobtrusive-javascript