Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 15.07.2020, 16:53
Аватар для nastya97core
Аспирант
Отправить личное сообщение для nastya97core Посмотреть профиль Найти все сообщения от nastya97core
 
Регистрация: 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 я брала на просторах форумов. Мне кажется, что там можно что-то изменить и тогда я буду получать именно содержимое документа с объектами в нём, а не просто текст.
Ответить с цитированием
  #2 (permalink)  
Старый 15.07.2020, 17:32
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Событие загрузки документа обрабатывают или его компонентов, в данном случае изображений. А "что там можно что-то изменить и тогда я буду получать именно содержимое документа", это где, в самом ответе? Ну можете не подгружать картинки, а вставить в src их base64, вот только документ ваш при этом будет 27 МБ весить.
Ответить с цитированием
  #3 (permalink)  
Старый 15.07.2020, 20:21
Аватар для nastya97core
Аспирант
Отправить личное сообщение для nastya97core Посмотреть профиль Найти все сообщения от nastya97core
 
Регистрация: 04.04.2020
Сообщений: 60

laimas,
С чего вы взяли, что размер страницы будет 27мб? Но это не важно, потому что это не вариант.

Я просто представляю это так: идёт запрос > получаем документ > загружаем его в памяти > как только загрузился - отображаем. Пока грузим в памяти - отображаем прогресс.

Просто есть https://github.com/HubSpot/pace , который отображает прогресс бар просто для страницы. Наверняка можно как-то сделать и для подгружаемой страницы.
Ответить с цитированием
  #4 (permalink)  
Старый 15.07.2020, 20:39
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от nastya97core
С чего вы взяли, что размер страницы будет 27мб?
Вы можете получить весь документ (ну или то что запрашиваете у сервера) сразу и с картинками, не заставляя браузер скачивать их отдельно. А значит можете и "нарисовать" прогресс загрузки. Но вставить вы можете картинки как base64, а это значит они будет в 3 раза больше по размеру чем исходные. Поэтому ваши 9МБ * 3 = 27МБ.

Установите обработчик загрузки изображений и отрисовывайте прогресс.

PS. Ну или обрабатывайте как ранее говорилось, событие window onload, рисуя "аля прогресс", как это делается в сети есть, одним словом просто фикция.

Последний раз редактировалось laimas, 15.07.2020 в 20:42.
Ответить с цитированием
  #5 (permalink)  
Старый 15.07.2020, 21:16
Аватар для nastya97core
Аспирант
Отправить личное сообщение для nastya97core Посмотреть профиль Найти все сообщения от nastya97core
 
Регистрация: 04.04.2020
Сообщений: 60

laimas,
я не нашла в сети XMLHttpRequest и onload изображений
Ответить с цитированием
  #6 (permalink)  
Старый 15.07.2020, 22:11
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

XMLHttpRequest имеет прогресс и его событие никак не связано с событием загрузки изображений. Изображения браузер закачивает через шлюз, и его событие загрузки сообщает о загруженном изображении, но никак не сможет вам сообщить на сколько процентов оно загружено. Собственно и прогресс имеющийся не только у XMLHttpRequest никогда вам не отобразит выполнение от 0 до 100% с шагом 1%.

Получили ответ сервера, пусть это будет 10% от объема, отобразили их, далее обрабатываете загрузку коллекции изображений, добавляя к прогрессу при загрузке каждого проценты зависящие, например, от размера изображения.
Ответить с цитированием
  #7 (permalink)  
Старый 15.07.2020, 22:14
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

А о примерах в сети, я имел ввиду фикцию прогресса загрузки страницы, то есть события window.onload.
Ответить с цитированием
  #8 (permalink)  
Старый 15.07.2020, 22:45
Аватар для nastya97core
Аспирант
Отправить личное сообщение для nastya97core Посмотреть профиль Найти все сообщения от nastya97core
 
Регистрация: 04.04.2020
Сообщений: 60

laimas,
Допустим. Как в моём случае использовать onload? Куда мне его вешать, чтобы при получении результата и полной его загрузки отрабатывал какой-нибудь console.log("готово")? Я пыталась повесить onload на div в index.html , и onload в подгружаемом элементе - всё безуспешно.
Ответить с цитированием
  #9 (permalink)  
Старый 15.07.2020, 23:24
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Вы же сами определили сценарий - загрузка асинхронная, где малая часть текст, большая часть картинки.
Определили свой, пользовательский, прогресс, "плавность шага" которого пусть будет обеспечиваться css (найдете в сети, есть такое и готовое).
Пусть малая часть, это 10%, остальные 90%, это картинки, и пусть их будет 9.
Сервер ответил, отмечаете на своем прогрессе 10%, далее обрабатываете событие image.onload этих изображений добавляя по каждому этому событию либо по 90/9%, либо проценты определяют размеры изображений, тогда 90%, это 100% размера всех изображений.
А как обрабатывается, это можно посмотреть, найдите в сети "предварительная загрузка изображений, прелоадер и т.п.", и выбирайте вам подходящее.
Ответить с цитированием
  #10 (permalink)  
Старый 16.07.2020, 12:33
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 642

<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.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как обновить количество товаров в корзине без перезагрузки? giwuf jQuery 0 16.05.2017 12:19
Подмена адреса без перезагрузки страницы MArtyn911 Оффтопик 14 19.07.2013 00:08
Как сохранить выбор сортировки на JS после обновления страницы? deeand Общие вопросы Javascript 5 18.05.2012 16:22
Как сделать смену картинки, типа "до" и "после", без перезагрузки страницы? btstudio Events/DOM/Window 2 23.02.2009 20:43
Автообновление <div> без перезагрузки страницы Antihrist AJAX и COMET 14 28.07.2008 06:06