С Новым годом! Форум программистов, компьютерный форум, киберфорум
JavaScript для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
Заблокирован

Отложенная загрузка изображений

08.04.2020, 03:59. Показов 1059. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
-Необходимо чтобы изображения указывались в теге scr, на тот случай. Когда js отключен и пользователь получит контент как обычно.
-Необходимо чтобы изображения подгружались по порядку, а не все что в окне видимости.
-Необходимо чтобы изображения подгружались при прокрутки срола.

Имеется ли готовое решение, что та все не то в нете. Либо заморочено с кодом, либо работает не так.

Быть может проще свой код написать, вопрос в том как заблокировать подгрузку изображений браузером, затем начать поочередно подгружать по мере загрузки предыдущего и самое сложное. Как определить видимость контента при скролинге, так чтобы начать подгружать чуть раньше чем блок появится в поле видимости.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.04.2020, 03:59
Ответы с готовыми решениями:

Загрузка изображений
Всем доброго времени суток. У меня вопрос касательно загрузки картинок на сайт. Как сделать так, чтобы при открытии страницы с множеством...

Отложенная загрузка изображений
Здравствуйте форумчане. Не подскажете дельный совет, как лучше организовать отложенную загрузку изображений на сайте? Идея такая, что при...

Загрузка изображений
Доброго времени суток. Подскажите как сделать загрузку картинок, что бы при выборе картинок было видно привью.

12
 Аватар для D_Vik
368 / 234 / 68
Регистрация: 19.07.2016
Сообщений: 833
08.04.2020, 06:48
Вы можете попробовать решить задачу с помощью IntersectionObserver .
0
Заблокирован
08.04.2020, 16:20  [ТС]
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
        document.addEventListener('DOMContentLoaded', function() {
            const imageObserver = new IntersectionObserver((entries, imgObserver) => {
                entries.forEach((entry) => {
                    if (entry.isIntersecting) {
                        const lazyImage = entry.target
                        console.log('lazy loading ', lazyImage)
                        lazyImage.src = lazyImage.dataset.src
                        lazyImage.classList.remove('lzy_img');
                        imgObserver.unobserve(lazyImage);
                    }
                })
            });
            document.querySelectorAll('img.lzy_img').forEach((v) => {
                imageObserver.observe(v);
            })
        })
</script>
Нашел данное, что та не совсем понимаю.


Скажите как изначально заблокировать загрузку изображений браузером? А затем в цикле давать старт загрузке изображений в порядке очереди...?
0
 Аватар для D_Vik
368 / 234 / 68
Регистрация: 19.07.2016
Сообщений: 833
08.04.2020, 16:42
Этот скрипт (немного подправить) загрузит стартовую картинку в списке, если она попадает в область видимости браузера. Каждая следующая, загрузится при прокрутке, когда попадет в область видимости.

Добавлено через 11 минут
Не совсем понятно, как у вас рисуются картинки. Если у вас блок, в котором нужно рисовать картинки по одной и при прокрутке показывать новый блок и в нем рисовать следующие картинки, то с помощью этого скрипта вы можете установить обсервер на блок, и не изменять src картинки сразу, а запустить функцию которая нарисует картинки в видимом блоке.
0
Заблокирован
09.04.2020, 03:32  [ТС]
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
        
 
 document.addEventListener('DOMContentLoaded', function() {
    function loadimg (msl) {
        //v.onload = function(){
                
                //}
                
                //v.onerror = function(){
                        
                //}
    }
            
      let ms = msl = [];
      const imageObserver = new IntersectionObserver((entries, imgObserver) => {
           entries.forEach((entry, i) => {
                 if (entry.isIntersecting) {
                       const lazyImage = entry.target
                       lazyImage.src   = ms[i];
                       msl[i]  = i;
                       loadimg (msl);
                       imgObserver.unobserve(lazyImage);    
                  } else if(msl[ii])
                            delete msl[ii];
           })
      });
 
      document.querySelectorAll('img').forEach((v, i) => {
            if(!v.complete){
                  ms[i] = v.src;
                  v.src = '';
                  imageObserver.observe(v);
            }
      })
})
Хорошо, собираем массив изображений которых нет в кэше. Затем чистим атрибут и следим, когда изображение попадает в поле видимости, меняем атрибут из массива, тем самым подгружаем. Но необходима последовательность. К примеру 10 изображений на виду, из них одно загружается быстрее то что в конце, другое медленней, что в начале.

Как выполнить таким образом, чтобы отследить загрузку первого, по завершению загрузки изображения подгрузить последующее. Как то не так начал с этими массивами...

Во первых путаница, можно добавить атрибут и из него брать ссылку(не желательно). Затем еще один создается массив и тут же удаляются элементы из массива если их нет в поле видимости.

Собрался через функцию запускать, в общем. Что та не то делаю, как проще это выполнить?

Добавлено через 1 час 43 минуты
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            let bl = true;
            const imageObserver = new IntersectionObserver((entries, imgObserver) => {
                entries.forEach((entry, i) => {
                    if (entry.isIntersecting) {
                        if(bl) {
                            const lazyImage = entry.target
                            lazyImage.src   = lazyImage.dataset.src;
                            lazyImage.onload = function(){              
                                bl = true;
                            }
                            lazyImage.onerror = function(){
                                bl = true;
                            }
                        }
                        bl = false;
                
                        imgObserver.unobserve(lazyImage);
                    }
                })
            });
            
            document.querySelectorAll('img').forEach((v) => {
                if(!v.complete){
                    v.dataset.src = v.src;
                    v.src = '';
                    imageObserver.observe(v);
                }
            })  
        })  
    </script>
Как выстроить таким образом, чтобы последующие изображения загружались по итогу загрузки предыдущего?

Не работает...
0
 Аватар для D_Vik
368 / 234 / 68
Регистрация: 19.07.2016
Сообщений: 833
09.04.2020, 05:39
Я так понимаю, вы хотите добиться такого эффекта ? :

HTML5
1
2
3
4
5
<body>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
</body>
CSS
1
2
3
4
5
.block {
  width: 600px;
  min-height: 650px;
  margin: 0 auto;
}
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
const config = {
  rootMargin: '0px',
  threshold: 0
}
 
const images = [
  { path: '/img/1.webp' },
  { path: '/img/2.webp' },
  { path: '/img/3.webp' },
  { path: '/img/4.webp' },
  { path: '/img/5.webp' }
]
 
let observer = new IntersectionObserver(function (entries, self) {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      display(entry.target, images)
      self.unobserve(entry.target)
    }
  })
}, config)
 
 
function timer(ms) {
  return new Promise(res => setTimeout(res, ms))
}
 
async function display(target, images) {
  for (let i = 0; i < images.length; i++) {
    const tag = document.createElement('img')
    tag.src = images[i].path
    target.append(tag)
    await timer(2000)
  }
}
 
const blocks = document.querySelectorAll('.block')
 
blocks.forEach(block => {
  observer.observe(block)
})
Добавлено через 46 минут
Таймер вы можете переписать как нибудь так :

JavaScript
1
2
3
4
5
function timer(tag) {
  return new Promise((resolve) => {
    tag.onload = () => resolve()
  })
}
и в нее передать текущий загружаемый тег из функции display.
0
Заблокирован
09.04.2020, 18:54  [ТС]
Таймер не то, изображение может загрузиться быстрее тайма, пользователю в таком случаи придется ожидать пока тайм истечет чтобы начать подгрузку следующего.

Так возможно поймать сигнал когда изображение подгрузилось. Но как сделать так, чтобы приостановить загрузку сдующих пока сигнал не сработал?
JavaScript
1
2
3
tag.onload = function(){              
          
}
0
 Аватар для D_Vik
368 / 234 / 68
Регистрация: 19.07.2016
Сообщений: 833
09.04.2020, 19:10
Не совсем понимаю, что за сигнал ?

Добавлено через 5 минут
Я написал как определить (примерно) что изображение загрузилось. tag.onload вернёт resolve, сообщение что картинка загрузилась и можно продолжить.
0
Заблокирован
09.04.2020, 20:07  [ТС]
Не понимаю, можно на моем примере?
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?php
 
$time = 221122421;
 
echo "
<body>
    <img src='/kamni.webp?t=".($time+1522)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+144)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+122)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+1)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+2)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+3)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+4)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+5)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+6)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+7)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+8)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+9)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+10)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+11)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+12)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+13)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+15)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+16)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+17)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+18)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+19)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+20)."' style='height: 200px;'/>
    <img src='/kamni.webp?t=".($time+21)."' style='height: 200px;'/>        
</body>
 
<script>
 
