Question La liaison d'événement sur les éléments créés dynamiquement?


J'ai un peu de code où je suis en boucle à travers toutes les cases de sélection sur une page et une liaison .hover événement pour eux de faire un peu de tourner avec leur largeur sur mouse on/off.

Cela arrive à la page prête et fonctionne très bien.

Le problème que j'ai est que toutes les boîtes de sélection que j'ajoute via Ajax ou DOM après la boucle initiale n'auront pas l'événement lié.

J'ai trouvé ce plugin (Plugin de requête Live jQuery), mais avant que j'ajoute un autre 5k à mes pages avec un plugin, je veux voir si n'importe qui sait un moyen de faire ceci, soit avec jQuery directement ou par une autre option.


1679
2017-10-14 23:25


origine


Réponses:


À partir de jQuery 1.7 Tu devrais utiliser jQuery.fn.on:

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

Avant cela, l'approche recommandée était d'utiliser live():

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

cependant, live() a été dépréciée en 1,7 en faveur de on(), et complètement supprimé dans 1.9. le live() Signature:

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

... peut être remplacé par le suivant on() Signature:

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

Par exemple, si votre page créait de façon dynamique des éléments avec le nom de la classe dosomething vous lieriez l'événement à un parent qui existe déjà (c'est le nœud du problème ici, vous avez besoin de quelque chose qui existe pour lier, ne pas lier au contenu dynamique), cela peut être (et l'option la plus facile) est document. Bien que gardez à l'esprit document peut ne pas être l'option la plus efficace.

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

Tout parent qui existe au moment où l'événement est lié est correct. Par exemple

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

s'appliquerait à

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

1786
2017-08-09 09:51



Il y a une bonne explication dans la documentation de jQuery.fn.on.

En bref:

Les gestionnaires d'événements sont liés uniquement aux éléments actuellement sélectionnés. ils doivent exister sur la page au moment où votre code appelle .on().

Ainsi dans l'exemple suivant #dataTable tbody tr doit exister avant que le code soit généré.

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

Si un nouveau code HTML est injecté dans la page, il est préférable d'utiliser des événements délégués pour attacher un gestionnaire d'événements, comme indiqué ci-après.

Événements délégués Avoir l'avantage qu'ils peuvent traiter des événements d'éléments descendants qui sont ajoutés au document plus tard. Par exemple, si la table existe, mais que les lignes sont ajoutées dynamiquement à l'aide de code, les éléments suivants le gèrent:

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

En plus de leur capacité à gérer les événements sur les éléments descendants qui ne sont pas encore créés, un autre avantage des événements délégués est leur potentiel de charge beaucoup plus faible lorsque de nombreux éléments doivent être surveillés. Sur une table de données avec 1 000 lignes dans son tbody, le premier exemple de code attache un gestionnaire à 1 000 éléments.

Une approche d'événements délégués (le deuxième exemple de code) attache un gestionnaire d'événements à un seul élément, le tbody, et l'événement a seulement besoin de monter d'un niveau (à partir du clic tr à tbody).

Remarque: Les événements délégués ne fonctionnent pas pour SVG.


301
2017-12-09 07:59



C'est un JavaScript pur solution sans bibliothèques ni 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);

hasClass est

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

Démonstration en direct

Le crédit va à Dave et Sime Vidas

En utilisant plus JS moderne, hasClass peut être implémenté comme:

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

158
2017-10-14 23:31



Vous pouvez ajouter des événements aux objets lorsque vous les créez. Si vous ajoutez les mêmes événements à plusieurs objets à des moments différents, la création d'une fonction nommée peut être le chemin à parcourir.

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



Vous pouvez simplement envelopper votre appel de liaison d'événement dans une fonction, puis l'appeler deux fois: une fois sur le document prêt et une fois après votre événement qui ajoute les nouveaux éléments DOM. Si vous faites cela, vous voudrez éviter de lier le même événement deux fois sur les éléments existants, vous aurez donc besoin soit de délier les événements existants ou (mieux) de ne lier que les éléments DOM nouvellement créés. Le code ressemblerait à ceci:

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

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

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

40
2018-03-21 22:35



Essayez d'utiliser .live() au lieu de .bind(); la .live() va lier .hover à votre case à cocher après l'exécution de la requête Ajax.


37
2017-12-21 07:26



Vous pouvez utiliser la méthode live () pour lier des éléments (même nouvellement créés) à des événements et des gestionnaires, comme l'événement onclick.

Voici un exemple de code que j'ai écrit, où vous pouvez voir comment la méthode live () lie les éléments choisis, même nouvellement créés, aux événements:

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



Liaison d'événements sur des éléments créés dynamiquement

Élément unique:

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

Élément enfant

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

Notez le ajouté *. Un événement sera déclenché pour tous les enfants de cet élément.

J'ai remarqué que:

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

Ça ne marche plus, mais ça fonctionnait avant. J'utilise jQuery de Google CDN, mais je ne sais pas s'ils l'ont changé.


18
2017-10-07 17:43



Une autre solution consiste à ajouter l'écouteur lors de la création de l'élément. Au lieu de placer l'écouteur dans le corps, vous placez l'écouteur dans l'élément au moment où vous le créez:

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



Je préfère utiliser le sélecteur et je l'applique sur le document.

Cela se lie sur le document et sera applicable aux éléments qui seront rendus après le chargement de la page.

Par exemple:

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

16
2018-04-05 07:11