javascript - dynamically - jquery event dynamic element




La liaison d'événement sur les éléments créés dynamiquement? (14)

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

J'ai un peu de code où je suis en boucle à travers toutes les boîtes de sélection sur une page et de lier un événement .hover à eux pour faire un peu de twiddling avec leur largeur à la 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 ( jQuery Live Query Plugin ), mais avant d'ajouter 5k à mes pages avec un plugin, je veux voir si quelqu'un sait comment le faire, soit directement avec jQuery, soit par une autre option.


C'est une solution JavaScript pure 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 des JS plus modernes, hasClass peut être implémenté comme:

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

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


Il y a une bonne explication dans la documentation de 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 ne 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.

Les événements délégués ont l'avantage de pouvoir traiter les événements à partir d'éléments descendants qui sont ajoutés au document ultérieurement. 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. Dans une table de données contenant 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 second exemple de code) attache un gestionnaire d'événements à un seul élément, le tbody , et l'événement n'a besoin que d'un niveau supérieur (du tr cliqué au tbody ).

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


La logique derrière cette chose est la présence de l'élément où vous devez lier votre événement. Si vous pensez que votre élément viendra dans un certain temps ou après un certain temps après avoir chargé votre site Web, il est préférable d'utiliser la délégation d'événements et cette simple ligne de code suffit juste.

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

Ici eventName peut être n'importe quel événement comme click, mouseover, mouseleave, entrée, changement ...


Prenez note de la classe "MAIN" l'élément est placé, par exemple,

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

Dans le scénario ci-dessus, l'objet MAIN que jQuery va regarder est "container".

Ensuite, vous aurez essentiellement des noms d'éléments sous le conteneur tels que ul , li , et select :

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

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

Utilisez la méthode .on() de jQuery on() pour attacher des gestionnaires d'événements à l'élément live.

De plus, à partir de la version 1.9, la méthode .live() est supprimée.


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

Vous pouvez joindre un événement à un élément lors de sa création dynamique à l'aide de jQuery(html, attributes) .

Depuis jQuery 1.8 , toute méthode d'instance jQuery (une méthode de jQuery.fn ) peut être utilisée comme propriété de l'objet passé au second paramètre:

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>


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>

tu pourrais utiliser

$('.buttons').on('click', 'button', function(){
    // your magic goes here
});

ou

$('.buttons').delegate('button', 'click', function() {
    // your magic goes here
});

ces deux méthodes sont équivalentes mais ont un ordre différent de paramètres.

voir: Événement de délégué jQuery


Solution plus flexible pour créer des éléments et lier des événements ( 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);

Remarque: Cela créera une instance de gestionnaire d'événements pour chaque élément (peut affecter les performances lorsqu'il est utilisé dans des boucles)


<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