OVH Cloud OVH Cloud

[IE] image.onload quand l'image est déjà dans le cache

18 réponses
Avatar
Yves Chedemois
Bonjour,

je cherche a contrôler le preload de mes images, en utilisant la méthode
onload pour passer à la suite une fois l'image chargée. Plus
précisément, je veux préloader une série d'images l'une après l'autre,
en commençant la chargement d'une image uniquement quand la précédente
est chargée.

Je bute sur la difficulté suivante : IE ne déclenche pas (ou même
apparement "pas toujours") la méthode onload quand l'image en question
est déjà dans le cache.

Or si l'image 3 est dèja dans le cache, par exemple parce qu'elle a été
utilisée dans une page consultée précédemment, ce n'est peut être pas le
cas de l'image 4. Mais comme je ne recois jamais l'évènement onload sur
la 3, la 4 ne sera jamais préloadée.

J'ai essayé de contourner le problème en utilisant onreadystatechange et
readyState dans le cas ou le browser est IE : même comportement,
onreadystatechange n'est pas déclenchée si l'image est déjà dans le cache.

Donc mes questions :
- Y a-t-il un moyen de faire en sorte que onload ou onreadystatechange
soient déclenchées "correctement" ?
- Sinon, y a-t-il un moyen direct de tester si une image est dans le cache ?
- Sinon, y a-t-il un moyen de conserver une sorte de variable globale à
l'échelle du site (càd qui ne soit pas remise à zéro quand l'utilisateur
change de page), dans laquelle je vais à la main stocker les urls des
images déja téléchargées ? En faisant l'hypothèse que l'utilisateur ne
vide pas son cache au milieu de la consultation du site...
- Ou bien toute autre meilleure idée ?

Yves

8 réponses

1 2
Avatar

var img = new Image();
img.onload = nom_de_la_fonction;
img.src='bla.jpg';
( !! ça marche si tu affectes le onload AVANT d'affecter le src
c'était ça qui me posait problème


oui,
c'est assez curieux que l'interrogation soit avant le sujet ;)

Ceci étant, on est bien obligé (au timer près)
de boucler sur la série d'images (je pense à ma petite anim)

que quand l'interpréteur JS tombe sur
monImage=new Image(); monImage.src='photo.jpg';
il lance le téléchargement de l'image.
Et ça c'est sur :-)


J'en sais rien, je vois ce que je vois ;)
et il me semble que mon IE s'arrête avant d'avoir tout chargé
(dès que je titille la page affichée)
et je subodore qu'il s'interrompt aussitôt pour s'occuper des lignes suivantes
en attendant d'avoir le temps de réflechir à la question.
ou qu'il y soit rappelé

l'image n'est pas chargée en cache par sa simple pré-déclaration


Bref, ça achève de me convaincre que les timers c'est une plaie,


le timer n'a rien à voir dans le chargement effectif ou non.
1) tu déclares les images et leur sources comme d'hab
pour lancer le chargement en cache (ok)
2) tu as ensuite une fonction (avec timer) lancée au onload de la page
pour t'assurer du chargement effectif
3) l'ensemble, me semblant démontrer que la déclaration seule
n'a pas assuré le chargement total en cache

D'ailleurs, à mon idée, ta solution démontre bien la même chose.
puisque, pour avoir l'image effectivement dans le cache
tu t'appuies sur image.onload
Le test pour image chargée lancé avant que ta méthode n'ait fini,
nous donnera tout autant une erreur si image(s) pas chargée(s)

et qu'on a sous la main un truc bien plus pratique avec onload.
Tu ne t'occupes de rien, tu sais que le browser te signalera lui meme
quand l'image est chargée.


