Page 1 sur 1

Probleme avec menu déroulant

Posté : 19 déc. 2006, 10:53
par bins007
Bonjour,

J'ai créer mon menu déroulant en m'aidant de ce site : http://www.htmldog.com/articles/suckerfish/dropdowns/

Voici la fonction javascript pour le faire fonctionner :

Code : Tout sélectionner

<script type="text/javascript"><!--//--><![CDATA[//><!-- sfHover = function() { var sfEls = document.getElementById("nav").getElementsByTagName("LI"); for (var i=0; i<sfEls.length; i++) { sfEls[i].onmouseover=function() { this.className+=" sfhover"; } sfEls[i].onmouseout=function() { this.className=this.className.replace(new RegExp(" sfhover\\b"), ""); } } } if (window.attachEvent) window.attachEvent("onload", sfHover); //--> </script>
Le problème c'est qu'avec IE, il faut faire

Code : Tout sélectionner

window.attachEvent("onload", sfHover);
Et donc le menu déroulant ne fonctionne qu'après le chargement complet de la page, ma page étant tres grosse avec beaucoup d'images : l'utilisateur doit attendre trop longtemps avant de pouvoir changer de page !

Comment faire pour que le menu déroulant fonctionne même avant le chargement complet de la page ?

Posté : 19 déc. 2006, 11:10
par Ryle
As-tu essayé d'appeller la fonction pendant le chargement de la page, directement dans un <script></script> au lieu de le faire sur le onLoad ?

Fais attention à ce que tous les éléments nécessaires au menu aient déjà été chargés à ce moment là... :)

Posté : 19 déc. 2006, 11:39
par bins007
C'est à dire ?

J'ai essayé ça mais ça marche pas :

Code : Tout sélectionner

sfHover = function() { var sfEls = document.getElementById("nav").getElementsByTagName("LI"); for (var i=0; i<sfEls.length; i++) { sfEls[i].onmouseover=function() { this.className+=" sfhover"; } sfEls[i].onmouseout=function() { this.className=this.className.replace(new RegExp(" sfhover\\b"), ""); } } } sfHover();
A noter que avec firefox ça marche très bien sans attendre la fin du chargement

Posté : 19 déc. 2006, 13:15
par Ajoloca
Bonjour,

Essaie ceci

Code : Tout sélectionner

window.addEventListener('load', sfHover, false);

Posté : 19 déc. 2006, 16:33
par Chakra Spirit
Salut,

oui, en effet, le fait d'ajouter addEventListener va permettre de mettre tout le monde au même niveau c'est à dire : chargement lent pour tous ! :lol:

En revanche, celà va permettre de mettre le script en externe, ce qui sémantiquement parlant sera un plus...

Lorsque je n'ai pas de besoins particuliers en terme de vitesse, j'ai recours à cette fonction :

Code : Tout sélectionner

var fnConnect = function(oElem, sEvType, fn, bCapture) { return oElem.addEventListener ? oElem.addEventListener(sEvType, fn, bCapture): oElem.attachEvent ? oElem.attachEvent('on' + sEvType, fn): oElem['on' + sEvType] = fn; };
qui prend aussi en compte les navigateurs plus anciens...

Si, par contre, j'ai besoin d'un script plus rapide, je sors l'artillerie lourde à savoir cette méthode...
Je la complète par ce petit bout de script afin de la rendre compatible IE5 :

Code : Tout sélectionner

var Array_push = function() { var A_p = 0; for (A_p = 0; A_p < arguments.length; A_p++) { this[this.length] = arguments[A_p]; } return this.length; } if(typeof Array.prototype.push == "undefined") { Array.prototype.push = Array_push; }
Si tu veux un exemple, je m'en suis servi sur ce menu. Une image lourde apparaît mais le menu est déjà opérationnel.

Juste une chose... Avant même de penser à employer ce type de méthode, il est bon d'optimiser ses pages... Dans la plupart des cas, ça suffit... Rien ne sert de se servir de méthodes de compet' si c'est pour faire n'importe quoi derrière... Enfin, c'est ce que j'en dit... :wink:

Un dernier petit truc, tu peux remplacer :

Code : Tout sélectionner

<!--//--><![CDATA[//><!-- ... //-->
où tu as oublié de fermer le CDATA par :

Code : Tout sélectionner

//<![CDATA[ ... //]]>
lorsque tes scripts sont intrusifs...

En espérant que ça t'aide... :)

Posté : 20 déc. 2006, 13:11
par bins007
merci, j'ai trouvé pour le moment une autre solution en m'aidant de la réponse de Ryle :

J'ai mis ça dans <head> :

Code : Tout sélectionner

sfHover = function() { var sfEls = document.getElementById("nav").getElementsByTagName("LI"); for (var i=0; i<sfEls.length; i++) { sfEls[i].onmouseover=function() { this.className+=" sfhover"; } sfEls[i].onmouseout=function() { this.className=this.className.replace(new RegExp(" sfhover\\b"), ""); } } }
et à la fin de la page :

Code : Tout sélectionner

<script type="text/javascript if (window.attachEvent) sfHover(); </script>
C'est marche correctement, est ce que ça pourrait poser probleme de laisser comme ça ?

Posté : 20 déc. 2006, 13:50
par Ajoloca
Re,

Je crois que

Code : Tout sélectionner

window.attachEvent
c'est propriètaire IE.

Vérifie tout de même.

Posté : 20 déc. 2006, 14:29
par Chakra Spirit
Je crois que

Code : Tout sélectionner

window.attachEvent
c'est propriètaire IE.
Oui, tout à fait... ce pourquoi, il serait préférable de reprendre la fonction fnConnect. :wink:

Posté : 20 déc. 2006, 21:01
par bins007
Oui justement le if (window.attachEvent) sert à vérifier si c'est IE en fait !

Car en mettant sfHover() sur firefox par exemple, le menu ne marche plus très bien !

En fait firefox n'a pas besoin de déclarer sfHover() alors que IE oui !

Donc c'est pour ça que j'ai mis :
if (window.attachEvent) sfHover();

Posté : 20 déc. 2006, 21:14
par Xenon_54
http://www.dustindiaz.com/top-ten-javascript/

Tu pourrais être intéressé par les 2 premières fonctions.

Posté : 21 déc. 2006, 12:13
par Chakra Spirit
Salut,

Je vais peut-être me faire un peu lourd mais la seconde fonction est susceptible de générer des problèmes en cas d'ajout de nouveaux scripts car il se sert d'onload. Il faut alors modifier les méthodes de lancement de chacun des scripts pour que tous utilisent la même. Si par hasard, on se trouve dans une optique de diffusion, ce n'est pas adapté.

La première fonction est meilleure et la fonction fnConnect que je proposais plus haut est identique, à un détail près, elle ne génère pas d'avertissement...
Elle fonctionne sur tous les navigateurs; j'en touche quelques mots sur ce tuto si vous souhaitez avoir un peu plus d'explications. Sur ce, je n'insiste pas plus...

Bonne journée. :wink: