11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous

Je suis confronté à ce problème sûrement récurrent mais auquel je ne trouve aucune solution...

Pour faire simple : j'ai un élément block (une div par exemple) qui contient un autre élément. Le deuxième élément n'existe pas encore ou est masqué. Sur mon premier élément j'ai un évènement "mouseover" qui déclenche l'apparition du deuxième élément et un évènement "mouseout" qui le masque. Jusque là, rien de bien grandiose.
Le problème qui se pose c'est lorsque je passe la souris sur mon deuxième élément (qui est contenu dans le premier élément, ne l'oublions pas) : l'évènement "mouseout" du premier élément se déclenche ce qui a pour conséquence de masquer le deuxième... et comme ce dernier est masqué il y a à nouveau "mouseover" sur le premier élément... et le deuxième rapparait donc causant "mouseout" sur le premier, ce qui masque le deuxième, etc., etc., indéfiniment ce qui donne, vous l'aurez compris : un clignotement !

Pour schématiser tout ça j'ai le code HTML suivant :

<!-- Element 1, parent de l'élément 2 -->
<div id="element1">
        <!-- Element 2, fils de l'élément 1 et non visible -->
        <div id="element2" style="display:none;"></div>
</div>


Et le code javascript (j'utilise la librairie Prototype !) :

//Evènement "mouseover" sur l'élément 1
Event.observe( $('element1'), 'mousover', function (e) {
        //Affichage de l'élément 2
        $('element2').style.display = '';
});
//Evènement "mouseout" sur l'élément 1
Event.observe( $('element1'), 'mouseout', function (e) {
        //Masquage de l'élément 2
        $('element2').style.display = 'none';
});


Je n'ai pas détaillé le CSS mais les éléments 1 et 2 ont bien évidemment une largeur et une hauteur.

Si quelqu'un a une solution à me proposer ça serait vraiment génial (c'est pour ça que je post) ! Ce n'est pas la première fois que je suis confronté à ce problème et là j'aimerais bien le résoudre une bonne fois pour toute !

Merci de vos réponses Smiley cligne
Oui j'y ai pensé... mais à partir du moment où je n'ai pas un simple "div" comme deuxième élément mais un table avec des tr, des td, du texte, des images... il faudrait appliquer les évènements sur chaque élément. Et ça deviendrait vite super lourd !

C'est un problème que beaucoup de monde a dû rencontrer, il doit bien exister un moyen quand même ? J'espère Smiley decu
a écrit :
à mon avis, le pb viens de Tes css, parce que ça marche !!


En effet, c'est bizarre... je vais essayer de voir ce qui ne cloche pas dans mon code.
Merci de ta réponse Smiley cligne
Ok j'ai trouvé ce qui ne va pas !

En fait je n'ai pas "afficher/masquer" mon élément 2, mais "créer/supprimer"...

En d'autres termes au lieu de faire comme dans l'exemple, j'ai fait comme ça :

//Evènement "mouseover" sur l'élément 1
Event.observe( $('element1'), 'mousover', function (e) {
        //Création de l'élément 2
        var elt = $('element1').insertBefore( document.createElement('div'), null );
        elt.id = "element2";
});

//Evènement "mouseout" sur l'élément 1
Event.observe( $('element1'), 'mouseout', function (e) {
        //Suppression de l'élément 2
        $('element1').removeChild( $('element2') );
});


Et en procédant ainsi, on constate un jolie clignotement (très désagréable...)

C'est tout bête mais je n'y avais jamais pensé Smiley biggol
en effet, c'est pas si simple ainsi ...

Que souhaites tu finalement ? conserver insert() // remove()

Ou tu peux utiliser style.display .. ? au moins pour la fermeture ...

(!$('element2')) ? $('element1').insertBefore( document.createElement('div'), null ) : $('element2').style.display = "block" ;

/* NOTA, en utilisant prototype, il y a aussi Script.aculo.us avec Builder.node() qui te serait très pratique ... */

@+