Sens-Interdit.fr

Tech Débloquer l'utilisation de l'event "onload" en Javascript

vendredi 30 juin 2006 à 09:05 (Julien Tartarin)

11 commentaires

L'event onload est très pratique pour initialiser des scripts Javascript, mais il a une limite : il attend que tout le contenu de la page soit chargé pour s'exécuter.

Dans certains cas, ça n'a aucune importance, surtout qu'avec l'ADSL, les délais de chargement des pages diminuent tout le temps. Mais les publicités sont souvent plus lentes à charger que les pages normales (les adservers sont toujours surchargés, c'est bien connu !), ce qui peut entraîner des dysfonctionnements.

Exemple typique de ce matin : une image de la page se trouve sur un serveur distant surchargé, au bout de 10, 20 ou même 30 secondes, elle n'est toujours pas chargée. La fonction attachée au onload n'est donc toujours pas exécutée au bout de cet intervalle de temps. L'utilisateur, de son côté, a déjà remarqué que certaines fonctionnalités (liées à cet event) sont cassées.

On va donc oublier le onload, et passer à une solution qui marche même si la page n'est pas chargée entièrement !

Le pitch, c'est de faire une fonction qui sera appelée dès son chargement pour lancer les procédures d'initialisation. Evidemment, puisqu'elle est appelée avant le chargement de la page, certaines choses risquent de ne pas fonctionner.

Pour résoudre ce problème, on va mettre une condition sur l'existence des éléments requis, et si celle-ci n'est pas remplie, on bouclera sur la fonction d'initialisation en boucle.

Le bout de code qui peut ne pas marcher :

window.onload = initialiserTout;

Il faut le remplacer par le code suivant (qui peut être mis un peu n'importe où : head, body ou script externe) :

function trytoload() {
   if(typeof initialiserTout== "function" && document.getElementById('elt')) {
       initialiserTout();
   } else {
       setTimeout("trytoload();", 100);
   }
}
trytoload();

Traduction: si initialiserTout est bien une fonction, ça voudra dire qu'elle est chargée. Et puisqu'elle joue avec l'élément HTML identifié elt, il faut que celui-ci soit chargé aussi. Si ces deux conditions sont réunies, la fonction sera appelée avec succès (il ne faut évidemment pas oublier un élément requis, au risque que plus rien ne fonctionne).

Et puis sinon, la tentative sera relancée tous les dixièmes de seconde...

Voilà donc pourquoi le Drag 'n Drop de Lexode v8 pourra fonctionner même en cas de panne des serveurs de pub (ou tout simplement pour les connexions bas débit) !

Commentaires

#1 Le jeudi 6 juillet 2006 à 01:07, par Neovov

A l'inverse si on veut exécuter une fonction une fois la page complètement chargée :
blog.neovov.com/index.php...

Pratique dans le cas d'une utilisation d'Ajax ou toute manipulation de DOM...

#2 Le jeudi 6 juillet 2006 à 05:38, par Julien Tartarin

Dans notre cas, le HTML doit bien être chargé en entier, mais le lancement ne doit pas attendre que la dernière pub soit affichée, on peut donc manipuler le DOM et faire des appels Ajax sans aucun problème.

D'ailleurs on a un peu modifié le bout de code, en mettant en condition l'existence du dernier élément HTML de nos pages (id "footer"), puisque dans le cas précédent, la condition retournait true même si tout le contenu de l'élément n'était pas chargé.

#3 Le jeudi 20 juillet 2006 à 14:44, par iTom

Je ne sais pas si la fonction setTimeout Javascript fonctionne comme celle d'ActionScript, mais si c'est le cas il y a un petit souci dans le code. En imaginant que le test soit faux, setTimeout lance la fonction toutes les dixièmes de secondes, seulement si lors de l'appel suivant le test est toujours faux, la fonction va lancer un second setTimeout, et ainsi de suite... et donc de la consommation de la mémoire inutile, bie que la fonction ne fasse pas grand chose, cependant cela peut entrainer un plantage du navigateur, d'ou l'interet de placer un destructeur du setTimeout (si c'est identique à l'ActionScript).

Sinon très bonne idée pour éviter le onLoad.

#4 Le jeudi 20 juillet 2006 à 21:49, par Julien Tartarin

La mémoire allouée à ce bout de code par rapport à ce qu'on peut demander au navigateur sur d'autres bouts de codes me semble tout à fait négligeable...

#5 Le vendredi 21 juillet 2006 à 15:25, par iTom

Certes c'est tout à fait négligeable mais je pense que la précision est utile si quelqu'un passe par là et utiliserait le setTimeout pour faire quelque chose de beaucoup "plus lourd" en ressources.

#6 Le lundi 28 janvier 2008 à 21:53, par dom

"onload ne s'exécute qu'une fois la page chargée"??????? ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha ahahahahahahaahha
oui en effet. c'est fait pour.

#7 Le lundi 28 janvier 2008 à 21:56, par Julien Tartarin

Héhé t'es un marrant toi :)

T'as lu en entier ?

#8 Le samedi 2 août 2008 à 23:59, par Tuti

Désolé de revenir sur ce vieux post ( recherche sur gg ), mais on peut également imaginer facilement un évènement onload sur une un div ou une img, non? ( au lieu de la page entière )

#9 Le dimanche 3 août 2008 à 09:07, par Julien Tartarin

Euh... Oui, sûrement. Faut essayer pour voir :]

#10 Le mardi 28 octobre 2008 à 00:36, par Ono

Merci pour ce bout de code, il m'a été três utile !

#11 Le dimanche 28 décembre 2008 à 17:32, par WildProgrammer

Il l'a été aussi pour moi. J'ai pu corrigé un problème énorme sur un petit projet.
Bonne continuation.

Sens-Interdit.fr