Pour l'instant, avec mon test bricolé pour la circonstance,
il me dit ok il est passé sur les 8 images mais ne les affiche pas
(si je l'interroge, il ne les connait pas non +)

Au image.onload je boucle sur la meme fonction incrémentée
et ça n'a pas l'air de faire ...

je dois m...er sur qque chose. (cf autre post)

J'attends de voir ton code ;)

à + +

--
******** (enlever/remove [OTER_MOI] du/from reply url) *******


Avatar

en fait j'ai développé une petite lib un peu plus complexe qui me permet
de faire du prelod d'images "par groupes"

Ce n'est pas d'une utilisation très complexe, je peux t'envoyer ça si tu
veux...


J'ai un peu essayé et ... n'y suis pas arrivé, donc,

Oui, Merci.

Tu sauras corriger mon adresse ?

en attendant, voici mon truc qui ne semble pas fonctionner
(8 images 1.jpg, .... 8.jpg, dans dossier [js_web] )

A = new Array();
i=0;
function postload() {
i++;
if(i<=8) {
A[i] = new Image();
A[i].onload = postload();
A[i].src = 'js_web/'+i+'.jpg';
window.status=' image '+i; // return true;
}
else {
//alert('ok');
i=1;
affiche();
}
}

function affiche() {
if(i<=8) {
document.images['ecran'].src = A[i].src;
i++ ;
setTimeout('affiche()',2000);
}
// if(i==8) { i=1; affiche(); }
}
onload=posload;

--
******** (enlever/remove [OTER_MOI] du/from reply url) *******

Avatar
YC

var img = new Image();
img.onload = nom_de_la_fonction;
img.src='bla.jpg';
( !! ça marche si tu affectes le onload AVANT d'affecter le src
c'était ça qui me posait problème



oui,
c'est assez curieux que l'interrogation soit avant le sujet ;)

Ceci étant, on est bien obligé (au timer près)
de boucler sur la série d'images (je pense à ma petite anim)
Oui, mais ça n'a rien a voir avec du preload.

Si tu veux faire une anim "a la main" (sans passer par du gif animé ou
du flash), effectivement, les timers semblent la solution naturelle.
Je n'ai pas dit que les timers étaient le mal absolu, c'est très
pratique pour certaines choses, et pour d'autres c'est balourd.

que quand l'interpréteur JS tombe sur
monImage=new Image(); monImage.src='photo.jpg';
il lance le téléchargement de l'image.
Et ça c'est sur :-)



J'en sais rien, je vois ce que je vois ;)
et il me semble que mon IE s'arrête avant d'avoir tout chargé
(dès que je titille la page affichée)
et je subodore qu'il s'interrompt aussitôt pour s'occuper des lignes suivantes
en attendant d'avoir le temps de réflechir à la question.
ou qu'il y soit rappelé
Je ne sais pas ce que tu veux dire par "titille".




l'image n'est pas chargée en cache par sa simple pré-déclaration


Bref, ça achève de me convaincre que les timers c'est une plaie,



le timer n'a rien à voir dans le chargement effectif ou non.
1) tu déclares les images et leur sources comme d'hab
pour lancer le chargement en cache (ok)
2) tu as ensuite une fonction (avec timer) lancée au onload de la page
pour t'assurer du chargement effectif
3) l'ensemble, me semblant démontrer que la déclaration seule
n'a pas assuré le chargement total en cache

D'ailleurs, à mon idée, ta solution démontre bien la même chose.
puisque, pour avoir l'image effectivement dans le cache
tu t'appuies sur image.onload
Le test pour image chargée lancé avant que ta méthode n'ait fini,
nous donnera tout autant une erreur si image(s) pas chargée(s)
Bon. D'accord. En ce sens, "img.src='abc.jpg'" ne suffit pas à charger

l'image dans le cache. Cela suffit à LANCER le chargement, et le reste
dépend du débit de la connection, du temps de réponse du serveur, etc...
Mais ce chargement a lieu en parallèle, JS n'attend pas la fin du
chargement avant de passer à la suite de ton code (et heureusement). Je
pensais que ce point-là était clair. C'est bien pour ça qu'on a besoin
d'un truc (avec des timers ou avec du onload selon les gouts) qui nous
signale que le chargement est terminé et que l'image est disponible.

Bon. Je crois qu'on a bien posé les termes du problème :-/

Pour ton code, suivi sur l'autre post.



Avatar
YC

en fait j'ai développé une petite lib un peu plus complexe qui me permet
de faire du prelod d'images "par groupes"

Ce n'est pas d'une utilisation très complexe, je peux t'envoyer ça si tu
veux...



J'ai un peu essayé et ... n'y suis pas arrivé, donc,

Oui, Merci.

Tu sauras corriger mon adresse ?

en attendant, voici mon truc qui ne semble pas fonctionner
(8 images 1.jpg, .... 8.jpg, dans dossier [js_web] )

Indépendemment des quelques erreurs de code, ta solution ne lance le

chargement d'une image que lorsque la précédente est terminée. Pourquoi
pas, mais si tes images ne sont pas trop grosses (qques Ko) c'est
dommage à mon avis.

je dirais :

var A = new Array();
var i = 0;

function preload() { // preload est le terme couramment utilisé
// pour faire ce genre de choses : tu charges les
// images AVANT de demander leur affichage => PREload
for (var j = 1; j<9; j++) {
A[j] = new Image();
A[j].onload = isComplete; // pas de parenthèses !
A[j].src = 'js_web/'+j+'.jpg';
}
}

