11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour tout le monde,
Je ne suis pas sur de la pertinence de mon titre... mais bon. Lorsque que lance le code ci-dessous une première fois, les largeurs des trois ou quatre dernières images ne sont pas lues (la console me donne des zéros). Il faut recharger la page pour obtenir le résultat correct. Comment puis remédier à cela ?
<?php
$images = array("./skeud/diskouezadeg.png", "./skeud/diskouezadeg1.png", "./skeud/diskouezadeg2.jpg", "./skeud/diskouezadeg3.jpg","./skeud/diskouezadeg4.jpg", "./skeud/diskouezadeg5.png", "./skeud/diskouezadeg6.jpg", "./skeud/diskouezadeg7.png");
?>


<script>
let js_images = <?php echo json_encode($images); ?>;
let largeurs = [];
	
for  (var i = 0; i < (js_images.length) ; i++) {
	const img = document.createElement("img");
    img.src = js_images[i];
    largeurs[i] = img.naturalWidth;
   }  
    console.log (largeurs);


</script>
Modifié par Titen (20 Mar 2022 - 10:32)
Modérateur
Bonjour,

Il faut attendre que les images soient chargées pour en sortir des infos Smiley cligne
En lançant cette fonction sur l'evenement "onload" de window, tu devrais avoir toutes les infos.

Cdt
Merci de ta réponse mais ça n'a pas l'air d'être ça. J'ai modifié le code qui devient :
<!DOCTYPE html>
<body onLoad="start();">

<article>
<?php
$images = array("./skeud/diskouezadeg.png", "./skeud/diskouezadeg1.png", "./skeud/diskouezadeg2.jpg", "./skeud/diskouezadeg3.jpg","./skeud/diskouezadeg4.jpg", "./skeud/diskouezadeg5.png", "./skeud/diskouezadeg6.jpg", "./skeud/diskouezadeg7.png");
?>

<script>
function start(){
let js_images = <?php echo json_encode($images); ?>;
let largeurs = [];
	
for  (var i = 0; i < (js_images.length) ; i++) {
    const img = document.createElement("img");
    img.src = js_images[i];
    largeurs[i] = img.naturalWidth;
   }  
    console.log (largeurs);
}
</script>
</article>
</body>
</html>


En fait quand la page est chargée, les images ne le sont toujours pas, je crois que ce sont ces deux lignes qui s'en chargent :
const img = document.createElement("img");
img.src = js_images;

