How to make a callback only when the images from the get request are loaded
I make a request to the address return
which returns the generated html.
the request code looks like this:
document.addEventListener("DOMContentLoaded", function() {
axios.get("/get-cards")
.then(response => {
document.getElementById("load").remove();
$("#content").html(response.data);
})
.catch(error => {
console.log(`ERROR: ${error}`);
});
});
The page that generates html (at /get-cards) looks like this:
@foreach($technics as $technic)
<div class="technic-card">
<div class="card-img">
<div style="background-image: url('{{ $technic->img_1 }}'" alt="{{ $technic->name }}">
<div style="background-image: url('{{ $technic->img_2 }}'" alt="{{ $technic->name }}">
<div style="background-image: url('{{ $technic->img_3 }}'" alt="{{ $technic->name }}">
</div>
<div class="card-name">{{ $technic->name }}</div>
<div class="card-type">{{ $technic->type }}</div>
<div class="card-footer">
<div class="card-price">{{ $technic->price }}/час</div>
<div class="card-buy-btn">арендовать</div>
</div>
</div>
@endforeach
I need to add ready-made html with uploaded images to the page, but the following scenario occurs.
- loads the page from which the request is sent and then the response (html markup) and added
- the loading indicator turns on
- the request returns the response
- the loading indicator is removed
- html code is added to the page
- and the images start loading it looks like this
How do I make sure that the loading indicator does not disappear until the images are loaded too?
0
Author: midnightelf18, 2020-10-09
1 answers
You need to find all the images and wait for them to load
In the example, I put the url of the images in a separate attribute for convenience, but it is quite possible to get element.style
from
// вместо getCards будет запрос через axios
getCards()
// когда ответ пришёл
.then(html => {
$('#content').html(html);
let loading = [];
// ищем картинки для прогрузки
$('#content [data-bg]').each(function(){
loading.push(new Promise(resolve => {
// Собираем url которые придётся грузить
let url = $(this).data('bg');
// создаём в памяти картинку
let img = new Image();
// и грузим её
img.src = url;
// когда загрузится, ставим её в background-image
// и отчитываемся о завершении
img.onload = () => {
$(this).css('background-image', `url(${url})`);
resolve();
}
}));
});
// когда всё загрузится
Promise.all(loading).then(()=>{
// убираем заглушку
// и показываем контент
$('#load').remove();
$('#content').removeClass('loading');
})
});
function getCards(){
return new Promise(resolve => {
setTimeout(()=>{
resolve(
`<div class="card">
<div data-bg="https://via.placeholder.com/350x150?r=${Math.random()}"></div>
<div data-bg="https://via.placeholder.com/350x150?r=${Math.random()}"></div>
<div data-bg="https://via.placeholder.com/350x150?r=${Math.random()}"></div>
</div>
<div class="card">
<div data-bg="https://via.placeholder.com/350x150?r=${Math.random()}"></div>
<div data-bg="https://via.placeholder.com/350x150?r=${Math.random()}"></div>
<div data-bg="https://via.placeholder.com/350x150?r=${Math.random()}"></div>
</div>
`
);
},1000);
})
}
.loading{
display:none;
}
[data-bg]{
display: inline-block;
width:70px;
height:70px;
background-position: center;
background-size:cover;
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="load">Loading...</div>
<div id="content" class="loading"></div>
You can also use the waitForImages{[5] plugin]}
1
Author: Ein, 2020-10-09 20:56:04