Форум программистов, компьютерный форум, киберфорум
jQuery
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
45 / 6 / 1
Регистрация: 19.02.2013
Сообщений: 149
1

Не отрабатывает .on('load')

12.03.2021, 09:12. Просмотров 1905. Ответов 7
Метки нет (Все метки)


Когда картинка загрузится, нужно запустить определённую функцию (обрезка изображения)
НО! почему-то для картинки не всегда отрабатывает .on('load')

Javascript
1
2
3
4
    $("#pic").on('load',function(){
    console.log("#pic on load");
    }
});
Например, взять страничку
https://dekorimage.ru/3D-foto-... y-biryuza/

бывает сразу отработает, потом F5 - облом, F5 - облом, ctr+F5 - норм
и какой либо закономерности я не нашел

пока обхожу проблему через ready() + setTimeout()
но хотелось бы всё таки более правильно - через .on('load')

help

Добавлено через 1 минуту
предположу - если картинка берётся из кэша браузера то on load не срабатывает ...
но не должно быть такого ведь, тогда каким событием можно отловить подгрузку картинки?

Добавлено через 2 минуты
а вот эта страничка и по ctr+f5 не хочет on load отрабатывать
https://dekorimage.ru/3D-foto-... a-terrasa/

Добавлено через 49 секунд
тестировать можно и без консоли - если полоски на картинке появились, отработало, если нет - облом

Добавлено через 57 минут
пока сделал на "костылях" через ready() + setTimeout()
так что проверить только через консоль -
#pic on load
будет отрабатывать далеко не всегда

буду рад любым предположениям
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.03.2021, 09:12
Ответы с готовыми решениями:

Failed to load resource 403 (Forbidden), Ошибка при загрузке $('.').load(.)
При выполнении скрипта JQuery $('#rezult').load('page.php') у всех пользователей загрузка...

Регулярка findstr отрабатывает на одном файле, но не отрабатывает на другом
Приветствую ! Сижу, ругаюсь матом в голос потому, что регулярка срабатывает на одном текстовом...

Результат запроса отрабатывает в консоли, но не отрабатывает в модуле
Доброго времени суток! Собственно проблема в следующем, есть запрос, который возвращает дату...

Ошибка DevTools failed to load SourceMap: Could not load content for влияет на работу страницы?
Было несколько ошибок DevTools failed to load SourceMap: Could not load content for связанных с...

7
Эксперт JS
5308 / 3068 / 1483
Регистрация: 14.06.2018
Сообщений: 5,822
12.03.2021, 09:20 2
Лучший ответ Сообщение было отмечено GTAlex как решение

Решение

Здравствуйте.
GTAlex, вроде load не глючит тут:
PHP/HTML
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
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <input type="button" id="btn" value="Загрузить">
    <div><img src="" alt=""></div>
    <script>
/**
 * TAP-версия загрузки изображения по HTTP 
 * @param {string} url Строка URL
 * @returns {Promise<HTMLImageElement>} Обещание вернуть элемент-изображение
 */
function loadImgAsync(url) {
    return new Promise((resolve, reject) => {
        let img = document.createElement("img");
        img.onload = () => { resolve(img); };
        img.onerror = (reason) => { reject(new Error("Ошибка загрузки изображения с адреса: " + url)); };
        img.setAttribute("src", url);
    });
};
 
document.querySelector("#btn").onclick = btn_click;
 
async function btn_click() {
    let url = "https://dekorimage.ru/upload/iblock/c24/c24e87409cfc786486cd5f3fe893f3cf.jpg";
    // let url = "https://dekorimage.ru/upload/iblock/596/596c1129512974610c3a281a99f03db2.jpg";
    //let url = "https://cyberstatic.net/images/cyberforum_logo.png";
    try {
        document.querySelector("div img").src = (await loadImgAsync(url)).src;
        console.dir(document.querySelector("div img"));
    }
    catch (error) {
        console.log(error.message);
    }
}
    </script>
</body>
</html>
Прошу потестировать для разных случаев.
1
the hardway first
Эксперт JS
2035 / 1518 / 771
Регистрация: 05.06.2015
Сообщений: 3,178
12.03.2021, 09:24 3
Лучший ответ Сообщение было отмечено GTAlex как решение

Решение

GTAlex, событие load не срабатывает, если изображение взято из кэша браузера. Вы можете проверить атрибут complete и вызвать событие load вручную.
Javascript
1
2
$('#pic').on('load', () => console.log('Img loaded'));
if ($('#pic').prop('complete')) $('#pic').trigger('load');
2
45 / 6 / 1
Регистрация: 19.02.2013
Сообщений: 149
12.03.2021, 11:33  [ТС] 4
Цитата Сообщение от j2FunOnly Посмотреть сообщение
GTAlex, событие load не срабатывает, если изображение взято из кэша браузера. Вы можете проверить атрибут complete и вызвать событие load вручную.
Так ведь и думал! Спасибо!

Добавлено через 4 минуты
Цитата Сообщение от j2FunOnly Посмотреть сообщение
Вы можете проверить атрибут complete и вызвать событие load вручную.
в какой момент проверять то?
я по таймеру через 1000 проверяю - он всегда true независимо из кэша картинка или сама загрузилась

Добавлено через 1 минуту
то есть отработал on load или нет, complete у картинки true

Добавлено через 1 минуту
Javascript
1
2
3
4
    let timerId = setTimeout(function tick() {
    console.log("#pic on timer");
    console.log("prop complete = "+$('#pic').prop('complete'));
    }, 1000);
Добавлено через 1 минуту
по таймеру тоже риск - вдруг после ready через 1000 картинка так и не будет загружена ...
на практике такой вариант без сбоев пашет

а событие если из кэша картинка берётся - так и непонятно как обрабатывать

Добавлено через 1 час 53 минуты
Цитата Сообщение от amr-now Посмотреть сообщение
вроде load не глючит тут
тут не глючит потому, что img тут изначально пустой
в идеале всё же нужен вариант, с возможностью контроля когда img из кэша подгружается
получается ради корректной обработки события жертвуем кэшем, что имхо не есть правильно
0
Эксперт JS
5308 / 3068 / 1483
Регистрация: 14.06.2018
Сообщений: 5,822
12.03.2021, 12:00 5
GTAlex, я сейчас поигрался с кэшированной картинкой.
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <input type="button" id="btn" value="Загрузить">
    <!-- <div><img src="wallpaper.jpg" alt=""></div> -->
    <div><img src="" alt=""></div>
    <script src="scripts/app.js"></script>
</body>
</html>
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
/**
 * TAP-версия загрузки изображения по HTTP
 * @param {string} url Строка URL
 * @returns {Promise<void>} Обещание, не возвращающее результат
 */
function loadImgAsync(img, url) {
    return new Promise((resolve, reject) => {
        img.addEventListener("load", function loadHandler() {
            img.removeEventListener("load", loadHandler);
            resolve();
        });
        img.addEventListener("error", function errorHandler() {
            img.removeEventListener("error", errorHandler);
            reject(new Error("Ошибка загрузки изображения с адреса: " + url));
        });
        img.setAttribute("src", ""); // Сделать, чтобы картинка точно грузилась
        img.setAttribute("src", url);
    });
}
let img = document.querySelector("img");
// img.onload = () => { console.log("Картинка загрузилась. Обрабатываю."); };
console.log(img.complete);
 
document.querySelector("#btn").onclick = btn_click;
 
async function btn_click() {
    let url = "wallpaper.jpg";
    // let url = "https://dekorimage.ru/upload/iblock/c24/c24e87409cfc786486cd5f3fe893f3cf.jpg";
    // let url = "https://dekorimage.ru/upload/iblock/596/596c1129512974610c3a281a99f03db2.jpg";
    //let url = "https://cyberstatic.net/images/cyberforum_logo.png";
    try {
        await loadImgAsync(img, url);
        console.log("Картинка загружена. Обработка.");
    }
    catch (error) {
        console.log(error.message);
    }
}
img из кэша подгружается в любом случае. Кэш у браузера всё равно был. Я проверял на картинке, которую на сервере надо ждать 30 секунд. Браузер второй раз никогда 30 секунд не ждет.

Переделал, что loadImgAsync(img, url) просто ждёт, когда картинка станет загружена.
Дождались, следом можно выполнять любые действия.
Например, console.log("Картинка загружена. Обработка.");

В моём примере механизм загрузки картинки и дальнейшей обработки запускается при нажатии на кнопку.
1
45 / 6 / 1
Регистрация: 19.02.2013
Сообщений: 149
12.03.2021, 12:37  [ТС] 6
Цитата Сообщение от amr-now Посмотреть сообщение
img из кэша подгружается в любом случае. Кэш у браузера всё равно был. Я проверял на картинке, которую на сервере надо ждать 30 секунд. Браузер второй раз никогда 30 секунд не ждет.
вот это уже чистый эксперимент! респект!
пошел адаптировать Ваше решение к себе

PS
Спасибо большое за уделённое Вами время по этому вопросу!

Добавлено через 12 минут
в этой строчке смысла всё же нет - поставил её ещё до вызова загрузки - true пишет
Javascript
1
console.log(img.complete);
Добавлено через 1 минуту
прикольно, что Вы всё на чистом Javascript сделали - красиво!
я к JQuery прилип нужно отлипать

Добавлено через 7 минут
что интересно - с Вашим загрузчиком изображения и обычный on load стал работать как часы!

Добавлено через 25 секунд
уфф ... костыль с таймером убрал

Добавлено через 6 минут
с трудом понимаю логику работы
сначала addEventListener ("load")
тут же в нём removeEventListener ...

смысл понимаю, но детали работы нет
1
Эксперт JS
5308 / 3068 / 1483
Регистрация: 14.06.2018
Сообщений: 5,822
12.03.2021, 13:02 7
Цитата Сообщение от GTAlex Посмотреть сообщение
сначала addEventListener ("load")
тут же в нём removeEventListener ...
Навесить слушателя. Когда событие load произошло, выполняется слушатель. При выполнении он удаляет себя из списка слушателей события load.
Там же можно было и слушателя error удалить. Ошибки то уже не было.

Добавлено через 6 минут
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
/**
 * TAP-версия загрузки изображения по HTTP 
 * @param {HTMLImageElement} img HTML-элемент изображения
 * @param {string} url Строка URL
 * @returns {Promise<void>} Обещание, не возвращающее результат
 */
function loadImgAsync(img: HTMLImageElement, url: string): Promise<void> {
    return new Promise((resolve, reject) => {
        function loadHandler() {
            img.removeEventListener("load", loadHandler);
            img.removeEventListener("error", errorHandler);
            resolve();
        }
        function errorHandler() {
            img.removeEventListener("load", loadHandler);
            img.removeEventListener("error", errorHandler);
            reject(new Error("Ошибка загрузки изображения с адреса: " + url));
        }
        img.addEventListener("load", loadHandler);
        img.addEventListener("error", errorHandler);
        img.setAttribute("src", ""); // Сделать, чтобы картинка точно грузилась
        img.setAttribute("src", url);
    });
}
Спасибо за наводку. Обработчики нельзя оставлять живыми, если на одну <img> собираетесь вешать тысячу url.
0
45 / 6 / 1
Регистрация: 19.02.2013
Сообщений: 149
12.03.2021, 13:50  [ТС] 8
Цитата Сообщение от amr-now Посмотреть сообщение
Там же можно было и слушателя error удалить. Ошибки то уже не было.
да, точно - удалю!
На продакшене он явно уже не нужен, если и ошибка будет - пусть это будет незаметно, без криков

Добавлено через 33 минуты
Цитата Сообщение от amr-now Посмотреть сообщение
Спасибо за наводку. Обработчики нельзя оставлять живыми, если на одну <img> собираетесь вешать тысячу url.
ну это если совместно с load error использовать ... я просто error убрал и всё корректненько стало
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.03.2021, 13:50

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

Запуск Load.dll (бывшая Load.exe) в дереве проц-ов, Как запустить прогой на C# .dll-ку
Подскажите, как должен выглядеть код простейшей программы на C# (Loader.exe), которая бы загружала...

Не отрабатывает if
//--------------------------------------------------------------------------- #include &lt;vcl.h&gt;...

Не отрабатывает try
всем привет. может кто подсказать что не так в коде: kod := edit1.Text; org :=...

Не отрабатывает Replace
Код не работаетDim strQuery as String strQuery=Replace(TextBox1.text,&quot;*&quot;,&quot;%&quot;) Код работаетDim...

не отрабатывает условие
подскажите где ошибся SELECT DISTINCT(mo.id) as ido, mo.userid as usi FROM...

Не отрабатывает цикл
Всем привет. Нужна очень помощь. Есть цикл ю Который не отрабатывает с таким условием For...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.