Probleme avec menu déroulant

Eléphant du PHP | 351 Messages

19 déc. 2006, 10:53

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 ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

19 déc. 2006, 11:10

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à... :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 351 Messages

19 déc. 2006, 11:39

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

ViPHP
ViPHP | 1961 Messages

19 déc. 2006, 13:15

Bonjour,

Essaie ceci

Code : Tout sélectionner

window.addEventListener('load', sfHover, false);
Deux choses sont infinies, l'Univers et la sottise humaine!!
Mais je ne suis pas sur de ce que j'affirme au sujet de l'Univers.

A. Einstein

Eléphant du PHP | 71 Messages

19 déc. 2006, 16:33

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... :)

Eléphant du PHP | 351 Messages

20 déc. 2006, 13:11

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 ?

ViPHP
ViPHP | 1961 Messages

20 déc. 2006, 13:50

Re,

Je crois que

Code : Tout sélectionner

window.attachEvent
c'est propriètaire IE.

Vérifie tout de même.
Deux choses sont infinies, l'Univers et la sottise humaine!!
Mais je ne suis pas sur de ce que j'affirme au sujet de l'Univers.

A. Einstein

Eléphant du PHP | 71 Messages

20 déc. 2006, 14:29

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:

Eléphant du PHP | 351 Messages

20 déc. 2006, 21:01

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();

Mammouth du PHP | 1885 Messages

20 déc. 2006, 21:14

http://www.dustindiaz.com/top-ten-javascript/

Tu pourrais être intéressé par les 2 premières fonctions.
La programmation est l'expression de la poésie d'un programmeur
Génération PHP

Eléphant du PHP | 71 Messages

21 déc. 2006, 12:13

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: