15.07.2020, 16:53
|
|
Аспирант
|
|
Регистрация: 04.04.2020
Сообщений: 60
|
|
Как подгружать страницы без перезагрузки на чистом js с прогрессом?
Здравствуйте. Хочу сделать возможность загружать страницы без перезагрузки и чтобы можно было посмотреть прогресс загрузки этой страницы.
Делаю кнопку:
<button onclick="send(event, 'req.html')">Загрузить</button>
И вот такую функцию:
function send(event, html){
console.log("Отправка запроса");
event.preventDefault ? event.preventDefault() : event.returnValue = false;
var req = new XMLHttpRequest();
req.open('POST', html, true);
req.onload = function() {
if (req.status >= 200 && req.status < 400) {
document.querySelector(".result").insertAdjacentHTML("afterbegin", this.response);
} else {alert("Ошибка сервера. Номер: "+req.status);}};
req.onerror = function() {alert("Ошибка отправки запроса");};
req.send();
}
Проблема в том, что req.onprogress отрабатывает только на запрос, а не на содержимое документа. Ведь запрос возвращает мне только текст того документа, а в тексте находятся изображения. Грубо говоря страница req.html выглядит так:
<img src="big1.png" alt="">
<img src="big2.png" alt="">
<img src="big3.png" alt="">
Как можно повесить прогресс на всю страницу из запроса?
Ещё раз повторюсь: весь документ req.html с учётом изображений весит 9мб, а текст документа (что я как раз и получаю) весит несколько килобайт. Прогресс разумеется сразу будет 100% потому что я загружаю лишь килобайты. Как загрузить именно весь документы и получить прогресс загрузки?
Сам этот нативный ajax я брала на просторах форумов. Мне кажется, что там можно что-то изменить и тогда я буду получать именно содержимое документа с объектами в нём, а не просто текст.
|
|
15.07.2020, 17:32
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Событие загрузки документа обрабатывают или его компонентов, в данном случае изображений. А "что там можно что-то изменить и тогда я буду получать именно содержимое документа", это где, в самом ответе? Ну можете не подгружать картинки, а вставить в src их base64, вот только документ ваш при этом будет 27 МБ весить.
|
|
15.07.2020, 20:21
|
|
Аспирант
|
|
Регистрация: 04.04.2020
Сообщений: 60
|
|
laimas,
С чего вы взяли, что размер страницы будет 27мб? Но это не важно, потому что это не вариант.
Я просто представляю это так: идёт запрос > получаем документ > загружаем его в памяти > как только загрузился - отображаем. Пока грузим в памяти - отображаем прогресс.
Просто есть https://github.com/HubSpot/pace , который отображает прогресс бар просто для страницы. Наверняка можно как-то сделать и для подгружаемой страницы.
|
|
15.07.2020, 20:39
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Сообщение от nastya97core
|
С чего вы взяли, что размер страницы будет 27мб?
|
Вы можете получить весь документ (ну или то что запрашиваете у сервера) сразу и с картинками, не заставляя браузер скачивать их отдельно. А значит можете и "нарисовать" прогресс загрузки. Но вставить вы можете картинки как base64, а это значит они будет в 3 раза больше по размеру чем исходные. Поэтому ваши 9МБ * 3 = 27МБ.
Установите обработчик загрузки изображений и отрисовывайте прогресс.
PS. Ну или обрабатывайте как ранее говорилось, событие window onload, рисуя "аля прогресс", как это делается в сети есть, одним словом просто фикция.
Последний раз редактировалось laimas, 15.07.2020 в 20:42.
|
|
15.07.2020, 21:16
|
|
Аспирант
|
|
Регистрация: 04.04.2020
Сообщений: 60
|
|
laimas,
я не нашла в сети XMLHttpRequest и onload изображений
|
|
15.07.2020, 22:11
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
XMLHttpRequest имеет прогресс и его событие никак не связано с событием загрузки изображений. Изображения браузер закачивает через шлюз, и его событие загрузки сообщает о загруженном изображении, но никак не сможет вам сообщить на сколько процентов оно загружено. Собственно и прогресс имеющийся не только у XMLHttpRequest никогда вам не отобразит выполнение от 0 до 100% с шагом 1%.
Получили ответ сервера, пусть это будет 10% от объема, отобразили их, далее обрабатываете загрузку коллекции изображений, добавляя к прогрессу при загрузке каждого проценты зависящие, например, от размера изображения.
|
|
15.07.2020, 22:14
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
А о примерах в сети, я имел ввиду фикцию прогресса загрузки страницы, то есть события window.onload.
|
|
15.07.2020, 22:45
|
|
Аспирант
|
|
Регистрация: 04.04.2020
Сообщений: 60
|
|
laimas,
Допустим. Как в моём случае использовать onload? Куда мне его вешать, чтобы при получении результата и полной его загрузки отрабатывал какой-нибудь console.log("готово")? Я пыталась повесить onload на div в index.html , и onload в подгружаемом элементе - всё безуспешно.
|
|
15.07.2020, 23:24
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Вы же сами определили сценарий - загрузка асинхронная, где малая часть текст, большая часть картинки.
Определили свой, пользовательский, прогресс, "плавность шага" которого пусть будет обеспечиваться css (найдете в сети, есть такое и готовое).
Пусть малая часть, это 10%, остальные 90%, это картинки, и пусть их будет 9.
Сервер ответил, отмечаете на своем прогрессе 10%, далее обрабатываете событие image.onload этих изображений добавляя по каждому этому событию либо по 90/9%, либо проценты определяют размеры изображений, тогда 90%, это 100% размера всех изображений.
А как обрабатывается, это можно посмотреть, найдите в сети "предварительная загрузка изображений, прелоадер и т.п.", и выбирайте вам подходящее.
|
|
16.07.2020, 12:33
|
|
Профессор
|
|
Регистрация: 08.11.2017
Сообщений: 641
|
|
<style>
* {
padding: 0;
margin: 0;
background-color: rgb(255, 237, 213);
}
.progress-bar {
width: 100%;
height: 5px;
box-sizing: border-box;
}
.progress-bar-meter {
background-color: red;
width: 0%;
height: inherit;
transition: width .5s;
}
.lazy-images {
width: 24%;
}
.images {
text-align: center;
}
</style>
<div class="progress-bar">
<div class="progress-bar-meter"></div>
</div>
<div class="images">
<img src="https://cdn.pixabay.com/photo/2020/07/10/22/38/cows-5392356_1280.jpg" class="lazy-images" alt="me" />
<img src="https://cdn.pixabay.com/photo/2020/07/02/08/00/landscape-5362157_1280.jpg" class="lazy-images" alt="me" />
<img src="https://cdn.pixabay.com/photo/2020/07/08/05/31/gray-cat-5382617_1280.jpg" class="lazy-images" alt="me" />
<img src="https://cdn.pixabay.com/photo/2020/07/02/17/29/landscape-5363681_1280.jpg" class="lazy-images" alt="me" />
</div>
<script>
function LazyLoader({ queryImages, queryProgress }) {
let progressLoad = 0;
const lazyImages = document.querySelectorAll(queryImages)
const progressBarMeter = document.querySelector(queryProgress)
const updateProgressBar = () => progressBarMeter.style.width = `${100 / (lazyImages.length / ++progressLoad) || 0}%`
lazyImages.forEach(
lazyImage =>
// lazyImage.naturalWidth > 0 - т.е. уже в кэше
lazyImage.naturalWidth > 0
?
updateProgressBar()
:
new Promise((resolve, reject) => lazyImage.onload = () => resolve(updateProgressBar()))
)
}
document.addEventListener('DOMContentLoaded', function () {
new LazyLoader({
queryImages: 'img.lazy-images',
queryProgress: '.progress-bar-meter'
})
});
</script>
Последний раз редактировалось SuperZen, 16.07.2020 в 12:49.
|
|
|
|