function isComplete() {
i++; // une image de plus a terminé de charger
if (i==8) { // toutes les images sont pretes, on passe à la suite
// window.alert('chargement terminé');
i = 1; // ce n'est peut-être pas un bonne idée de garder la même
// variable, mais bon...
anim();
}

function anim() {
// window.status='affiche image '+i;
if (i>8) i=1;
document.images['ecran'].src = A[i].src;
// ou meme peut-être directement document.images['ecran'] = A[i]; ?
i++ ;
setTimeout('affiche()',2000);
}

window.onload=preload;
// ou directement dans le HTML : <body onload="preload();">

Bon, à tester, mais ça devrait être à peu près ça.

Sinon je t'envoie la lib dont je te parlais. Pour ce cas précis, c'est
sans doute prendre un marteau pour écraser une mouche, mais à toi de voir.


Avatar

Indépendemment des quelques erreurs de code,


Voilà qu'on croit qu'on arrive à tripatouiller du code
et dès que ce n'est plus dans les habitudes ça errore ! :-(

ta solution ne lance le
chargement d'une image que lorsque la précédente est terminée. Pourquoi
pas,


Oui, pourquoi pas ? (ça suit le raisonnement du bidule avec timer)

mais si tes images ne sont pas trop grosses (qques Ko) c'est
dommage à mon avis.


Explication ?
mon anim en JS, si en RTC, et sans preLoad n'est pas terrible
(dans ce cas, si ça veut bien démarrer,
ça peut aussi bien sauter 3 images par-ci par-là aux 2 ou 3 1ers passages)
(20 images d'environ 2000 octets chaque, faut leur laisser le temps d'arriver)

je dirais :

var A = new Array();
var i = 0;

function preload() { // preload est le terme couramment utilisé
// pour faire ce genre de choses : tu charges les
// images AVANT de demander leur affichage => PREload


Hoeu-Kaiye Hoeu-Kaiye ;)
j'va ben finir par comprlendrle :-)

for (var j = 1; j<9; j++) {
A[j] = new Image();
A[j].onload = isComplete; // pas de parenthèses !


Bon sang ! mais c'est bien sûr !
Voilà que mon truc commence à marchicoter ;-)

A[j].src = 'js_web/'+j+'.jpg';
}
}

function isComplete() {
i++; // une image de plus a terminé de charger
if (i==8) { // toutes les images sont pretes, on passe à la suite
// window.alert('chargement terminé');
i = 1; // ce n'est peut-être pas un bonne idée de garder la même
// variable, mais bon...


Bof !
puisque qu'on en n'a plus besoin pour le précedent ... autant que ça reserve

anim();
}

function anim() {
// window.status='affiche image '+i;
if (i>8) i=1;
document.images['ecran'].src = A[i].src;
// ou meme peut-être directement document.images['ecran'] = A[i]; ?
i++ ;
setTimeout('affiche()',2000);
}

window.onload=preload;
// ou directement dans le HTML : <body onload="preload();">


paraittrait que c'est mal vu des stricteurs
de balancer des machins dans la balise body
Me goure-je encore ?

Bon, à tester, mais ça devrait être à peu près ça.


Testé,
à part une } et la fonction affiche() non déclarée
tout baigne ;)
Je pense commencer à comprendre la méthode ;)

Sinon je t'envoie la lib dont je te parlais. Pour ce cas précis, c'est
sans doute prendre un marteau pour écraser une mouche, mais à toi de voir.


C'est bien sûr, surtout histoire de curiosité
étant condamné au RTC je reste encore très sensible au poids
de ce qui transite par le Net
Je doute que je m'aventure dans le chargement (pré-post) de
groupe(s) d'images lourdes (>10 ou 20ko)


--
******** (enlever/remove [OTER_MOI] du/from reply url) *******
Stéphane MORIAUX : mailto:
Aide aux Pages Perso (images & couleurs, formulaire, CHP, JS)
http://perso.wanadoo.fr/stephane.moriaux/internet/
**************************************************************

Avatar
YC

ta solution ne lance le
chargement d'une image que lorsque la précédente est terminée. Pourquoi
pas,
mais si tes images ne sont pas trop grosses (qques Ko) c'est
dommage à mon avis.



Explication ?
Je sais pas, c'est mon feeling, je ne saurais pas bien le justifier

correctement. Je me dis que si les navigateurs pas seulement IE...), par
défaut, chargent les différents éléments d'une page en parallèle, c'est
que ça doit être mieux... Juste dans mon cas il y des fois ou je ne
_veux_ pas que ça se passe comme ça, alors je ruse.

Pour ton cas précis, à toi de voir :-)

mon anim en JS, si en RTC, et sans preLoad n'est pas terrible
(dans ce cas, si ça veut bien démarrer,
ça peut aussi bien sauter 3 images par-ci par-là aux 2 ou 3 1ers passages)
(20 images d'environ 2000 octets chaque, faut leur laisser le temps d'arriver)
pas avec le code que tu proposais (et le mien aussi d'ailleurs) : l'anim

n'est lancée que quand toutes les images qui la composent sont disponibles.

window.onload=preload;
// ou directement dans le HTML : <body onload="preload();">



paraittrait que c'est mal vu des stricteurs
de balancer des machins dans la balise body
Me goure-je encore ?
Ah, je ne sais pas, je valide en XHTML Transitionnal...

Mais je crois bien que le XHTML strict (et donc a fortiori le HTML)
connait l'attribut onload pour le tag body...

Testé,
à part une } et la fonction affiche() non déclarée
tout baigne ;)
Yep, j'avais copié sans faire gaffe que j'avais changé le nom de ta

fonction :-)

C'est bien sûr, surtout histoire de curiosité
étant condamné au RTC je reste encore très sensible au poids
de ce qui transite par le Net
Je doute que je m'aventure dans le chargement (pré-post) de
groupe(s) d'images lourdes (>10 ou 20ko)



Ben c'est précisément pour que mon site soit viable en RTC que j'ai
développé la lib...
Je fais quelques hypothèses sur la navigation de l'utilisateur, et je
préloade tout ce que je peux le maximum en avance possible...
Donc j'ai besoin de pouvoir dire qu'il y des trucs urgents à preloader,
et d'autres "si on a le temps..."

Tu verras si ça peut t'être utile...


Avatar


mon anim en JS, si en RTC et sans preLoad, n'est pas terrible


pas avec le code que tu proposais (et le mien aussi d'ailleurs) : l'anim
n'est lancée que quand toutes les images qui la composent sont disponibles.


toutafé, c'est bien le but de la manip
et donc, on s'assure du chargement effectif d'1 image après l'autre.

Je doute que je m'aventure dans le chargement (pré-post) de
groupe(s) d'images lourdes (>10 ou 20ko)


Ben c'est précisément pour que mon site soit viable en RTC que j'ai
développé la lib...
Je fais quelques hypothèses sur la navigation de l'utilisateur, et je
préloade tout ce que je peux le maximum en avance possible...


Encore qque chose qui m'échape ici ...
Tu sais touj d'avance vers quelle page le visiteur va sauter
pour en assurer le préload pendant la consult de celle présentée ?

Je fais çà pour du diaporama mais je suis quasi certain de la page suivante
puisque bouton [vue suivante] sur la page ;-).
http://perso.wanadoo.fr/stephane.moriaux/truc/popup_image_auto_4.shtml

Donc j'ai besoin de pouvoir dire qu'il y des trucs urgents à preloader,
et d'autres "si on a le temps..."

Tu verras si ça peut t'être utile...


Pour l'heure on essaie d'y comprendre ;-))

--
******** (enlever/remove [OTER_MOI] du/from reply url) *******
Stéphane MORIAUX : mailto:
Aide aux Pages Perso (images & couleurs, formulaire, CHP, JS)
http://perso.wanadoo.fr/stephane.moriaux/internet/
**************************************************************


Avatar
YC

pas avec le code que tu proposais (et le mien aussi d'ailleurs) : l'anim
n'est lancée que quand toutes les images qui la composent sont disponibles.



toutafé, c'est bien le but de la manip
et donc, on s'assure du chargement effectif d'1 image après l'autre.
Pas forcément, ce qui compte c'est que tu t'assures que au moment de

lancer l'anim toutes les images sont dispo.
Mais tu peux les charger l'une après l'autre ou toutes en parallèle,
c'est comme tu veux...

Je doute que je m'aventure dans le chargement (pré-post) de
groupe(s) d'images lourdes (>10 ou 20ko)


Ben c'est précisément pour que mon site soit viable en RTC que j'ai
développé la lib...
Je fais quelques hypothèses sur la navigation de l'utilisateur, et je
préloade tout ce que je peux le maximum en avance possible...



Encore qque chose qui m'échape ici ...
Tu sais touj d'avance vers quelle page le visiteur va sauter
pour en assurer le préload pendant la consult de celle présentée ?

Je fais çà pour du diaporama mais je suis quasi certain de la page suivante
puisque bouton [vue suivante] sur la page ;-).
http://perso.wanadoo.fr/stephane.moriaux/truc/popup_image_auto_4.shtml

C'est ce que je veux dire quand je dis "je fais des hypothèses"...

Si l'utilisateur a un comportement différent, c'est pas grave, juste le
preload sera un peu moins efficace...



1 2