обратный вызов jQuery при загрузке изображения (даже если изображение кэшируется)
Я хочу сделать:
$("img").bind('load', function() {
// do stuff
});
но событие load не срабатывает, когда изображение загружается из кэша. документы jQuery предлагаю плагин чтобы исправить это, но не работает
14 ответов:
если
srcуже установлен, тогда событие запускается в кэшированном случае, прежде чем вы даже получите привязку обработчика событий. Чтобы исправить это, вы можете выполнить цикл проверки и запуска события на основе off.complete, например:$("img").one("load", function() { // do stuff }).each(function() { if(this.complete) $(this).load(); });обратите внимание на изменение с
.bind()до.one()поэтому обработчик событий не запускается дважды.
могу ли я предложить вам перезагрузить его в объект изображения, отличный от DOM? Если он кэшируется, это не займет много времени, и onload все равно будет срабатывать. Если он не кэшируется, он будет запускать onload при загрузке изображения, что должно быть в то же время, когда версия 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событие непосредственно к вашему изображению, а также;<img src="/path/to/image.jpg" onload="doStuff(this);" />Он будет срабатывать каждый раз, когда изображение загружается из кэша или нет.
У меня просто была эта проблема, я искал везде решение, которое не связано с убийством моего кэша или загрузкой плагина.
Я не сразу увидел эту тему, поэтому вместо этого я нашел что-то еще, что является интересным исправлением и (я думаю) достойным публикации здесь:
$('.image').load(function(){ // stuff }).attr('src', 'new_src');Я на самом деле получил эту идею из комментариев здесь: http://www.witheringtree.com/2009/05/image-load-event-binding-with-ie-using-jquery/
У меня нет идея, почему это работает, но я проверил это на IE7 и где он сломался, прежде чем он теперь работает.
надеюсь, это поможет,
Edit
принятый ответ на самом деле объясняет, почему:
Если 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(); } });
модификация примера Гаса:
$(document).ready(function() { var tmpImg = new Image() ; tmpImg.onload = function() { // Run onload code. } ; tmpImg.src = $('#img').attr('src'); })установите источник до и после onload.
используя jQuery для создания нового изображения с src изображения и назначая метод load непосредственно этому, метод load успешно вызывается, когда jQuery завершает создание нового изображения. Это работает для меня в IE 8, 9 и 10
$('<img />', { "src": $("#img").attr("src") }).load(function(){ // Do something });
просто повторно добавьте аргумент src в отдельной строке после определения объекта img. Это трюк, т. е. на запуск лад-событие. Это некрасиво, но это самый простой обходной путь, который я нашел до сих пор.
jQuery('<img/>', { src: url, id: 'whatever' }) .load(function() { }) .appendTo('#someelement'); $('#whatever').attr('src', url); // trigger .load on IE
Я могу дать вам небольшой совет, если вы хотите сделать так:
<div style="position:relative;width:100px;height:100px"> <img src="loading.jpg" style='position:absolute;width:100px;height:100px;z-index:0'/> <img onLoad="$(this).fadeIn('normal').siblings('img').fadeOut('normal')" src="picture.jpg" style="display:none;position:absolute;width:100px;height:100px;z-index:1"/> </div>Если вы делаете это, когда браузер кэширует изображения, это не проблема всегда img показано, но загрузка img под реальной картинкой.
У меня была эта проблема с IE, где E.target.ширина будет неопределенной. Событие загрузки будет срабатывать, но я не мог получить размеры изображения в IE (chrome + FF работал).
оказывается, вам нужно искать Эл.currentTarget.naturalWidth & Эл.currentTarget.naturalHeight.
еще раз, т. е. делает вещи, это собственный (более сложный) способ.
решение, которое я нашел 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;
Вы можете решить вашу проблему с помощью тюрьмы плагин, который также позволяет лениво загружать изображения (улучшая производительность страницы) и передавать обратный звонок в качестве параметра
$('img').asynchImageLoader({callback : function(){...}});HTML должен выглядеть как
<img name="/global/images/sample1.jpg" src="/global/images/blank.gif" width="width" height="height" />
Если вы хотите чистое решение CSS, этот трюк работает очень хорошо-используйте объект преобразования. Это также работает с изображениями, когда они кэшируются или нет:
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:
<div class="main_container"> <div class="center_horizontally"></div> <div class="center_vertically"></div> <div class="center"></div> </div> </div
Comments