Я пишу Javascript, чтобы изменить размер большого изображения, чтобы оно поместилось в окне браузера пользователя. (К сожалению, я не контролирую размер исходных изображений.)
В HTML будет что-то вроде этого:
<img id="photo"
src="a_really_big_file.jpg"
alt="this is some alt text"
title="this is some title text" />
Есть ли способ определить, было ли загружено src
изображение в img
теге?
Мне это нужно, потому что я сталкиваюсь с проблемой, если $(document).ready()
выполняется до того, как браузер загрузит изображение. $("#photo").width()
и $("#photo").height()
вернет размер заполнителя (альтернативный текст). В моем случае это примерно 134 х 20.
Прямо сейчас я просто проверяю, меньше ли высота фотографии 150, и предполагаю, что если да, то это просто замещающий текст. Но это настоящий взлом, и он сломается, если высота фотографии меньше 150 пикселей (маловероятно в моем конкретном случае) или если высота альтернативного текста больше 150 пикселей (возможно, это произойдет в небольшом окне браузера) .
Изменить: для всех, кто хочет увидеть код:
$(function()
{
var REAL_WIDTH = $("#photo").width();
var REAL_HEIGHT = $("#photo").height();
$(window).resize(adjust_photo_size);
adjust_photo_size();
function adjust_photo_size()
{
if(REAL_HEIGHT < 150)
{
REAL_WIDTH = $("#photo").width();
REAL_HEIGHT = $("#photo").height();
if(REAL_HEIGHT < 150)
{
//image not loaded.. try again in a quarter-second
setTimeout(adjust_photo_size, 250);
return;
}
}
var new_width = . . . ;
var new_height = . . . ;
$("#photo").width(Math.round(new_width));
$("#photo").height(Math.round(new_height));
}
});
Обновление : спасибо за предложения. Существует риск того, что событие не будет запущено, если я установлю обратный вызов для $("#photo").load
события, поэтому я определил событие onLoad непосредственно в теге изображения. Для записи вот код, который я выбрал:
<img id="photo"
onload="photoLoaded();"
src="a_really_big_file.jpg"
alt="this is some alt text"
title="this is some title text" />
Затем в Javascript:
//This must be outside $() because it may get called first
var isPhotoLoaded = false;
function photoLoaded()
{
isPhotoLoaded = true;
}
$(function()
{
//Hides scrollbars, so we can resize properly. Set with JS instead of
// CSS so that page doesn't break with JS disabled.
$("body").css("overflow", "hidden");
var REAL_WIDTH = -1;
var REAL_HEIGHT = -1;
$(window).resize(adjust_photo_size);
adjust_photo_size();
function adjust_photo_size()
{
if(!isPhotoLoaded)
{
//image not loaded.. try again in a quarter-second
setTimeout(adjust_photo_size, 250);
return;
}
else if(REAL_WIDTH < 0)
{
//first time in this function since photo loaded
REAL_WIDTH = $("#photo").width();
REAL_HEIGHT = $("#photo").height();
}
var new_width = . . . ;
var new_height = . . . ;
$("#photo").width(Math.round(new_width));
$("#photo").height(Math.round(new_height));
}
});
max-width
иmax-height
стилем изображения с помощью Javascript? Затем вы избегаете ВСЕГО кода, который вам нужно написать, устанавливая максимальную ширину / высоту равной размеру ширины / высоты области просмотра.max-width
иmax-height
изменить размер. Но это довольно простая задача, на.resize()
самом деле однострочное использование .Ответы:
Либо добавьте прослушиватель событий, либо заставьте изображение объявить о себе с помощью onload. Затем определите размеры оттуда.
<img id="photo" onload='loaded(this.id)' src="a_really_big_file.jpg" alt="this is some alt text" title="this is some title text" />
источник
Используя хранилище данных jquery, вы можете определить состояние «загружено».
<img id="myimage" onload="$(this).data('loaded', 'loaded');" src="lolcats.jpg" />
Тогда в другом месте вы можете сделать:
if ($('#myimage').data('loaded')) { // loaded, so do stuff }
источник
jQuery(this)
вместо этого$(this)
для лучшей совместимости с другими библиотеками (jquery не владеет $), особенно если у вас есть JavaScript в html.Правильный ответ - использовать event.special.load
Согласно документации по .load ()
источник
$.ready
делает. Я собирался предложить просто проверить ширину, но в этом есть свои проблемы, мне очень нравится это решение.Вы хотите сделать то, что сказал Аллен, однако имейте в виду, что иногда изображение загружается до готовности dom, что означает, что ваш обработчик нагрузки не срабатывает. Лучше всего сделать так, как говорит Аллен, но установить src изображения с помощью javascript после присоединения обработчика нагрузки. Таким образом, вы можете гарантировать, что он сработает.
Что касается доступности, будет ли ваш сайт по-прежнему работать для людей без javascript? Вы можете указать тегу img правильный src, прикрепить обработчик dom ready для запуска вашего js: очистить изображение src (установить фиксированное значение и высоту с помощью css, чтобы предотвратить мерцание страницы), затем установите свой обработчик загрузки img, затем сбросьте src на правильный файл. Таким образом вы охватите все базы :)
источник
Согласно одному из недавних комментариев к вашему исходному вопросу
$(function() { $(window).resize(adjust_photo_size); adjust_photo_size(); function adjust_photo_size() { if (!$("#photo").get(0).complete) { $("#photo").load(function() { adjust_photo_size(); }); } else { ... } });
Предупреждение. Этот ответ может вызвать серьезный цикл в IE8 и ниже, потому что img.complete не всегда правильно устанавливается браузером. Если вы должны поддерживать ie8, используйте флаг, чтобы помнить, что изображение загружено.
источник
Попробуйте что-нибудь вроде:
$("#photo").load(function() { alert("Hello from Image"); });
источник
Есть плагин jQuery под названием «imagesLoaded», который предоставляет кроссбраузерный метод проверки, загружены ли изображения элемента.
Сайт: https://github.com/desandro/imagesloaded/
Использование для контейнера, внутри которого много изображений:
$('container').imagesLoaded(function(){ console.log("I loaded!"); })
Плагин отличный:
источник
Есть комментарии по этому поводу?
...
doShow = function(){ if($('#img_id').attr('complete')){ alert('Image is loaded!'); } else { window.setTimeout('doShow()',100); } }; $('#img_id').attr('src','image.jpg'); doShow();
...
Вроде везде работает ...
источник
setTimeout
Я только что создал функцию jQuery для загрузки изображения с помощью отложенного объекта jQuerys, что позволяет очень легко реагировать на событие загрузки / ошибки:
$.fn.extend({ loadImg: function(url, timeout) { // init deferred object var defer = $.Deferred(), $img = this, img = $img.get(0), timer = null; // define load and error events BEFORE setting the src // otherwise IE might fire the event before listening to it $img.load(function(e) { var that = this; // defer this check in order to let IE catch the right image size window.setTimeout(function() { // make sure the width and height are > 0 ((that.width > 0 && that.height > 0) ? defer.resolveWith : defer.rejectWith)($img); }, 1); }).error(function(e) { defer.rejectWith($img); }); // start loading the image img.src = url; // check if it's already in the cache if (img.complete) { defer.resolveWith($img); } else if (0 !== timeout) { // add a timeout, by default 15 seconds timer = window.setTimeout(function() { defer.rejectWith($img); }, timeout || 15000); } // return the promise of the deferred object return defer.promise().always(function() { // stop the timeout timer window.clearTimeout(timer); timer = null; // unbind the load and error event this.off("load error"); }); } });
Применение:
var image = $('<img />').loadImg('http://www.google.com/intl/en_com/images/srpr/logo3w.png') .done(function() { alert('image loaded'); $('body').append(this); }).fail(function(){ alert('image failed'); });
Посмотрите, как это работает: http://jsfiddle.net/roberkules/AdWZj/
источник
error
событие, которое обрабатывается.error(function(e) { defer.rejectWith($img); })
. Если вы посмотрите на jsFiddle, вы увидите, чтоhttp://www.google.com/abc.png not found
текст отображается сразу в панели результатов (не дожидаясь тайм-аута, потому что произошло событие ошибки)file://
ограничении - мне никогда не нужно было связывать изображения с использованием файлового протокола, и я не думаю, что в этом особая необходимость.Эта функция проверяет, загружено ли изображение, исходя из измеримых размеров. Этот метод полезен, если ваш скрипт выполняется после того, как некоторые изображения уже были загружены.
imageLoaded = function(node) { var w = 'undefined' != typeof node.clientWidth ? node.clientWidth : node.offsetWidth; var h = 'undefined' != typeof node.clientHeight ? node.clientHeight : node.offsetHeight; return w+h > 0 ? true : false; };
источник
Я обнаружил, что это сработало для меня
document.querySelector("img").addEventListener("load", function() { alert('onload!'); });
Кредит полностью принадлежит Фрэнку Швитерману, который прокомментировал принятый ответ. Мне пришлось положить это сюда, это слишком ценно ...
источник
Мы разработали страницу, на которую загружалось несколько изображений, а другие функции выполнялись только после загрузки изображения. Это был загруженный сайт, который генерировал много трафика. Похоже, что следующий простой скрипт работал практически во всех браузерах:
$(elem).onload = function() { doSomething(); }
НО ЭТО ПОТЕНЦИАЛЬНАЯ ПРОБЛЕМА ДЛЯ IE9!
ЕДИНСТВЕННЫЙ браузер, о котором мы сообщили о проблемах, - это IE9. Мы не удивлены? Кажется, что лучший способ решить эту проблему - не назначать src изображению до тех пор, пока ПОСЛЕ определения функции onload, например:
$(elem).onload = function() { doSomething(); } $(elem).attr('src','theimage.png');
Кажется, что IE 9 иногда не выдает
onload
событие по какой-либо причине. Другие решения на этой странице (например, решение Эвана Кэрролла) по-прежнему не работали. Логически это проверяет, было ли состояние загрузки уже успешным, и запускает функцию, а если нет, то устанавливает обработчик загрузки, но даже когда вы это делаете, мы продемонстрировали при тестировании, что изображение может загружаться между этими двумя строками js, тем самым отображается не загруженным в первую строку, а затем загружается до того, как будет установлен обработчик загрузки.Мы обнаружили, что лучший способ получить желаемое - не определять src изображения до тех пор, пока вы не установите
onload
триггер события.Мы совсем недавно перестали поддерживать IE8, поэтому я не могу говорить о версиях до IE9, иначе из всех других браузеров, которые использовались на сайте - IE10 и 11, а также Firefox, Chrome, Opera, Safari и т. люди использовали мобильный браузер - установка
src
перед назначениемonload
обработчика даже не была проблемой.источник
Могу я вообще предложить решение на чистом CSS?
Просто имейте Div, в котором вы хотите показать изображение. Установите изображение как фон. Тогда имейте собственность
background-size: cover
или вbackground-size: contain
зависимости от того, как вы этого хотите.cover
будет обрезать изображение до тех пор, пока меньшие стороны не покроют коробку.contain
сохранит все изображение внутри div, оставив вам пробелы по бокам.Посмотрите фрагмент ниже.
div { height: 300px; width: 300px; border: 3px dashed grey; background-position: center; background-repeat: no-repeat; } .cover-image { background-size: cover; } .contain-image { background-size: contain; }
<div class="cover-image" style="background-image:url(https://assets1.ignimgs.com/2019/04/25/avengers-endgame-1280y-1556226255823_1280w.jpg)"> </div> <br/> <div class="contain-image" style="background-image:url(https://assets1.ignimgs.com/2019/04/25/avengers-endgame-1280y-1556226255823_1280w.jpg)"> </div>
источник
Я считаю, что мне лучше всего подходит это простое решение:
function setEqualHeight(a, b) { if (!$(a).height()) { return window.setTimeout(function(){ setEqualHeight(a, b); }, 1000); } $(b).height($(a).height()); } $(document).ready(function() { setEqualHeight('#image', '#description'); $(window).resize(function(){setEqualHeight('#image', '#description')}); }); </script>
источник