11548 sujets

JavaScript, DOM et API Web HTML5

Quelle technique utilisez-vous (sinon une technique maison) pour
précharger, voire spécifier un ordre de préchargement de vos fichiers
javascript liés?

On trouve tout et n'importe quoi aujourd'hui en ce qui concerne les
possibilités d'"interfacage" offertes par les librairies js mais
étonnamment, il faut bien chercher pour trouver quelque chose qui en
permette la gestion et en organise le chargement (rien dans la
librairie jquery par exemple). Le webdesigner qui n'est pas en mesure
de composer son propre code va se retrouver avec toute une série de
fichiers importés et au final, un sérieux manque de fluidité à
l'affichage.

Seul résultat de mes recherches, ce script : Preloader XHTML en
Javascript version 2.0.3 (http://www.patrickperron.com/2008/02/13/preloader-xhtml-javascript/) qui comporte toutefois quelques
limitations (incompatibilité avec un css reset).

Mon problème est le suivant : un sous-menu déroulant qui se fige à l'ouverture (chargement?) de la page, puis se résorbe au bout de quelques secondes. Menu qui appelle le superfish.js de la librairie jquery. Un préchargement du js pourrait résoudre ça...
Modifié par pr-brna (26 Nov 2008 - 15:35)
Hello,

Pas sûr de comprendre ce que tu veux exactement... L'exemple que tu donnes est en tout cas à éviter : l'utilisateur doit attendre la fin du chargement de la page et de toutes ses démpendances (images, ...) pour voir quelque chose... Sans parler du fait que le script en lui-même emploie des techniques préhistoriques.

Est-ce que tu aurais un exemple en ligne de ton problème d'origine ? Je pense qu'il faudrait plutôt attaquer par là. Parce que "préchargement du JS" ne me parle pas beaucoup. Smiley smile
pr-brna a écrit :
Mon problème est le suivant : un sous-menu déroulant qui se fige à l'ouverture (chargement?) de la page, puis se résorbe au bout de quelques secondes. Menu qui appelle le superfish.js de la librairie jquery. Un préchargement du js pourrait résoudre ça...

Tu exécutes ta fonction au window.onload, ou tu utilisez l'évènement $(document).ready() proposé par jQuery? Normalement avec le deuxième (le moyen «standard» d'associer des comportements aux éléments d'une page) tu ne devrais pas avoir ce problème.

Pour le «préchargement» de JavaScript: c'est déjà le cas par défaut, un script JS appelé dans le HEAD de la page sera chargé avant les contenus du BODY, il me semble.
a écrit :
Tu exécutes ta fonction au window.onload, ou tu utilisez l'évènement $(document).ready() proposé par jQuery


tu aurais un lien sur un cas pratique stp... que je vois à quoi ressemble le code.

a écrit :
un script JS appelé dans le HEAD de la page sera chargé avant les contenus du BODY


Dans ce cas, pourquoi le menu déroulant se déploie t'il et reste t'il figé un court laps de temps au chargement de la page?

0. le fonctionnement du menu est assuré par le javascript 'superfish.js', librairie jquery

1. paramètre qui pourrait jouer : je charge sous ce menu une anim Flash. En raison d'un bug du player, le menu se déroule "sous"
l'anim (et ce , quelque soit le z-index). J'ai du insérer le swf de façon "traditionelle" :
<script language="javascript">
	if (AC_FL_RunContent == 0) {...

et passer les wmode en transparent afin de corriger. Mais ce bug (menu déroulant qui se fige à l'affichage de la page - serait un meilleur titre pour cette question) pourrait être à nouveau généré par la présence du swf sous le menu... ?

2. Le problème n'apparait que sur ie (7 et 6) mais ça ne ressemble pas à une incompatibilité, ou un problème d'interprétation. Je pense que le moteur d'ie est simplement plus lent que le webkit...

Voici un exemple du code placé dans le head, l'ensemble des fichiers appelés :
<link href="Public/css/global.css" rel="stylesheet" type="text/css" />
    <link href="Public/css/mainnav.css" rel="stylesheet" type="text/css" />
    <link href="Public/css/jquery.jcarousel.css" rel="stylesheet" type="text/css" />
    <link href="Public/css/jcarousel-skin.css" rel="stylesheet" type="text/css" />
    <link href="Public/css/thickbox.css" rel="stylesheet" type="text/css" />
    
    
<!--[if gt IE 6]><!-->
    <link href="Public/css/superfish_vertical.css" rel="stylesheet" type="text/css" />
    <link href="Public/css/tabs-products.css" rel="stylesheet" type="text/css" />
<!--><![endif]--> 
    
<!--[if lte IE 6]>
   <link href="Public/css/ie6.css" rel="stylesheet" type="text/css" />
<![endif]-->
    
<!--[if lt IE 7]>
    <script src="js/IE7.js" type="text/javascript"></script>
<![endif]-->

    <script type="text/javascript" src="AC_RunActiveContent.js"></script>
    
    <script type="text/javascript" src="js/jquery-latest.pack.js"></script>
   <script type="text/javascript" src="js/thickbox.js"></script>
    <script type="text/javascript" src="js/superfish.js"></script>
     <script type="text/javascript">

		// initialise plugins
		jQuery(function(){
			jQuery('ul.sf-menu').superfish();
		});

		</script>
    <script type="text/javascript" src="js/jquery.jcarousel.pack.js"></script>
        <script type="text/javascript">
            jQuery(document).ready(function() {
                jQuery('#mycarousel').jcarousel({
                    start: 5,
                    animation: 1000
                });
            });
        </script>
    
   
<!--[if gt IE 6]><!-->        
    <script type="text/javascript" src="js/jquery.curvycorners.packed.js"></script>
    <script type="text/javascript">
	    $(function(){
			    $('.inner').corner({
			      tl: { radius: 6 },
			      tr: { radius: 6 },
			      bl: { radius: 6 },
			      br: { radius: 6 }});
    			  
	    });
    </script>
    <script type="text/javascript" src="js/ui.core.js"></script>    
    <script type="text/javascript" src="js/ui.tabs.js"></script>
    <script type="text/javascript">
            $(function() {
                $('#rotate > ul').tabs({ fx: { opacity: 'toggle' } }).tabs('rotate', 15000);
            });
    </script>
<!--><![endif]--> 


le superfish.js est appelé en 3ème position, après l'appel de la librairie et celui d'un 2ème fichier.
a écrit :
Pour le «préchargement» de JavaScript: c'est déjà le cas par défaut


Est-il possible de n'afficher la page qu'APRES le chargement de certains fichiers appelés dans le head?

A moins que ce problème de latence soit dû à autre chose...
pr-brna a écrit :
Tu exécutes ta fonction au window.onload, ou tu utilisez l'évènement $(document).ready() proposé par jQuery

tu aurais un lien sur un cas pratique stp... que je vois à quoi ressemble le code.
En fait, tu utilises déjà cette technique quand tu écris "jQuery(function(){ ... });".
pr-brna a écrit :
Est-il possible de n'afficher la page qu'APRES le chargement de certains fichiers appelés dans le head?

Comme le disait Florent, c'est le cas par défaut : quand le parseur du navigateur rencontre un élément script, il se bloque jusqu'à ce que le script ait été chargé et exécuté. Ton problème est que l'appel "jQuery('ul.sf-menu').superfish();" est effectué au chargement de la page, puisque tu utilises la technique évoquée ci-dessus (ready).

Solutions possibles :
- Faire en sorte que ta page soit moins lourde, parce que ça a l'air d'être assez monstrueux... Mais bon ça c'est facile à dire. Smiley smile
- Faire l'appel au plugin superfish juste après le parsing de l'élement correspondant au menu. En clair, remplacer
<script type="text/javascript">
  jQuery(function(){
    jQuery('ul.sf-menu').superfish();
  });
</script>

dans ton head par
<script type="text/javascript">
  jQuery('ul.sf-menu').superfish();
</script>

juste après l'élement <ul class="sf-menu">...</ul>
ok... la réponse (apportée sur un autre forum... je titre mal mon message, me fait les questions et les réponses, fait de la pub pour les concurrents... p* c'est n'importe quoi...) :

le js étant appelé après le css, et le display:none appliqué sur le sous-menu déroulant étant généré dans le js, le sous-menu s'affichait donc avant que le js soit chargé. Rajouter un display-none dans le css résoud le problème.
a écrit :
Faire en sorte que ta page soit moins lourde, parce que ça a l'air d'être assez monstrueux... Mais bon ça c'est facile à dire.


La home est costaud oui... mais il faut bien se plier à la demande, elle-même influencée par ce qui se passe chez le voisin (slider, flash, caroussel, etc...)... novice en js, je n'ai su que... me limiter à l'import d'une seule librairie.

Je continue à chercher une solution pour accélérer le chargement du javascript et tombe sur cet article :
Javascript non bloquant où est évoqué l'insertion du javascript via une requête XMLHttpRequest. Si quelqu'un possède un lien détaillant la manip, je suis preneur...
Modérateur
Salut, Smiley smile

pr-brna a écrit :
Rajouter un display-none dans le css résoud le problème.
Ca rend surtout ta navigation impraticable dès lors que l'utilisateur ne dispose pas de JS. Smiley cligne Ce que te proposait Julien est bien meilleur.

Aussi, ce qui compte, c'est avant tout que l'utilisateur ait un feedback pour qu'il comprenne que la page se charge plutôt que d'essayer de charger le js plus vite.

La solution d'insérer tes scripts via XMLHttpRequest est, elle aussi, mauvaise vu qu'on peut parfaitement disposer de js sans avoir accès à XMLHttpRequest.

Pour améliorer l'aspect graphique (en évitant le "clipping"), il suffit de placer, juste après l'ouverture de la balise body :
a écrit :
document.body.className += ' hasJS';
puis de définir les styles de base en appliquant, par exemple :
a écrit :
.hasJS .hidden {display:none;}
et, pour optimiser le chargement de la partie js, tu peux faire un fichier js unique qui insère des balises scripts appelant chacun des fichiers js nécessaires.

Après, dans un soucis d'accessibilité, tu peux encore améliorer ce système en testant, avant d'ajouter le document.body.className, que tu disposes bien de css et des images (car, du fait que tu te sers d'un menu déroulant, des zones de contenus se superposent et il serait nécessaire de prévoir un fond en image sur la partie supérieure afin que les écritures restent lisibles même en cas de désactivation des couleurs sur IE5, Fx2, etc...)
Modifié par koala64 (27 Nov 2008 - 12:16)
a écrit :
Ce que te proposait Julien est bien meilleur


adopté... si j'ai bien saisi, la fonction 'ready' fonctionne sur ce principe : dès que le DOM est prêt, j'exécute la fonction (en gros, la fonction exécutée l'est juste avant la lecture de la balise body). Du coup, placer l'initialisation du script après le bloc permet de laisser s'afficher les 1ers éléments de la page avant que la balise script ne bloque à nouveau l'affichage...

...pour ce qui est du :
a écrit :
document.body.className += ' hasJS';
et du test à effectuer avant, il me manque les bases du js pour bien l'appréhender, et l'exécuter en connaissance de cause. Je me met au js là (tout premier site sur lequel je l'utilise, je suis un p* de graphiste Smiley bawling ), et si vous avez un lien sur un tuto particulier, bien fait, qui aborde ce "chapitre-là du javascript, c'est volontiers...

Merci!