11484 sujets

JavaScript, DOM et API Web HTML5

Bonjour,
En localhost j'ai effectué une page et un script pour animer quelques élément de ma page en fonction de la hauteur du scroll. Jusque là tout va pas trop mal, mais j'ai un bug inexpliqué sur la hauteur de la page renvoyée en javascript qui ne correspondait pas à la hauteur du scroll total jusqu'en bas de page. J'ai donc retiré éléments par éléments pour voir où il y avait une différence entre la hauteur javascript et la hauteur réelle dans l'inspecteur : c'est une div d'images miniatures affichée en flexbox qui pose problème.
Du coup j'ai voulu vous en faire part et tout mis sur mon pages-perso orange et là miracle, j'ai les bonnes valeurs ... donc sur chrome en localhost, ça déconne, sur orange ça passe nickel, sur un autre hébergeur ça marche plus .... bon, donc ???
Et là miracle, je réfléchis (ça m'arrive), je mets un setTimeout et bingo à chaque fois. Identification du problème, les images mettent du temps à se charger, javascript récupère trop tôt la hauteur de la page sans les images, ça correspond donc plus.
D'où ma question : comment déclencher une fonction, une action ... bref, après le chargement complet de toutes les images.
genre images = document.getElementsByTagName('img') et tant que toutes images ne sont pas chargées donc function loaded() ne renvoie pas true pour chaque images alors on attend...
les liens du test (mais qui chez moi fonctionne avec orange Smiley smile )
http://loic.bourges.pagesperso-orange.fr/TEST/test_position.html
	
<script type="text/javascript">
	var hauteurPage=Math.round(document.documentElement.scrollHeight),
		hauteurFenetre = Math.round(window.innerHeight),
		divImages=document.getElementById("images"),
		hauteurDiv=divImages.offsetHeight;
		console.log('hauteur page : '+hauteurPage);
		console.log('hauteur fenêtre : '+hauteurFenetre);
		console.log('hauteur div images : '+hauteurDiv);
		function scroll() {
			scrollTop=Math.round(window.scrollY+hauteurFenetre);
			console.log('hauteur scroll : '+scrollTop);
		}
		document.addEventListener("scroll",scroll);
	</script>

dans la console j'affiche la hauteur de page, la hauteur de fenêtre, la hauteur de la div des images et le niveau du scroll (niveau scroll = scroll + hauteur fenêtre pour dérouler jusqu'au dernier pixel)
Merci beaucoup !
loic
j'ai bidouillé un truc qui fait le job, je ne sais pas si c'est comme ça qu'il faut aborder la chose et si c'est le plus efficace (redondance d'appel de tests ...)

<script type="text/javascript">
	var hauteurPage,
		hauteurFenetre,
		divImages,
		hauteurDiv,
		images=document.getElementsByTagName('img'),
		nbreImages=images.length,
		load=new Array(),
		loaded;

	console.log(images);
	function testLoad() {
	for (var i = 0 ; i<nbreImages ; i++) {
		load[i]=false;
		if (images[i].complete) loaded=true;
		console.log(load[i]);
			}
		return loaded;
		}
	var test=setInterval(function(){
	loaded=testLoad();
	if (loaded) 
	{
		recupHauteurs();
		console.log("testLoad true");
		clearInterval(test);
	}
	else console.log("testLoad false");
		},500);
	function recupHauteurs()
	{
	hauteurPage=Math.round(document.documentElement.scrollHeight),
	hauteurFenetre = Math.round(window.innerHeight),
	divImages=document.getElementById("images"),
	hauteurDiv=divImages.offsetHeight;
	console.log('hauteur page : '+hauteurPage);
	console.log('hauteur fenêtre : '+hauteurFenetre);
	console.log('hauteur div images : '+hauteurDiv);
		}
	function scroll() {
		scrollTop=Math.round(window.scrollY+hauteurFenetre);
		console.log('hauteur scroll : '+scrollTop);
	}
	document.addEventListener("scroll",scroll);
</script>

Du coup je veux bien quand même vos avis ...
Merci
loic
Administrateur
Bonjour et bienvenue, Smiley smile

j'avais eu un souci similaire avec un script de lazyloading où l'image était "régulièrement" annoncée comme chargée et en fait non et Chrome qui renvoyait des dimensions de 1x1 ou 0x0 pour une image "chargée" donc j'attendais avec setTimeout que les dimensions soient supérieures à 1…
C'était au 1er semestre 2015, les choses ont peut-être changé depuis Smiley smile et je ne suis pas exactement une référence en JavaScript, ce n'est pas ma compétence de base Smiley langue

Bref, à part te conseiller de rajouter pour la phase de test un log des dimensions des images quand elles sont "chargées", ça m'a pas l'air déconnant.
Idéalement tu pourrais côté serveur ralentir le chargement des images pour simuler une connexion lente (Charles Proxy ? Pas sûr du bon outil).
EDIT : ajouter un clearInterval() pour achever le setTimeout()
La version moderne pour le scroll, c'est l'API Intersection Observer mais il faut un polyfill pour IE et Firefox ESR (52, le 59 est sûrement déjà sorti)
Modifié par Felipe (27 Sep 2018 - 16:58)