it-swarm.com.de

jQuery, wie onclick -Ereignisse an dynamisch hinzugefügte HTML-Elemente gebunden werden

Ich möchte ein onclick-Ereignis an ein Element binden, das ich dynamisch mit jQuery einfüge

Die gebundene Funktion wird jedoch nie ausgeführt. Ich würde mich freuen, wenn Sie herausfinden können, warum dieses Beispiel nicht funktioniert und wie ich es zum Laufen bringen kann:

<!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" xml:lang="da" lang="da">
        <head>
          <title>test of click binding</title>

<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
          <script type="text/javascript">


        jQuery(function(){
          close_link = $('<a class="" href="#">Click here to see an alert</a>');
          close_link.bind("click", function(){
            alert('hello from binded function call');
            //do stuff here...
          });
  
          $('.add_to_this').append(close_link);
        });
          </script>
        </head>
        <body>
          <h1 >Test of click binding</h1>
          <p>problem: to bind a click event to an element I append via JQuery.</p>

          <div class="add_to_this">
            <p>The link is created, then added here below:</p>
          </div>

          <div class="add_to_this">
            <p>Another is added here below:</p>
          </div>


        </body>
        </html>

BEARBEITEN: Ich habe das Beispiel so bearbeitet, dass es zwei Elemente enthält, in die die Methode eingefügt wurde. In diesem Fall wird der alert() -Aufruf niemals ausgeführt. (Danke an @Daff für den Hinweis in einem Kommentar)

122

Das erste Problem besteht darin, dass beim Aufrufen von append für ein jQuery-Set mit mehr als einem Element für jedes Element ein Klon des anzuhängenden Elements erstellt wird und somit der angehängte Ereignisbeobachter verloren geht.

Eine alternative Möglichkeit wäre, den Link für jedes Element zu erstellen:

function handler() { alert('hello'); }
$('.add_to_this').append(function() {
  return $('<a>Click here</a>').click(handler);
})

Ein weiteres mögliches Problem kann darin bestehen, dass der Ereignisbeobachter angehängt wird, bevor das Element dem DOM hinzugefügt wurde. Ich bin nicht sicher, ob dies irgendetwas zu sagen hat, aber ich denke, das Verhalten könnte als unbestimmt angesehen werden. Ein soliderer Ansatz wäre wahrscheinlich:

function handler() { alert('hello'); }
$('.add_to_this').each(function() {
  var link = $('<a>Click here</a>');
  $(this).append(link);
  link.click(handler);
});
59
Tobias

Alle diese Methoden sind veraltet. Sie sollten die Methode on verwenden, um Ihr Problem zu lösen.

Wenn Sie ein dynamisch hinzugefügtes Element als Ziel festlegen möchten, müssen Sie verwenden

$(document).on('click', selector-to-your-element , function() {
     //code here ....
});

dies ersetzt die veraltete .live() Methode.

279
aM1Ne

Wie wäre es mit der Live-Methode?

$('.add_to_this a').live('click', function() {
    alert('hello from binded function call');
});

Dennoch sieht es so aus, als ob das, was Sie getan haben, funktionieren sollte. Es gibt ein weiterer Beitrag der ziemlich ähnlich aussieht.

51
Brother Erryn

Ein bisschen zu spät zur Party, aber ich dachte, ich würde versuchen, einige häufige Missverständnisse in jQuery-Ereignishandlern auszuräumen. Ab jQuery 1.7 sollte .on() anstelle des veralteten .live() verwendet werden, um Ereignishandler an Elemente zu delegieren, die zu einem beliebigen Zeitpunkt nach dem Zuweisen des Ereignishandlers dynamisch erstellt werden.

Das heißt, es ist nicht einfach, live für on zu wechseln, da die Syntax leicht abweicht:

Neue Methode (Beispiel 1):

$(document).on('click', '#someting', function(){

});

Veraltete Methode (Beispiel 2):

$('#something').live(function(){

});

Wie oben gezeigt, gibt es einen Unterschied. Die Drehung ist .on() kann tatsächlich ähnlich wie .live() aufgerufen werden, indem der Selektor an die jQuery-Funktion selbst übergeben wird:

Beispiel 3:

$('#something').on('click', function(){

});

