Обратный вызов jQuery при загрузке изображения (даже при кэшировании изображения)

Я хочу делать:

$("img").bind('load', function() { // do stuff }); 

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

14 Solutions collect form web for “Обратный вызов jQuery при загрузке изображения (даже при кэшировании изображения)”

Если src уже установлен, событие запускается в кэшированном случае, прежде чем вы получите привязку обработчика события. Чтобы исправить это, вы можете выполнить проверку и запуск события на основе .complete , например:

 $("img").one("load", function() { // do stuff }).each(function() { if(this.complete) $(this).load(); }); 

Обратите внимание на изменение с .bind() на .one() чтобы обработчик события не запускался дважды.

Могу ли я предложить перезагрузить его в объект изображения, отличного от DOM? Если он кэширован, это совсем не займет времени, и он будет продолжать работать. Если он не кэширован, он будет запускать загрузку при загрузке изображения, которое должно совпадать с тем, как версия DOM изображения заканчивается загрузкой.

Javascript:

 $(document).ready(function() { var tmpImg = new Image() ; tmpImg.src = $('#img').attr('src') ; tmpImg.onload = function() { // Run onload code. } ; }) ; 

Обновлено (для обработки нескольких изображений и с правильно упорядоченным приложением onload):

 $(document).ready(function() { var imageLoaded = function() { // Run onload code. } $('#img').each(function() { var tmpImg = new Image() ; tmpImg.onload = imageLoaded ; tmpImg.src = $(this).attr('src') ; }) ; }) ; 

Мое простое решение, ему не нужен внешний плагин, и для обычных случаев должно быть достаточно:

 /** * Trigger a callback when the selected images are loaded: * @param {String} selector * @param {Function} callback */ var onImgLoad = function(selector, callback){ $(selector).each(function(){ if (this.complete || /*for IE 10-*/ $(this).height() > 0) { callback.apply(this); } else { $(this).on('load', function(){ callback.apply(this); }); } }); }; 

используйте его вот так:

 onImgLoad('img', function(){ // do stuff }); 

например, для постепенного исчезновения ваших изображений при загрузке, которые вы можете сделать:

 $('img').hide(); onImgLoad('img', function(){ $(this).fadeIn(700); }); 

Или как альтернатива, если вы предпочитаете подход, похожий на jquery:

 /** * Trigger a callback when 'this' image is loaded: * @param {Function} callback */ (function($){ $.fn.imgLoad = function(callback) { return this.each(function() { if (callback) { if (this.complete || /*for IE 10-*/ $(this).height() > 0) { callback.apply(this); } else { $(this).on('load', function(){ callback.apply(this); }); } } }); }; })(jQuery); 

и использовать его таким образом:

 $('img').imgLoad(function(){ // do stuff }); 

например:

 $('img').hide().imgLoad(function(){ $(this).fadeIn(700); }); 

Вам действительно нужно это делать с помощью jQuery? Вы можете прикрепить событие onload непосредственно к своему изображению;

  

Он будет запускаться каждый раз, когда изображение загружается из кеша или нет.

У меня просто была проблема, я искал везде решение, которое не предполагало убийство моего кеша или загрузку плагина.

Я не видел эту нить сразу, поэтому я нашел что-то другое, а это интересное исправление и (я думаю), достойное публикации здесь:

 $('.image').load(function(){ // stuff }).attr('src', 'new_src'); 

Я получил эту идею от комментариев здесь: http://www.witheringtree.com/2009/05/image-load-event-binding-with-ie-using-jquery/

Я понятия не имею, почему это работает, но я тестировал это на IE7 и где он сломался, прежде чем он теперь работает.

Надеюсь, поможет,

редактировать

Принятый ответ на самом деле объясняет, почему:

Если src уже установлен, событие запускается в кеш-кеш, прежде чем вы получите привязку обработчика события.

Вы также можете использовать этот код с поддержкой ошибки загрузки:

 $("img").on('load', function() { // do stuff on success }) .on('error', function() { // do stuff on smth wrong (error 404, etc.) }) .each(function() { if(this.complete) { $(this).load(); } else if(this.error) { $(this).error(); } }); 

Модификация примера GUS:

 $(document).ready(function() { var tmpImg = new Image() ; tmpImg.onload = function() { // Run onload code. } ; tmpImg.src = $('#img').attr('src'); }) 

Установите источник до и после загрузки.

Используя jQuery для генерации нового изображения с помощью src изображения и непосредственного назначения метода загрузки, метод загрузки успешно вызывается, когда jQuery заканчивает создание нового изображения. Это работает для меня в IE 8, 9 и 10

 $('', { "src": $("#img").attr("src") }).load(function(){ // Do something }); 

Просто повторно добавьте аргумент src в отдельной строке после определения значения img. Это приведет к запуску IE в запуске lad-event. Это уродливо, но это простейший обходной путь, который я нашел до сих пор.

 jQuery('', { src: url, id: 'whatever' }) .load(function() { }) .appendTo('#someelement'); $('#whatever').attr('src', url); // trigger .load on IE 

Я могу дать вам небольшой совет, если вы хотите сделать так:

 

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

У меня была эта проблема с IE, где e.target.width не была бы определена. Событие загрузки будет срабатывать, но я не смог бы получить размеры изображения в IE (chrome + FF работал).

Оказывается, вам нужно искать e.currentTarget.naturalWidth & e.currentTarget.naturalHeight .

И снова IE делает вещи своими собственными (более сложными) способами.

Решение, которое я нашел https://bugs.chromium.org/p/chromium/issues/detail?id=7731#c12 (Этот код был получен непосредственно из комментария)

 var photo = document.getElementById('image_id'); var img = new Image(); img.addEventListener('load', myFunction, false); img.src = 'http://newimgsource.jpg'; photo.src = img.src; 

Вы можете решить свою проблему с помощью JAIL- плагина, который также позволяет вам ленить загружать изображения (улучшая производительность страницы) и передавать обратный вызов в качестве параметра

 $('img').asynchImageLoader({callback : function(){...}}); 

HTML должен выглядеть так:

  

Если вы хотите использовать чистое решение CSS, этот трюк работает очень хорошо – используйте объект transform. Это также работает с изображениями, когда они кэшированы или нет:

CSS:

 .main_container{ position: relative; width: 500px; height: 300px; background-color: #cccccc; } .center_horizontally{ position: absolute; width: 100px; height: 100px; background-color: green; left: 50%; top: 0; transform: translate(-50%,0); } .center_vertically{ position: absolute; top: 50%; left: 0; width: 100px; height: 100px; background-color: blue; transform: translate(0,-50%); } .center{ position: absolute; top: 50%; left: 50%; width: 100px; height: 100px; background-color: red; transform: translate(-50%,-50%); } 

HTML:

 

Пример Codepen

Пример Codepen LESS

Interesting Posts

Как остановить перезапуск Windows 8; «15 минут» и подсчет …?

Как отключить создание .Spotlight-V100 и .Trash папок на внешнем диске?

«Адрес получателя отклонен» при отправке электронной почты с помощью sendgrid

Как запустить функцию bash_profile из файла псевдонимов desktop .command на OSX Lion?

Нет кнопки «Новая папка» в окнах 7

Как изменить IP-адрес, чтобы указать на localhost?

Отменить новое поведение на вкладке в Google Chrome 29+

Когда ssh'ing, как я могу установить переменную среды на сервере, которая изменяется от сеанса к сеансу?

Как исправить черные линии на ЖК-дисплее ноутбука, которые становятся длиннее?

Документ Microsoft Office «заблокирован для редактирования« другим пользователем »»

Как использовать точный путь в диалоговом окне открытия файла Mac OS X?

Ограниченные проблемы с подключением в сети, нужна помощь в устранении основной причины

Почему UAC запрашивает пароль вместо yes / no?

Как игнорировать все орфографические ошибки в документе Word 2013?

Как преодолеть доступ Отказано при убийстве в Windows?

Давайте будем гением компьютера.