Mais je ne vois pas comment m'assurer qu'elles ont fini leur boulot...
Modérateur
okay, alors il faut le faire en deux temps: (oups, je n'avais pas remarqué que tu créer tes images à la volée)

1. creer l'element img (comme tu fais)
2. lui ajouter l’événement "onload", qui lui déclenchera la recherche d'info sur l'image une fois qu'elle est disponible.

exemple test : https://jsfiddle.net/L6gyxaoz/
Modifié par gcyrillus (20 Mar 2022 - 13:47)
Euh... c'est pire, je n'ai plus aucune valeur, mais c'est peut-être dû à une mauvaise implémentation de ton exemple :
function start(){
let js_images = <?php echo json_encode($images); ?>;
let largeurs = [];
	
for  (var i = 0; i < (js_images.length) ; i++) {
    const img = document.createElement("img");   
    img.onLoad = function (){largeurs[i]= img.naturalWidth;} 
    img.src = js_images[i];
   }  
    console.log (largeurs);
}

Je note toutefois que tu fais un div.appendChild avant de chercher à connaître la largeur de l'image. Ce qui j'imagine provoque le chargement 'réel' de l'image. Mais je veux justement tester ces largeurs pour décider ou non de l'affichage (pour un genre de petit carroussel), donc avant de faire ou pas un appendChild.
Modifié par Titen (20 Mar 2022 - 13:53)
Modérateur
En fait, il faut aussi que tu attendes que la dernière image soit chargées pour avoir toutes tes infos.
Pour ça, associe le console.log() avec le onload de la dernière image.

exemple possible :
for  (var i = 0; i < (js_images.length) ; i++) {
	const img = document.createElement("img");
    img.src = js_images[i];
	img.onload= function(){
     largeurs[i] = img.naturalWidth;
	 if (i =  js_images.length ) {
		     console.log (largeurs);
	 }
	}
   }

Ceci étant, les images sont effectivement chargées, sinon ton navigateur n'aurait rien à te dire à leur sujet .

P.S. reste critique sur ce code, je ne suis pas un expert non plus Smiley cligne
Modifié par gcyrillus (20 Mar 2022 - 18:09)
On y est.... presque !
en console, j'ai sous sous Chrome :
test.php:17 (9) [vide × 8, 124]
test.php:17 (9) [vide × 8, 112]
test.php:17 (9) [vide × 8, 118]
test.php:17 (9) [vide × 8, 104]
test.php:17 (9) [vide × 8, 111]
test.php:17 (9) [vide × 8, 112]
test.php:17 (9) [vide × 8, 104]
test.php:17 (9) [vide × 8, 124]

et avec Firefox :
Array(9) [ <8 empty slots>, 124 ]
Array(9) [ <8 empty slots>, 112 ]
Array(9) [ <8 empty slots>, 118 ]
etc..


ce qui contient bien les valeurs attendues (yeah!!!) mais pas mal parasitées... D'ailleurs si je fais ensuite un :
for  (var i = 0; i < (js_images.length) ; i++) {
	console.log (largeurs[i]);
   }


la console me répond une suite de undefined... ?? Smiley decu
Modifié par Titen (20 Mar 2022 - 18:46)
Modérateur
Si tu lances ta boucle avant que le tableau soit rempli, c'est normal , et hop => retour case 1

Sinon, pour le dernier script proposé, il était plein d'erreur (d'amateur).

Pour démontrer qu'il faut attendre que les images soit bien chargées, en donnant un délai à la boucle , on peut la voir se remplir correctement (si connexion assez rapide) https://jsfiddle.net/n9wg10k7/ pour mettre l'url avec https://jsfiddle.net/rc5mg6wL/ )
let largeurs = [];
for (var i = 0; i < (js_images.length); i++) {
  const img = document.createElement("img");
  const index = i;
  img.src = js_images[i];
  img.onload = function() {
    const largeur = img.naturalWidth;
    console.log(largeur);
    largeurs[index] = largeur;
  }
}

setTimeout(function() {
  console.log(largeurs);
  for (var i = 0; i < (js_images.length); i++) {
    console.log(largeurs[i] + ' ' + js_images[i] +' Loaded');
  }
}, 500);


On peut aussi se servir de l’événement onload et compter le nombre d'images chargées pour déclencher la boucle quand elles sont toutes là : https://jsfiddle.net/n9wg10k7/1/ (pour mettre l'url avec https://jsfiddle.net/32ftubqm/ )
let largeurs = [];
let name = [];
let index = 0;
for (var i = 0; i < (js_images.length); i++) {
  const img = document.createElement("img");

  img.src = js_images[i];
  img.onload = function() {
    const largeur = img.naturalWidth;
    console.log(largeur);
    largeurs[index] = largeur;
    name[index] = img.src
    index++;
    
    if (index == (js_images.length)) {
      for (var ii = 0; ii < (js_images.length); ii++) {
        console.log(largeurs[ii]  + ' ' + name[ii] + ' Loaded inside event');
      }
    }
  }

Note l'usage de let et const qui selon, n'aura pas la même incidence. Je ne me lancerait pas dans une explication hasardeuse.

Cdt

P.S. toujours amateur, un œil critique est toujours requis à propos des scripts proposés Smiley cligne
Modifié par gcyrillus (20 Mar 2022 - 22:23)
Meilleure solution
Nickel chrome (& firefox..) ! Un grand merci à gcyrillus : compétences et disponibilité.
Je n'ai plus qu'à essayer de bien assimiler le code proposé pour éviter mon "plein d'erreur[s]" d'amateur : c'est en codant qu'on devient codeur !
Bonne journée à tous !
Modifié par Titen (21 Mar 2022 - 11:42)