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

10 réponses

1 2
Avatar
Le Fou
Yves Chedemois a écrit

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


A l'adresse :
http://perso.club-internet.fr/ehiller/barreprog/
Regarde le code, j'utilise la propriété "complete" de l'image pour tester si
elle est totalement chargée afin de modifier la barre de chargement (ça tu
t'en fous) et de passer à la suivante.
Ca peut peut-être t'aider...

--
A'tchao

Le Fou
http://perso.club-internet.fr/ehiller/
http://club.exocet.free.fr/
http://www.ffessm-cd84.com/

Avatar
Yves Chedemois

A l'adresse :
http://perso.club-internet.fr/ehiller/barreprog/
Regarde le code, j'utilise la propriété "complete" de l'image pour tester si
elle est totalement chargée afin de modifier la barre de chargement (ça tu
t'en fous) et de passer à la suivante.


Reste en effet toujours la solution de mettre des timers pour aller voir
si l'image est OK.

Mais franchement ça me fend un peu le coeur d'avoir sous la main un
modèle évènementiel bien propre qui est censé te prévenir tout seul, et
d'être obligé de bidouiller en allant vérifier toutes les x
millisecondes si par hasard le truc qui doit me faire signe n'aurait pas
oublié de le faire.

M'enfin, quand le truc bien propre marche pas, on est un peu oblige de
laisser ses visées esthétiques de côté... Je mettrai donc des timers... :-)

Avatar

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.


<script type="text/javascript"><!--

// déclaration des images à préloader
if(document.images) {
I = new Array();
I[0] = new Image(); I[0].src = 'photos/vue_1.jpg';
I[1] = new Image(); I[1].src = 'photos/truc.jpg';
.../...

I[99] = new Image(); I[99].src = 'croquis/machin.jpg';
}

// vérif et confortement des préload d'images
function preload() {
ok = 1;
window.status = 'Verif cache des images';
for(var i=0;i<I.length;i++)
if(!(I[i].complete)) ok=0;
(ok==0)?
setTimeout('preload()',200)
:
window.status='toutes images ok';
}

// post chargement des preloadées :-))
onload=preload;

// pre-chargement des pre-loadées
// non conseillé car on attend devant une page blanche
// preload();

// --></script>

Méthode employée ici pour la petite animation haut-gauche
http://perso.wanadoo.fr/stephane.moriaux/internet/web_vrml/
La première page ça rame
en attendant que le chargement en cache se fasse
à la page suivante,
l'animation se met (théoriquement) en route assez vite

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.


La simple déclaration des sources des images
monImage=new Image(); monImage.src='photo.jpg';
ne suffit pas à un pre-load effectif 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" ?


Dès que tu cliquottes sur la page le navigateur arrête
de charger en cache les images déclarées
(et le + souvent le post-load aussi est stopé).
Ces déclarations aideront à retrouver le chemin de l'image
demandée à l'instant t (par un clic ou un appel en JS)
et le navigateur choisira celle du cache si elle y est
Tu peux en profiter pour relancer la vérification preload()
comme ça, avec un peu de chance, la liste des en-cache va se compléter.

- Sinon, y a-t-il un moyen direct de tester si une image est dans le cache ?


oui :
<a href="#" onclick="
var monImage=I[3];
if(monImage.complete) alert('Tu m'appelles ?n mec');
else alert('Un jour peut-etre ?');
">Photo 4, es-tu pré-chargée ?</a>

- 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 ?


Ben, par la déclaration, même si elle a été faite dans une autre page,
le navigateur se souviendra de la source (url) proposée
qu'il aura archivée/classée dans le cache avec l'image (complète ou non)
Il saura la retrouver sans peine si on lui redemande la même image.

Et si elle n'y est pas, et bien il la charge à son appel.

Sur chaque page, si tu y veux une espèce de post-pre-load des images
qui pourront y être post-chargées
à mon idée tu dois y mettre la routine complète donnée + haut
éventuellement complétée des nouvelles images mises "à la main"

Eviter dès la 1ère page de faire charger l'album complet ! :-)

Pour se souvenir de page en page
le + facile est de faire afficher les pages dans une page de cadres
C'est la page de cadre qui aura le script donné + haut

Pour y ajouter de nvelles vues par le chargement d'1 nvelle page:

<script type="text/javascript"><!-- // script sur nvelle page
if(document.images) {
parent.I[parent.I.length] = new Image();
parent.I[parent.I.lenth-1].src = 'autres/photo_maison.jpg';
parent.I[parent.I.length] = new Image();
parent.I[parent.I.lenth-1].src = 'autres/photo_chbre.jpg';
}
parent.preload();
// --></script>


--
******** (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
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.



<script type="text/javascript"><!--
(...)
// --></script>



Merci pour le code, mais j'aurais vraiment préféré me passer de timers,
c'est sale et la méthode image.onload est précisément là pour permettre
de s'en passer (enfin, "_devrait_ être la pour permettre" etc...)

Méthode employée ici pour la petite animation haut-gauche
http://perso.wanadoo.fr/stephane.moriaux/internet/web_vrml/


OK sous Mozilla mais bug sous IE ? pas d'anim et la status bar indique
'clic pour STOP ou pour REPRENDRE'

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.



La simple déclaration des sources des images
monImage=new Image(); monImage.src='photo.jpg';
ne suffit pas à un pre-load effectif dans le cache


- Ah ? il me semblait pourtant bien que si...
- Je ne comprends pas le lien avec ma remarque :-)


- Sinon, y a-t-il un moyen direct de tester si une image est dans le cache ?



oui :
<a href="#" onclick="
var monImage=I[3];
if(monImage.complete) alert('Tu m'appelles ?n mec');
else alert('Un jour peut-etre ?');
">Photo 4, es-tu pré-chargée ?</a>


Oui, mais il faut faire le test sur monImage.complete un temps
"suffisament long"
après la demande de download pour laisser au browser le temps de faire la
vérification. Faire :
monImage = new Image();monImage.src='zozo.jpg';
(monImage.complete)?window.alert('non'):window.alert('oui');
affichera 'non', même si l'image est déja dans le cache.
Donc ça veut dire effectivement mettre des timers... Beurk

- 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 ?



Ben, par la déclaration, même si elle a été faite dans une autre page,
le navigateur se souviendra de la source (url) proposée
qu'il aura archivée/classée dans le cache avec l'image (complète ou non)
Il saura la retrouver sans peine si on lui redemande la même image.


Bien sur, c'est le principe du cache.

Pour se souvenir de page en page
le + facile est de faire afficher les pages dans une page de cadres
C'est la page de cadre qui aura le script donné + haut


Trop contraignant, je n'ai pas envie de m'embeter avec des frames alors
que mon site n'en nécessite pas au niveau de la mise en page.


Avatar
Yves Chedemois
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.


Bon, je me réponds moi-même, parce que j'ai fini par trouver mon erreur,
et mon erreur c'est que je suis un peu stupide...

je faisais dans l'ordre :
monImage = new Image;
monImage.src = 'images/bla.jpg';
monImage.onload = new Function("window.alert('image chargée !");

et là, effectivement, si l'image est déjà dans le cache, la fonction
nextImage n'est pas déclenchée

ce qu'il faut faire (evidemment ?) c'est attribuer la callback de fin de
chargement AVANT d'indiquer l'url :
monImage = new Image;
monImage.onload = new Function("window.alert('image chargée !");
monImage.src = 'images/bla.jpg';

Et ça marche.

Au passage, j'en profite pour encourager vivement cette approche par
rapport à celle des timers pour faire des trucs autour du preloading
d'images : quand l'image est chargée, le browser vous le signale, donc
pas la peine de lancer un timer par image pour aller voir si son
chargement est fini...

Avatar

Merci pour le code, mais j'aurais vraiment préféré me passer de timers,
c'est sale et la méthode image.onload est précisément là pour permettre
de s'en passer (enfin, "_devrait_ être la pour permettre" etc...)


la méthode image.onload
kesako ? ( bon, je regarde dans le post suivant )

En quoi cela répond-il à if image chargée ?
N'est-ce point encore une facilité à la IE ?
et image.postload ? c'est pour quand ?
(je préfére postloader pendant que la visite de la page se fait)

Méthode employée ici pour la petite animation haut-gauche
http://perso.wanadoo.fr/stephane.moriaux/internet/web_vrml/


OK sous Mozilla mais bug sous IE ? pas d'anim et la status bar indique
'clic pour STOP ou pour REPRENDRE'


Ah! ben ça c'est nouveau !
Je n'ai pas ce pb (IE5 Mac),
la barre d'état m'indique les fichiers en cours de chargement
et, il semblerait, ceux des images de l'anim aussi.
nota : il y a longtemps que je n'ai pas autopsié cette page
et elle ne devrait donc + être dans le cache
Le message indiqué ne doit apparaître qu'au survol de l'anim
(justement, en cliquant, pour faire ce qu'il est dit)

La simple déclaration des sources des images
monImage=new Image(); monImage.src='photo.jpg';
ne suffit pas à un pre-load effectif dans le cache


- Ah ? il me semblait pourtant bien que si...


D'expérience, il me semble bien que non ...
C'est le pb rencontré très souvent avec les roll-overs
Bien sûr il faut ss doute avoir la chance d'être en RTC
pour s'en apercevoir ;-)

- Je ne comprends pas le lien avec ma remarque :-)


Comme tu ne decris pas ta méthode, je suis en droit de l'imaginer
et c'est celle là à laquelle j'ai pensé

- Sinon, y a-t-il un moyen direct de tester si une image est dans le cache ?


<a href="#" onclick="
var monImage=I[3];
if(monImage.complete) alert('Tu m'appelles ?n mec');
else alert('Un jour peut-etre ?');
">Photo 4, es-tu pré-chargée ?</a>


Oui, mais il faut faire le test sur monImage.complete un temps
"suffisament long"


Bien entendu ! tu te moques ?
faut attendre que l'image soit dans le cache pour en avoir confirmation !
N'est-ce point le but et la réponse à ta question "tester si" ?

Et donc, c'est bien çà et on en a confirmation,
l'image n'est pas chargée en cache par sa simple pré-déclaration

après la demande de download pour laisser au browser le temps de faire la
vérification. Faire :
monImage = new Image();monImage.src='zozo.jpg';
(monImage.complete)?window.alert('non'):window.alert('oui');
affichera 'non', même si l'image est déja dans le cache.


Est-ce que tu es certain d'avoir eu zozo.jpg en cache avant de lancer ce code ?
Si oui, on peut imaginer que : elle n'y est pas puisque : new Image()
et peut-être même : sous-entendu "de cette page" car if(document.images)
Il faut peut-être laisser le temps au cache de se réorganiser
(par des doublons ou des alias à créer ?)


--
******** (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

ce qu'il faut faire (evidemment ?) c'est attribuer la callback de fin de
chargement AVANT d'indiquer l'url :
monImage = new Image;
monImage.onload = new Function("window.alert('image chargée !");
monImage.src = 'images/bla.jpg';


new Function("window.alert('image chargée !')");

Et ça marche.


je vais essayer avec mon anim
bien que je n'ai pas réussi l'affichage de l'image chargée...

tu n'as pas le code complet pré-mâché ?

--
******** (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

Merci pour le code, mais j'aurais vraiment préféré me passer de timers,
c'est sale et la méthode image.onload est précisément là pour permettre
de s'en passer (enfin, "_devrait_ être la pour permettre" etc...)



la méthode image.onload
kesako ? ( bon, je regarde dans le post suivant )

En quoi cela répond-il à if image chargée ?
N'est-ce point encore une facilité à la IE ?
(désolé, je reviens sur le forum un peu tard...)


onload est un évènement utilisable sur les objets images, un peu comme
le onclick ou onmouseover - en l'occurrence, il sert à indiquer du code
JS à exécuter quand le chargement de l'image est terminé.

Il répond donc très directement (et très simplement) à "if image
chargée" :-)

Ce n'est pas du tout un évènement particulier à IE (contrairement à
onreadystatechange, qui joue un peu le même rôle en plus détaillé),
l'évènement onload est dans les standards, recunnu par tous les
browsers. (c'est en fait le même que dans <body onload="blabla...">

Tu peux le déclarer soit en html
<img src='bla.jpg' onload='aExecuterQuandLImageEstChargee();' alt='' etc...>
soit dynamiquement sur un objet JS que tu crées pour du faire du preload
var img = new Image();
img.preload = 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 - voir mon dernier post dans le thread)

et image.postload ? c'est pour quand ?
(je préfére postloader pendant que la visite de la page se fait)
Bien sur, quand on parle de "preload", on veut dire en général un truc

qui est déclenché par <body onload="preloadImages();">, c'est à dire
APRES le chargement de la page elle-même - c'est à dire ce que tu
appelles du postload

La simple déclaration des sources des images
monImage=new Image(); monImage.src='photo.jpg';
ne suffit pas à un pre-load effectif dans le cache


- Ah ? il me semblait pourtant bien que si...



D'expérience, il me semble bien que non ...
C'est le pb rencontré très souvent avec les roll-overs
Bien sûr il faut ss doute avoir la chance d'être en RTC
pour s'en apercevoir ;-)
Je crois qu'il y a malentendu sur les termes. Ce que je veux dire, c'est

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



- Je ne comprends pas le lien avec ma remarque :-)



Comme tu ne decris pas ta méthode, je suis en droit de l'imaginer
et c'est celle là à laquelle j'ai pensé


- Sinon, y a-t-il un moyen direct de tester si une image est dans le cache ?


<a href="#" onclick="
var monImage=I[3];
if(monImage.complete) alert('Tu m'appelles ?n mec');
else alert('Un jour peut-etre ?');
">Photo 4, es-tu pré-chargée ?</a>


Oui, mais il faut faire le test sur monImage.complete un temps
"suffisament long"



Bien entendu ! tu te moques ?
faut attendre que l'image soit dans le cache pour en avoir confirmation !
N'est-ce point le but et la réponse à ta question "tester si" ?

Et donc, c'est bien çà et on en a confirmation,
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,
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.




Avatar
YC
tu n'as pas le code complet pré-mâché ?



pas vraiment de manière prémachée simple...
en fait j'ai développé une petite lib un peu plus complexe qui me permet
de faire du prelod d'images "par groupes"
ça charge un groupe dimages, et ça ne passe au groupe suivant que quand
toutes les images ont terminé de charger
Ca permet de définir un ordre de priorité, et de s'assurer le plus
"urgent" arrive d'abord sans être plombé par de grosses images.

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

Avatar
YC

Merci pour le code, mais j'aurais vraiment préféré me passer de timers,
c'est sale et la méthode image.onload est précisément là pour permettre
de s'en passer (enfin, "_devrait_ être la pour permettre" etc...)



la méthode image.onload
kesako ? ( bon, je regarde dans le post suivant )

En quoi cela répond-il à if image chargée ?
N'est-ce point encore une facilité à la IE ?
(désolé, je reviens sur le forum un peu tard...)


onload est un évènement utilisable sur les objets images, un peu comme
le onclick ou onmouseover - en l'occurrence, il sert à indiquer du code
JS à exécuter quand le chargement de l'image est terminé.

Il répond donc très directement (et très simplement) à "if image
chargée" :-)

Ce n'est pas du tout un évènement particulier à IE (contrairement à
onreadystatechange, qui joue un peu le même rôle en plus détaillé),
l'évènement onload est dans les standards, recunnu par tous les
browsers. (c'est en fait le même que dans <body onload="blabla...">

Tu peux le déclarer soit en html
<img src='bla.jpg' onload='aExecuterQuandLImageEstChargee();' alt='' etc...>
soit dynamiquement sur un objet JS que tu crées pour du faire du preload
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 - voir mon dernier post dans le thread)

et image.postload ? c'est pour quand ?
(je préfére postloader pendant que la visite de la page se fait)


Bien sur, quand on parle de "preload", on veut dire en général un truc
qui est déclenché par <body onload="preloadImages();">, c'est à dire
APRES le chargement de la page elle-même - c'est à dire ce que tu
appelles du postload

La simple déclaration des sources des images
monImage=new Image(); monImage.src='photo.jpg';
ne suffit pas à un pre-load effectif dans le cache


- Ah ? il me semblait pourtant bien que si...



D'expérience, il me semble bien que non ...
C'est le pb rencontré très souvent avec les roll-overs
Bien sûr il faut ss doute avoir la chance d'être en RTC
pour s'en apercevoir ;-)
Je crois qu'il y a malentendu sur les termes. Ce que je veux dire, c'est

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



- Je ne comprends pas le lien avec ma remarque :-)



Comme tu ne decris pas ta méthode, je suis en droit de l'imaginer
et c'est celle là à laquelle j'ai pensé


- Sinon, y a-t-il un moyen direct de tester si une image est dans le cache ?


<a href="#" onclick="
var monImage=I[3];
if(monImage.complete) alert('Tu m'appelles ?n mec');
else alert('Un jour peut-etre ?');
">Photo 4, es-tu pré-chargée ?</a>


Oui, mais il faut faire le test sur monImage.complete un temps
"suffisament long"



Bien entendu ! tu te moques ?
faut attendre que l'image soit dans le cache pour en avoir confirmation !
N'est-ce point le but et la réponse à ta question "tester si" ?

Et donc, c'est bien çà et on en a confirmation,
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,
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.




1 2