Vraag Gebeurtenisbinding op dynamisch gemaakte elementen?


Ik heb een beetje code waar ik alle selectievakjes op een pagina doorloop en een bind .hover event aan hen om een ​​beetje twiddling doen met hun breedte op mouse on/off.

Dit gebeurt op de pagina klaar en werkt prima.

Het probleem dat ik heb is dat elke selectievak die ik via Ajax of DOM na de initiële lus toevoeg, de gebeurtenis niet zal verbinden.

Ik heb deze plugin gevonden (jQuery Live Query-plug-in), maar voordat ik nog eens 5k aan mijn pagina's toevoeg met een plug-in, wil ik zien of iemand een manier weet om dit te doen, met jQuery rechtstreeks of met een andere optie.


1679
2017-10-14 23:25


oorsprong


antwoorden:


Vanaf jQuery 1.7 je zou ... moeten gebruiken jQuery.fn.on:

$(staticAncestors).on(eventName, dynamicChild, function() {});

Voorafgaand hieraan, de aanbevolen aanpak was om te gebruiken live():

$(selector).live( eventName, function(){} );

Echter, live() werd afgekeurd in 1.7 ten gunste van on(), en volledig verwijderd in 1.9. De live() handtekening:

$(selector).live( eventName, function(){} );

... kan worden vervangen door het volgende on() handtekening:

$(document).on( eventName, selector, function(){} );

Als uw pagina bijvoorbeeld dynamisch elementen met de klassennaam maakt dosomething je zou de gebeurtenis binden aan een ouder die al bestaat (dit is de kern van het probleem hier, je hebt iets nodig om te binden aan, bindt niet aan de dynamische inhoud), dit kan (en de gemakkelijkste optie) is document. Houd echter rekening met document misschien niet de meest efficiënte optie.

$(document).on('mouseover mouseout', '.dosomething', function(){
    // what you want to happen when mouseover and mouseout 
    // occurs on elements that match '.dosomething'
});

Elke ouder die bestaat op het moment dat de gebeurtenis is gebonden, is prima. Bijvoorbeeld

$('.buttons').on('click', 'button', function(){
    // do something here
});

zou van toepassing zijn op

<div class="buttons">
    <!-- <button>s that are generated dynamically and added here -->
</div>

1786
2017-08-09 09:51



Er is een goede uitleg in de documentatie van jQuery.fn.on.

In het kort:

Event-handlers zijn alleen gebonden aan de momenteel geselecteerde elementen; ze moeten op de pagina voorkomen op het moment dat uw code de oproep doet .on().

Dus in het volgende voorbeeld #dataTable tbody tr moet bestaan ​​voordat de code wordt gegenereerd.

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

Als er nieuwe HTML in de pagina wordt geïnjecteerd, heeft het de voorkeur om gedelegeerde gebeurtenissen te gebruiken om een ​​gebeurtenishandler toe te voegen, zoals hierna wordt beschreven.

Gedelegeerde evenementen hebben het voordeel dat ze gebeurtenissen kunnen verwerken van afstammelingen die op een later tijdstip aan het document zijn toegevoegd. Als de tabel bijvoorbeeld bestaat, maar de rijen dynamisch met behulp van code worden toegevoegd, zal het volgende hiermee omgaan:

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

Naast hun vermogen om gebeurtenissen af ​​te handelen op onderliggende elementen die nog niet zijn gemaakt, is een ander voordeel van gedelegeerde gebeurtenissen hun potentieel voor veel lagere overhead wanneer veel elementen moeten worden gecontroleerd. Op een gegevenstabel met 1.000 rijen in zijn tbody, het eerste codevoorbeeld hecht een handler aan 1000 elementen.

Een benadering met gedelegeerde gebeurtenissen (het tweede codevoorbeeld) koppelt een gebeurtenishandler aan slechts één element, de tbodyen de gebeurtenis hoeft maar één niveau omhoog te komen (van het geklikte tr naar tbody).

Notitie: Gedelegeerde evenementen werken niet voor SVG.


301
2017-12-09 07:59



Dit is een pure JavaScript oplossing zonder enige bibliotheken of plug-ins:

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

waar hasClass is

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

Live demonstratie

Krediet gaat naar Dave en Sime Vidas

Gebruik makend van modernere JS, hasClass kan worden geïmplementeerd als:

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

158
2017-10-14 23:31



U kunt gebeurtenissen aan objecten toevoegen wanneer u ze maakt. Als u dezelfde gebeurtenissen op verschillende tijdstippen aan meerdere objecten toevoegt, is het wellicht de beste manier om een ​​benoemde functie te maken.

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

59
2017-10-14 23:35



U kunt uw bindingsoproep eenvoudig in een functie omzetten en het vervolgens twee keer oproepen: eenmaal in document gereed en één keer na uw evenement dat de nieuwe DOM-elementen toevoegt. Als u dat doet, wilt u voorkomen dat twee keer dezelfde gebeurtenis wordt gekoppeld aan de bestaande elementen, zodat u de bestaande gebeurtenissen moet ontbinden of (beter) alleen moet binden aan de DOM-elementen die nieuw zijn gemaakt. De code zou er ongeveer zo uitzien:

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

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

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

40
2018-03-21 22:35



Probeer te gebruiken .live() in plaats van .bind(); de .live() zal binden .hover naar uw selectievakje nadat het Ajax-verzoek is uitgevoerd.


37
2017-12-21 07:26



U kunt de methode liv () gebruiken om elementen (zelfs nieuw gemaakte) aan evenementen en handlers te koppelen, zoals de onclick -gebeurtenis.

Hier is een voorbeeldcode die ik heb geschreven, waar je kunt zien hoe de methode live () bindt aan gekozen elementen, zelfs nieuw gemaakte, aan evenementen:

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

21
2018-01-22 01:06



Gebeurtenisbinding op dynamisch gemaakte elementen

Enkel element:

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

Child Element:

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

Let op de toegevoegde *. Een evenement zal worden geactiveerd voor alle kinderen van dat element.

Ik heb het genoteerd:

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

Het werkt niet meer, maar het werkte eerder. Ik gebruik jQuery van Google CDN, maar ik weet niet of ze het hebben veranderd.


18
2017-10-07 17:43



Een andere oplossing is om de luisteraar toe te voegen bij het maken van het element. In plaats van de luisteraar in het lichaam te plaatsen, plaats je de luisteraar in het element op het moment dat je het aanmaakt:

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

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


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

16
2017-11-21 12:01



Ik gebruik liever de selector en ik pas het toe op het document.

Dit bindt zich aan het document en is van toepassing op de elementen die na het laden van de pagina worden weergegeven.

Bijvoorbeeld:

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

16
2018-04-05 07:11



U kunt gebeurtenissen aan een element koppelen wanneer het dynamisch wordt gemaakt met jQuery(html, attributes).

Vanaf jQuery 1.8, elke jQuery-instantiemethode (een methode van jQuery.fn) kan worden gebruikt als een eigenschap van het object dat wordt doorgegeven aan de   tweede parameter:

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>


11
2018-03-26 02:15