J'exécute un script après le chargement de l'image d'en-tête de page:
objImg = new Image(); objImg.src = '/images/header.jpg'; objImg.onload = function() { $('#myDiv').fadeIn(500); }
Cela fonctionne très bien. Cependant, sur l'une des pages, j'en ai besoin pour s'exécuter après le chargement de quatre images au lieu d'une seule. Y a-t-il un moyen de modifier cela pour qu'il s'agisse d'un tableau au lieu d'une seule image?
3 Réponses :
Cela pourrait être fait en utilisant des promesses comme ici . Ou simplement en boucle tout en stockant leurs sources dans un tableau parallèle et utilisez une fonction de rappel lorsque toutes les images sont préchargées. Le tableau parallèle pourrait également être utile lors des erreurs de chargement afin que nous puissions l'utiliser pour afficher uniquement des images préchargées et valides.
Une approche plus sophistiquée ajouterait une fonction pour tester la disponibilité de l'image avant même de la précharger en utilisant XMLHttpRequest (); ou un ajax.
Notez que j'utilise une fausse image ici pour tester l'échec du chargement.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="myDiv"></div>
#myDiv{ display:none; }
var pix = new Array('https://image.shutterstock.com/image-photo/colorful-hot-air-balloons-flying-260nw-1033306540.jpg','https://images.fineartamerica.com/images-medium-large-5/hot-air-balloons-over-hay-bales-sunset-landscape-matthew-gibson.jpg','https://iso.500px.com/wp-content/uploads/2014/07/big-one.jpg','https://some.thing/undefined.jpg','https://cdn-media.rtl.fr/cache/4gx11M-ZCLtBdzqGMR2TWA/880v587-0/online/image/2019/1212/7799676803_l-enfant-de-the-mandalorian-est-la-star-de-la-galaxie.jpg'); var total = pix.length; var ctr = 0; var cache=[]; for(var i=0; i<total; i++){ var img = new Image(); img.src = pix[i]; //We push it to the cached elements list cache.push(img); img.onload = function(){ console.log('Pic loaded!'); ctr++; //When all are loaded if(ctr == total){ console.log('All done ;) '); //We append them to the targeted div WellDone(); } } img.onerror = function(){ //Because we didn't test the picture loading before adding it, we have to remove the failing image from the array cache.splice(i, 1); ctr++; if(ctr == total){ console.log('All done ;) '); //We append them to the targeted div WellDone(); } } } function WellDone(){ //finally here things could run in a sequence! for (var i = 0; i < cache.length; i++) { $('#myDiv').append(cache[i]); } cache=[]; $('#myDiv').fadeIn(500); }
La démo ci-dessous utilise une fonction async
et wait
mot clé pour qu'une Promise contrôle l'interaction asynchrone entre le client (vous) et un test en direct serveur au endpoint donné (premier paramètre) . Un sélecteur (deuxième paramètre facultatif) d'un DOM L'élément est passé pour spécifier où rendre les images (la valeur par défaut est "body"
s'il n'est pas défini).
<header class='gallery'></header>
fetch ()
est une fonction asynchrone qui garantit une réponse ou un rejet des données demandées via le mot-clé await
. Le .json ()
a> (également précédée de await
) récupère le JSON.
.gallery { display: flex; justify-content: center; width: 96%; margin: 10px auto; padding: 5px; background: rgb(138, 56, 201); } figure { width: 50vw; margin: 10px 2.5px 5px; } figcaption { font: 700 small-caps 3vw/1 Arial; color: gold; text-align: center; } img { width: 100%; height: auto; } @keyframes fadeIn { from { opacity: 0; } 50% { opacity: 0.66; } to { opacity: 1; } }
Ensuite, le tableau JSON (alias imgArray
) est exécuté via la méthode de tableau .forEach ((src, idx) => {...
. Chaque URL ( src
premier paramètre) dans imgArray
est traitée. Le Voici une description étape par étape de la première URL d'image en cours de traitement ( Notez comment le deuxième paramètre idx
est utilisé à l'étape 3 ):
Faites référence à l'élément DOM dans lequel les images seront placées
const endpoint = `https://api.myjson.com/bins/19fk22`; const fetchImages = async(endpoint, selector = "body") => { const response = await fetch(endpoint); let imgArray = await response.json(); imgArray.forEach((src, idx) => { const node = document.querySelector(selector); let name = src.split('/').pop().split('.').shift(); let html = ` <figure style="animation: ${3 * (idx+1)}s fadeIn"> <img src="${src}"> <figcaption>${name}</figcaption> </figure>`; node.insertAdjacentHTML("beforeend", html); }); } fetchImages(endpoint, '.gallery');
Extrayez le nom de fichier de l'image avec .split ()
let html = ` <figure style="animation: ${3 * (idx+1)}s fadeIn">` /* <figure style="animation: 3s fadeIn"> Each iteration is assigned an increased CSS animation-duration value. The first image fades in for 3sec, the second image fades in for 6sec, third 9sec, etc. The actual code for the animation is in the CSS. */ `<img src="${src}">` // <img src="https://i.ibb.co/hZj77BZ/lena01.jpg"> `<figcaption>${name}</figcaption>` /* <figcaption>LENA01</figcaption> The name value from step #2 is inserted as a caption and styled by CSS */ `</figure>`; node.insertAdjacentHTML("beforeend", html); /* .insertAdjacentHTML(position, htmlString) is .innerHTML on steroids @Param: [Position]: "beforebegin", "afterbegin", "beforeend", or "afterend" @Param: [htmlString]: strongly suggest that template literals be used instead of literal strings
Attribuez un littéral de modèle d'une htmlString
à une variable ( let html
) puis interpolez $ {values}
et / ou $ {expressions} code>
let name = src.split('/') // ['https:', 'i.ibb.co', 'hZj77BZ', 'lena01.jpg'] .pop() // 'lena01.jpg' .split('.') // ['lena01', 'jpg'] .shift(); // 'lena01'
const node = document.querySelector('.gallery') // <header class="gallery">|<= images will be inserted here =>|</header>
const response = await fetch(`https://api.myjson.com/bins/19fk22`); let imgArray = await response.json(); /* At this point the JSON is stored in a variable called imgArray imgArray = [ "https://i.ibb.co/hZj77BZ/lena01.jpg", "https://i.ibb.co/7XxsBr5/lena02.png", "https://i.ibb.co/X7SCb3w/lena03.png" ] */
fetchImages("https://sub.domain.tld/path/to/json", "tagName#id.className[attribute]"/*or "body"*/)
J'utiliserais quelque chose comme ceci.
Utilisez la même approche dans votre question.
Pour le tableau d'images, donnez une classe, dites image-wait-for-load à la balise
img
Recherchez maintenant combien d'images il y a dans votre page à attendre.
var waitImageCount = $ ( '.image-wait-for-load'). length;
Code pour vérifier si toutes les images sont chargées.
$(document /* or what ever */).on('load', '.image-wait-for-load', function() { waitImageCount--; // decrease the counter if(waitImageCount === 0) { // all images are loaded. // Do what ever you like } });
Veuillez notez que ce code n'a pas été testé, mais j'espère que quelque chose comme ça devrait fonctionner.
Je viens de le UPvoté! Parce que même s'il ne gère pas les erreurs, l'approche est créative et nouvelle pour moi :)