11489 sujets

JavaScript, DOM et API Web HTML5

Bonjour,
Je suis actuellement face à un petit problème. Lorsque je mets à jour un contenu dynamiquement via la fonction html() en JQuery, ce même contenu ne réagit plus aux actions jquery...
Exemple:
Soit le bouton "Foo" qui doit faire apparaître une DIV cachée:

En HTML:

<button class="controle_update">Update</button>
<div id="controle">
    <button class="foo_btn">Foo</button>
</div>
<div id="foo_hidden" style="display: none;">
    Hello World
</div>


Au niveau du Javascript:

$(document).ready(function(){
    $(".foo_btn").click(function() {
        $("#foo_hidden").slideToggle("normal");
    });
});
$(".controle_update").click(function() {
    $("#controle").html("<button class='foo_btn'>Foo New Version</button>");
});


Jusque là, tout va bien. Quand je clique sur mon petit bouton Foo, ma div apparaît et disparaît convenablement.
Mais lorsque je clique sur le bouton Update, le bouton Foo devient Foo New Version, sa class ne change pas, mais son action ne fonctionne plus. La div foo_hidden n'apparaît et ne disparaît plus.

Première question: Pourquoi Jquery ne semble plus reconnaitre mon bouton ?
Seconde question: Comment pallier à ce problème ? (Pour le moment, je spécifie une action OnClick sur le bouton foo_btn, mais dans des cas plus compliqués je ne peux malheureusement pas utiliser d'événements, par exemple: le drag&drop sur un tableau fraichement réécris par la fonction html().)

Merci d'avance pour les éventuelles lumières que vous pourrez m'apporter !
Salut.

Il suffit que tu remettes ton "écouteur" du click après que le html ait été changé, en effet ta div avec sa classe n'est pas reconnu par jQuery car celui-ci place ses listeners une première fois lors de la lecture du js mais n'est pas au courant qu'il doit revérifier si de nouveaux foo_btn ont été ajouté ou enlevé lors de l'appelle d'autres fonctions.

En gros, change ton code ainsi :

$(document).ready(function(){
    $(".foo_btn").click(function() {
        $("#foo_hidden").slideToggle("normal");
    });
});

$(".controle_update").click(function() {
    $("#controle").html("<button class='foo_btn'>Foo New Version</button>");
     $(".foo_btn").click(function() {
        $("#foo_hidden").slideToggle("normal");
    });
});


Pas testé mais ça devrait fonctionner. Smiley smile
Merci à toi Skoua,
Effectivement, en replaçant "l'écouteur" cela fonctionne. Par contre, juste une petite correction sur le code que tu m'as donné:

$(document).ready(function(){
    $(".foo_btn").click(function() {
        $("#foo_hidden").slideToggle("normal");
    });

   $(".controle_update").click(function() {
       $("#controle").html("<button class='foo_btn'>Foo New Version</button>");
        $(".foo_btn").click(function() {
           $("#foo_hidden").slideToggle("normal");
         });
   });
});


L'écouteur $(".controle_update").click() doit être dans la fonction $(document).ready() Smiley smile
Le code que tu m'as donné (suite à cette correction) fonctionne.
Merci beaucoup pour cette aide (rapide!).
Mais je ne vais pas m'arrêter là Smiley biggrin
Petite question bonus, si mes écouteurs font 4 pages de codes, vais-je devoir me les "taper" un par un à nouveau à chaque changement de contenu sur ma page ? Ca risque d'être un peu long... Smiley smile Auriez-vous une solution plus "souple", ou peut être existe-t-il une fonction permettant de recharger l'ensemble des listeners js ?
Je m'en vais de ce pas faire mes recherches, mais si vous avez des infos supplémentaires, je suis preneur (et en plus je suis sûr que cela pourrait être utile à d'autres).
Je vais me répondre à moi-même. Je pense avoir trouvé une piste grâce au plugin "LiveQuery" (http://docs.jquery.com/Plugins/livequery). Si j'ai bien compris le principe de ce plugin, il va "binder" différentes actions ce qui permettrait de pouvoir associer des actions à des éléments du DOM qui ne seraient pas encore présents (ajoutés ultérieurement par AJAX par exemple).
A tester.
Salut,

Depuis la version 1.3 de jQuery, liveQuery y est intégré.

Donc si tu utilises jQuery 1.3+ tu peux écrire simplement:

$(function(){
    $(".foo_btn").live('click', function() {
        $("#foo_hidden").slideToggle("normal");
    });
   $(".controle_update").click(function() {
       $("#controle").html("<button class='foo_btn'>Foo New Version</button>");
   });
});


Voici la doc de la fonction live

a+
Merci bien pour l'info, effectivement, je travaillais encore en version 1.2.6 Smiley cligne
Sujet résolu!

Merci à tous.
Modifié par SerialGlandeur (04 Jun 2009 - 15:33)
Ah bah c'est à ça que sert live... Smiley langue

Je n'avais jamais compris la différence entre mettre directement un événement et live, ça m'aura servi de t'aider. Smiley smile