javascript - with - jquery event listener on dynamic element




Ereignisbindung für dynamisch erstellte Elemente? (14)

Ereignisbindung für dynamisch erstellte Elemente

Einzelelement:

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

Kind Element:

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

Beachten Sie das hinzugefügte * . Für alle untergeordneten Elemente dieses Elements wird ein Ereignis ausgelöst.

Ich habe bemerkt, dass:

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

Es funktioniert nicht mehr, aber es hat früher funktioniert. Ich habe jQuery von Google CDN , aber ich weiß nicht, ob sie es geändert haben.

Ich habe ein wenig Code, wo ich alle Auswahlfelder auf einer Seite .hover und ein .hover Ereignis an sie binden .hover , um ein wenig mit ihrer Breite beim Ein- mouse on/off drehen.

Dies geschieht auf Seite bereit und funktioniert gut.

Das Problem, das ich habe, ist, dass irgendwelche Auswahlkästen, die ich über Ajax oder DOM nach der anfänglichen Schleife hinzufüge, die Ereignisgrenze nicht haben wird.

Ich habe dieses Plugin gefunden ( jQuery Live Query Plugin ), aber bevor ich weitere 5k zu meinen Seiten mit einem Plugin hinzufüge, möchte ich sehen, ob jemand einen Weg kennt, dies entweder mit jQuery direkt oder mit einer anderen Option.


Achten Sie auf die "MAIN" -Klasse, in der das Element platziert ist, z. B.

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

Im obigen Szenario ist das MAIN-Objekt, das jQuery beobachten wird, "container".

Dann haben Sie im Grunde Elemente Namen unter Container wie ul , li , und select :

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

Die Logik hinter dieser Sache ist die Anwesenheit des Elements, an das Sie Ihr Ereignis binden müssen. Wenn Sie denken, dass Ihr Element in Zukunft irgendwann oder nach einiger Zeit, nachdem Sie Ihre Website geladen haben, kommen wird, ist es besser, Ereignisdelegierung zu verwenden und diese einfache Codezeile reicht gerade aus.

 $(document).on( 'eventName', '.elementName', function () { ... do your work 
}); 

Hier kann eventName ein beliebiges Ereignis sein wie Klick, Mouseover, Mouselave, Eingabe, Änderung ...


Dies ist eine reine JavaScript- Lösung ohne Bibliotheken oder Plugins:

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

Wo ist hasClass

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

Live-Demo

Der Dank geht an Dave und Sime Vidas

Mit moderneren JS kann hasClass wie hasClass implementiert werden:

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

Eine andere Lösung besteht darin, den Listener beim Erstellen des Elements hinzuzufügen. Anstatt den Zuhörer in den Körper zu setzen, setzen Sie den Zuhörer in das Element in dem Moment, in dem Sie ihn erstellen:

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

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


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

Es gibt eine gute Erklärung in der Dokumentation von on() .

Zusamenfassend:

Event-Handler sind nur an die aktuell ausgewählten Elemente gebunden; Sie müssen zu dem Zeitpunkt auf der Seite vorhanden sein, zu dem der Code den Aufruf von .on() .

Im folgenden Beispiel muss #dataTable tbody tr existieren, bevor der Code generiert wird.

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

Wenn neues HTML in die Seite eingefügt wird, ist es vorzuziehen, delegierte Ereignisse zu verwenden, um einen Ereignishandler anzuhängen, wie als nächstes beschrieben wird.

Delegierte Ereignisse haben den Vorteil, dass sie Ereignisse von untergeordneten Elementen verarbeiten können, die dem Dokument zu einem späteren Zeitpunkt hinzugefügt werden. Wenn die Tabelle beispielsweise vorhanden ist, die Zeilen jedoch dynamisch mithilfe von Code hinzugefügt werden, wird Folgendes behandelt:

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

Zusätzlich zu ihrer Fähigkeit, Ereignisse auf Nachkommenelementen zu behandeln, die noch nicht erstellt wurden, ist ein weiterer Vorteil von delegierten Ereignissen ihr Potenzial für viel geringeren Overhead, wenn viele Elemente überwacht werden müssen. In einer Datentabelle mit 1.000 Zeilen in seinem tbody das erste Codebeispiel einen Handler an 1.000 Elemente an.

Ein Delegated-Events-Ansatz (das zweite Codebeispiel) fügt einen Ereignishandler nur einem Element, dem tbody , tbody , und das Ereignis muss nur um eine Ebene tbody (vom angeklickten tr bis tbody ).

Hinweis: Delegierte Ereignisse funktionieren nicht für SVG .


Jedes p arent, das zum Zeitpunkt der Bindung des Ereignisses existiert, und wenn Ihre Seite dynamisch Elemente mit der Schaltfläche für den Klassennamen erstellt, binden Sie das Ereignis an einen Elternteil, der bereits existiert

$(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>


Sie können Ereignisse zu Objekten hinzufügen, wenn Sie sie erstellen. Wenn Sie mehreren Objekten zu unterschiedlichen Zeiten die gleichen Ereignisse hinzufügen, können Sie eine benannte Funktion erstellen.

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

Sie können die Methode live () verwenden, um Elemente (auch neu erstellte) an Ereignisse und Handler wie das Ereignis onclick zu binden.

Hier ist ein Beispielcode, den ich geschrieben habe, wo Sie sehen können, wie die live () -Methode ausgewählte Elemente, sogar neu erstellte, an Ereignisse bindet:

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

Sie können ein Ereignis an ein Element anhängen, wenn Sie mit jQuery(html, attributes) dynamisch erstellt werden.

Ab jQuery 1.8 kann jede jQuery-Instanzmethode (eine Methode von jQuery.fn ) als eine Eigenschaft des Objekts verwendet werden, das an den zweiten Parameter übergeben wird:

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>


Versuchen Sie, .live() anstelle von .bind() ; Die .live() bindet .hover an das Kontrollkästchen, nachdem die Ajax-Anfrage ausgeführt wurde.


Verwenden Sie die .on() Methode von jQuery on() , um Ereignishandler an das Live-Element anzuhängen.

.live() Version 1.9 wird auch die .live() Methode entfernt.


Flexiblere Lösung zum Erstellen von Elementen und Binden von Ereignissen ( 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);

Hinweis: Dadurch wird für jedes Element eine Event-Handler-Instanz erstellt (kann die Leistung beeinträchtigen, wenn sie in Schleifen verwendet wird).


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




unobtrusive-javascript