let mas = [],
observer = new IntersectionObserver(function (entries, self) {
  entries.forEach((entry, i) => {
    if (entry.isIntersecting) {
        mas[i] = entry.target.dataset.src;
        display(entry.target, mas)
        self.unobserve(entry.target)
    }
  })
}, {rootMargin: '0px 0px 10px 0px', threshold: 0})
 
 
function timer(ms) {
  return new Promise(res => setTimeout(res, ms))
}
 
async function display(target, mas) {
   for (let i = 0; i < mas.length; i++) {
    target.src = mas[i];
    await timer(2000)
  }
}
 
document.querySelectorAll('img').forEach(v => {
    if(!v.complete){
        v.dataset.src = v.src;
        v.src = '';
        observer.observe(v);
    }
})
</script>";
В вашем случаи последующие изображения загружаются только по истечению 2 секунд. Зачем тут таймер? Как быть в тех случаях, с теми изображениями которые загружаются менее чем за 300 миллесекунда?

Мы можем поймать событие когда изображение подгрузилось, следовательно можем подгрузить последующее. Только как это совместить с IntersectionObserver?

У меня каждые 2 секунды скрипт меняет url у каждой секуды. Таймер тут явно лишний...
0
 Аватар для D_Vik
368 / 234 / 68
Регистрация: 19.07.2016
Сообщений: 833
09.04.2020, 20:57
Вы не внимательно прочитали мое сообщение. Я же переписал таймер. Он ждёт пока картинка загрузится и разрешает циклу вставить следующее изображение в dom.И так пока цикл не завершится. Но в этом варианте, если у клиента будет отключен js в браузере, картинки не загрузится. Но так же, слепой парсер не сможет украсть картинки. Скопируйте полностью мой пример, запустите у себя и посмотрите как оно работает.
0
 Аватар для CyberPaladin
18 / 16 / 8
Регистрация: 27.05.2017
Сообщений: 118
09.04.2020, 21:38
Gerd199, а почему бы не использовать встроенные возможности браузера, для начала - укажите новый атрибут для тега <img> loading="lazy"
Так:
HTML5
1
2
<img align="center" src="celebration.jpg" loading="lazy" alt="..." />
<iframe src="video-player.html" loading="lazy"></iframe>
Если вам не нужна поддержка старых браузеров конечно...

Добавлено через 42 секунды
https://habr.com/ru/company/ruvds/blog/448914/
1
Заблокирован
09.04.2020, 23:44  [ТС]
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
let observer = new IntersectionObserver(function (entries, self) {
  entries.forEach((entry, i) => {
    if (entry.isIntersecting) {
        display(entry.target);
        self.unobserve(entry.target)
    }
  })
}, {rootMargin: '0px 0px 200px 0px', threshold: 0})
 
 
function timer(tag) {
  return new Promise((resolve) => {
    tag.onload = () => resolve()
  })
}
 
async function display(target) {
    target.src = target.dataset.src;
    await timer(2000)
}
 
document.querySelectorAll('img').forEach(v => {
    if(!v.complete){
        v.dataset.src = v.src;
        v.src = '';
        observer.observe(v);
    }
})
Что та в моем случаи не работает последовательность. И с чего то блокирует скролл если прокручивать страницу не по колесику.

Добавлено через 3 минуты
loading="lazy"
Работает, охота чтобы была последовательность подгрузки изображений. Не сразу все изображения в поле видимости.
0
 Аватар для D_Vik
368 / 234 / 68
Регистрация: 19.07.2016
Сообщений: 833
10.04.2020, 04:48
В общем вы мне надоели. Мало того что у вас с фантазией проблема, так вы ещё не можете внимательно смотреть что написано. На мазила девелопер есть описание этого api, в перед и с песней.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.04.2020, 04:48
Помогаю со студенческими работами здесь

Загрузка изображений
Всем привет! Подскажите как правильно организовать. Есть доска объявлений http://board.paradiseholdingsl.com/ Вопрос в том, что в...

Загрузка изображений
Здравствуйте, имеется такой код. var...

Загрузка изображений в Canvas
Всем доброго времени суток :) Есть задача: Сделать в интерфейсе один &lt;input type=&quot;file&quot;/&gt; и один &lt;canvas&gt; Из input...

Загрузка изображений jquery
Здравствуйте, скачал скрипт массовой загрузки файлов с предпросмотром. С помощью скрипта выбирау картинки но при отправки на скрипт...

Загрузка изображений в lightbox
Привет! Сделала на бутстрапе галерею, присоединила к иконкам lightbox , подсоединила скрипт &lt;script src=&quot;&lt;?php...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru