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

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

08.04.2020, 03:59. Показов 1085. Ответов 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
Ответ Создать тему
Новые блоги и статьи
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru