¿Alguien puede decirme por qué no puedo detectar el evento de carga en este elemento de imagen y configurar el GIF de carga para display: none ? Me gustaría configurar el div con la clase de cargador para display: none cuando se carga la primera imagen después de hacer clic en el botón Add Image . En este momento, solo establece el estilo después de hacer clic dos veces en el botón Agregar Doggo.
Aquí está el código:
HTML:
<title>image loader</title> </head> <body> <h1>Dog Images</h1> <button class="add-doggo">Add Image</button> <div class="doggos"> <div class="loader"><img src="src/Preloader.gif" /></div> </div> <script src="src/doggos.js"></script> </body>CSS:
.loader { display: none; }JavaScript:
const DOG_URL = 'https://dog.ceo/api/breeds/image/random'; const doggos = document.querySelector('.doggos'); let loader = document.querySelector('.loader'); let dogImage, isLoaded; function addNewDoggo() { const promise = fetch(DOG_URL); promise .then(function (response) { const processingPromise = response.json(); //This line of code parses the API response into a usuable js object return processingPromise; //this code returns a new promise and this process is called | PROCESS-CHAINING }) .then(function (processedResponse) { const img = document.createElement('img'); img.classList.add('dog-image'); img.src = processedResponse.message; img.alt = 'Cute doggo'; doggos.appendChild(img); }); } document.querySelector('.add-doggo').addEventListener('click', () => { dogImage = document.querySelector('.dog-image'); isLoaded = dogImage?.complete && dogImage?.naturalHeight !== 0; if (!isLoaded) { loader.style.display = 'block'; console.log(true); } else if (isLoaded) { loader.style.display = 'none'; console.log('IMAGE LOADED'); } return addNewDoggo(); }); // Adding event listener on the image element itself to detect if it's loaded document.querySelector('.dog-image').addEventListener('load', () => { console.log('DOG IMAGE LOADED'); isLoaded = dogImage?.complete && dogImage?.naturalHeight !== 0; if (isLoaded) { loader.style.display = 'none'; } });Aquí, como se menciona en un comentario, puede ver claramente que lo primero que hago con el elemento de imagen recién creado es darle un controlador de eventos para el evento de carga. Eso es realmente todo lo que hay que decir AFAIK.
"use strict"; function byId(id){return document.getElementById(id)} function qsa(sel,parent=document){return parent.querySelectorAll(sel)} function newEl(tag){return document.createElement(tag)} window.addEventListener('load', onLoaded, false); function onLoaded(evt) { qsa('button')[0].addEventListener('click', addNewDog, false); } const dogUrl = "https://dog.ceo/api/breeds/image/random"; function addNewDog() { qsa('.loader')[0].classList.remove('hidden'); fetch(dogUrl) .then( response => response.json() ) .then( jsObj => { let img = newEl('img'); img.addEventListener('load', onUserImgLoaded, false); img.classList.add('dog-image'); img.alt = 'cute dog'; img.src = jsObj.message; qsa('.doggos')[0].appendChild(img); } ); } function onUserImgLoaded(evt) { qsa('.loader')[0].classList.add('hidden'); } .hidden { display: none; } .loader img { max-width: 128px; } <h1>Dog Images</h1> <button class="add-doggo">Add Image</button> <div class="doggos"> <div class="loader hidden"><img src="https://flevix.com/wp-content/uploads/2020/01/Bounce-Bar-Preloader-1.gif" /></div> </div>