565 Stimmen

Klick-Ereignis funktioniert nicht bei dynamisch erzeugten Elementen

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

Ich habe versucht, ein neues Tag mit dem Klassennamen test dans le <h2> indem Sie auf die Schaltfläche klicken. Ich habe auch ein Klick-Ereignis definiert, das mit test . Aber das Ereignis funktioniert nicht.

Kann jemand helfen?

4voto

EliuX Punkte 9135

Wenn Sie einen dinamisch hinzugefügten Link zu einem Container oder dem Body haben:

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

können Sie sein rohes Javascript-Element nehmen und ihm einen Ereignis-Listener hinzufügen, wie die anklicken. :

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

Unabhängig davon, wie oft Sie diese neue Link-Instanz hinzufügen, können Sie sie so verwenden, als ob Sie ein jquery click Funktion.

function doActionFunction(e) {
    e.preventDefault();
    e.stopPropagation();

    alert($(this).html());
}

Sie erhalten dann eine Meldung, die besagt

Es ist ok

Es hat eine bessere Leistung als andere Alternativen.

Extra : Sie können eine bessere Leistung erzielen, indem Sie Jquery vermeiden und einfaches Javascript verwenden. Wenn Sie den IE bis zur Version 8 verwenden, sollten Sie dieses Polyfill verwenden, um die Methode addEventListener

if (typeof Element.prototype.addEventListener === 'undefined') {
    Element.prototype.addEventListener = function (e, callback) {
      e = 'on' + e;
      return this.attachEvent(e, callback);
    };
  }

4voto

Nick Mitchell Punkte 1087

Eine alternative und prägnantere Alternative (IMHO) ist die Verwendung einer rohen Javascript-Funktion, die auf ein On-Click-Ereignis reagiert, dann übergeben Sie das Zielelement zurück zu jQuery, wenn Sie möchten. Der Vorteil dieses Ansatzes ist, dass Sie dynamisch Ihr Element überall hinzufügen können, und der Klick-Handler wird "nur Arbeit", und Sie müssen nicht kümmern sich um die Kontrolle zu übergeordneten Elementen delegieren, und so weiter.

Schritt 1: Aktualisieren Sie die dynamische HTML-Datei, um ein Onclick-Ereignis auszulösen. Achten Sie darauf, das Objekt "event" als Argument zu übergeben

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

Schritt 2: Erstellen Sie die Testfunktion, die auf das Klick-Ereignis reagieren soll

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

Optionaler Schritt 3: Da Sie jQuery verwenden, nehme ich an, dass es nützlich sein wird, einen Verweis zurück auf die Quellschaltfläche zu erhalten

    function test(e){
        alert();

        // Get a reference to the button
        // An explanation of this line is available [here](https://stackoverflow.com/questions/7846268/javascript-onclick-event-handler-how-do-i-get-the-reference-to-the-clicked-ite)
        var target = (e.target)? e.target : e.srcElement;

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

    });

4voto

Marc LaFleur Punkte 29814

Das Problem, das Sie haben, besteht darin, dass Sie versuchen, die Klasse "test" an das Ereignis zu binden, bevor es etwas mit einer Klasse "test" in der DOM . Auch wenn es den Anschein hat, dass dies alles dynamisch ist, geschieht in Wirklichkeit Folgendes JQuery macht einen Pass über die DOM und verdrahtet das Klick-Ereignis, wenn die ready() Funktion ausgelöst, bevor Sie das "Click Me"-Ereignis in Ihrer Schaltfläche erstellt haben.

Durch Hinzufügen des "Test"-Klick-Ereignisses zum "Button"-Klick-Handler wird dieser verdrahtet, nachdem das richtige Element in der 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() (wie andere darauf hingewiesen haben) ist eine weitere Möglichkeit, dies zu tun, aber ich fühlte es war auch eine gute Idee, um auf den kleinen Fehler in Ihrem JS-Code. Was Sie geschrieben haben, war nicht falsch, es musste nur richtig skaliert werden. Erfassen, wie die DOM und JS funktioniert, ist für viele traditionelle Entwickler eine der schwierigsten Aufgaben, die sie bewältigen müssen.

live() ist ein sauberer Weg, dies zu handhaben, und in den meisten Fällen der richtige Weg zu gehen. Es ist im Wesentlichen die Beobachtung der DOM und die Dinge neu zu verdrahten, wenn sich die Elemente darin ändern.

3voto

Timbergus Punkte 3077

Ich arbeite mit Tabellen, die neue Elemente dynamisch zu ihnen hinzufügen, und bei Verwendung von on(), die einzige Möglichkeit, es funktioniert für mich ist mit einem nicht-dynamischen übergeordneten als:

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

Dies ist wirklich nützlich, denn um Ereignisse zu entfernen, die mit on() können Sie verwenden aus() und zur einmaligen Verwendung von Ereignissen können Sie ein() .

3voto

Sasha Shepherd Punkte 71

Ich konnte weder Live noch Delegate dazu bringen, auf einem Div in einer Lightbox (tinybox) zu arbeiten.

Ich habe setTimeout erfolgreich verwendet, und zwar auf die folgende einfache Weise:

$('#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());
    })
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X