javascript - event - jquery on live bind




Associazione di eventi su elementi creati dinamicamente? (16)

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.


È 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>


Associare l'evento a un genitore già esistente:

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

C'è una buona spiegazione nella documentazione di on() .

In breve:

I gestori di eventi sono associati solo agli elementi attualmente selezionati; devono esistere nella pagina nel momento in cui il tuo codice effettua la chiamata a .on() .

Quindi nel seguente esempio #dataTable tbody tr deve esistere prima che il codice venga generato.

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

Se il nuovo codice HTML viene iniettato nella pagina, è preferibile utilizzare gli eventi delegati per collegare un gestore di eventi, come descritto di seguito.

Gli eventi delegati hanno il vantaggio di poter elaborare eventi da elementi discendenti che vengono aggiunti al documento in un secondo momento. Ad esempio, se la tabella esiste, ma le righe vengono aggiunte dinamicamente utilizzando il codice, il seguente lo gestirà:

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

Oltre alla loro capacità di gestire eventi su elementi discendenti che non sono ancora stati creati, un altro vantaggio degli eventi delegati è il loro potenziale per un sovraccarico molto più basso quando molti elementi devono essere monitorati. Su una tabella di dati con 1.000 righe nel suo tbody , il primo esempio di codice allega un gestore a 1.000 elementi.

Un approccio ad eventi delegati (il secondo esempio di codice) allega un gestore di eventi a un solo elemento, il tbody , e l'evento deve solo risalire di un livello (dalla tr clic a tbody ).

Nota: gli eventi delegati non funzionano per SVG .


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

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
}


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

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


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

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>


Questo viene fatto dalla delega degli eventi. L'evento si collegherà all'elemento wrapper-class ma sarà delegato all'elemento selector-class. Ecco come funziona.

const sendAction = function(e){ ... }
// bind the click
$('body').on('click', 'button.send', sendAction );

// unbind the click
$('body').on('click', 'button.send', function(){} );

Nota:

l'elemento wrapper-class può essere qualsiasi cosa ex. documento, corpo o il tuo wrapper. Il wrapper dovrebbe già esistere.


Stavo cercando una soluzione per ottenere $.bind e $.unbind funzionanti senza problemi negli elementi aggiunti dinamicamente.

Come on() rende il trucco per allegare eventi, al fine di creare un falso unbind su quelli che sono venuto a:

<html>
    <head>
        <title>HTML Document</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
    </head>

    <body>
        <div id="hover-id">
            Hello World
        </div>

        <script>
            jQuery(document).ready(function($){
                $(document).on('mouseover', '#hover-id', function(){
                    $(this).css('color','yellowgreen');
                });

                $(document).on('mouseout', '#hover-id', function(){
                    $(this).css('color','black');
                });
            });
        </script>
    </body>
</html>

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.


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


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)


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




unobtrusive-javascript