Ohne die Verwendung von $(document) wie in Beispiel 1 funktioniert Beispiel 3 jedoch nicht für dynamisch erstellte Elemente. Das Beispiel 3 ist absolut in Ordnung, wenn Sie die dynamische Delegierung nicht benötigen.

Soll $ (document) .on () für alles verwendet werden?

Es wird funktionieren, aber wenn Sie die dynamische Delegierung nicht benötigen, wäre es angemessener, Beispiel 3 zu verwenden, da Beispiel 1 etwas mehr Arbeit vom Browser erfordert. Es gibt keine wirklichen Auswirkungen auf die Leistung, aber es ist sinnvoll, die für Ihre Verwendung am besten geeignete Methode zu verwenden.

Soll .on () anstelle von .click () verwendet werden, wenn keine dynamische Delegierung erforderlich ist?

Nicht unbedingt. Das Folgende ist nur eine Abkürzung für Beispiel 3:

$('#something').click(function(){

});

Das oben Genannte ist vollkommen gültig und es ist daher eine Frage der persönlichen Präferenz, welche Methode verwendet wird, wenn keine dynamische Delegierung erforderlich ist.

Verweise:

18
MrCode

Bedenken Sie:

jQuery(function(){
  var close_link = $('<a class="" href="#">Click here to see an alert</a>');
      $('.add_to_this').append(close_link);
      $('.add_to_this').children().each(function()
      {
        $(this).click(function() {
            alert('hello from binded function call');
            //do stuff here...
        });
      });
});

Es wird funktionieren, weil Sie es an jedes bestimmte Element anhängen. Aus diesem Grund müssen Sie nach dem Hinzufügen Ihres Links zum DOM eine Möglichkeit finden, Ihr hinzugefügtes Element explizit als JQuery-Element im DOM auszuwählen und das click-Ereignis daran zu binden.

Der beste Weg wird wahrscheinlich - wie vorgeschlagen - sein, es über die Live-Methode an eine bestimmte Klasse zu binden.

1
Daff

Es ist möglich und manchmal erforderlich, das Klickereignis zusammen mit dem Element zu erstellen. Dies ist zum Beispiel der Fall, wenn eine selektorbasierte Bindung nicht möglich ist. Der Schlüssel besteht darin, das Problem zu vermeiden, über das Tobias sprach, indem .replaceWith() für ein einzelnes Element verwendet wird. Beachten Sie, dass dies nur ein Proof of Concept ist.

<script>
    // This simulates the object to handle
    var staticObj = [
        { ID: '1', Name: 'Foo' },
        { ID: '2', Name: 'Foo' },
        { ID: '3', Name: 'Foo' }
    ];
    staticObj[1].children = [
        { ID: 'a', Name: 'Bar' },
        { ID: 'b', Name: 'Bar' },
        { ID: 'c', Name: 'Bar' }
    ];
    staticObj[1].children[1].children = [
        { ID: 'x', Name: 'Baz' },
        { ID: 'y', Name: 'Baz' }
    ];

    // This is the object-to-html-element function handler with recursion
    var handleItem = function( item ) {
        var ul, li = $("<li>" + item.ID + " " + item.Name + "</li>");

        if(typeof item.children !== 'undefined') {
            ul = $("<ul />");
            for (var i = 0; i < item.children.length; i++) {
                ul.append(handleItem(item.children[i]));
            }
            li.append(ul);
        }

        // This click handler actually does work
        li.click(function(e) {
            alert(item.Name);
            e.stopPropagation();
        });
        return li;
    };

    // Wait for the dom instead of an ajax call or whatever
    $(function() {
        var ul = $("<ul />");

        for (var i = 0; i < staticObj.length; i++) {
            ul.append(handleItem(staticObj[i]));
        }

        // Here; this works.
        $('#something').replaceWith(ul);
    });
</script>
<div id="something">Magical ponies ♥</div>
0
Nenotlep
    function load_tpl(selected=""){
        $("#load_tpl").empty();
        for(x in ds_tpl){
            $("#load_tpl").append('<li><a id="'+ds_tpl[x]+'" href="#" >'+ds_tpl[x]+'</a></li>');
        }
        $.each($("#load_tpl a"),function(){
            $(this).on("click",function(e){
                alert(e.target.id);
            });
        });
    }
0
tanthuc

Ich glaube, wie gut es geht:

$('#id').append('<a id="#subid" href="#">...</a>');
$('#subid').click( close_link );
0
yogsototh