Piszę trochę JavaScript, aby zmienić rozmiar dużego obrazu, aby zmieścił się w oknie przeglądarki użytkownika. (Niestety nie kontroluję rozmiaru obrazów źródłowych).
Więc coś takiego byłoby w HTML:
<img id="photo"
src="a_really_big_file.jpg"
alt="this is some alt text"
title="this is some title text" />
Czy istnieje sposób, aby sprawdzić, czy src
obraz w img
tagu został pobrany?
Potrzebuję tego, ponieważ mam problem, jeśli $(document).ready()
jest wykonywany przed załadowaniem obrazu przez przeglądarkę. $("#photo").width()
i $("#photo").height()
zwróci rozmiar symbolu zastępczego (tekst alternatywny). W moim przypadku jest to około 134 x 20.
W tej chwili sprawdzam tylko, czy wysokość zdjęcia jest mniejsza niż 150 i zakładam, że jeśli tak, to tylko tekst alternatywny. Ale to niezły hack i zepsuje się, jeśli zdjęcie ma mniej niż 150 pikseli wysokości (mało prawdopodobne w moim przypadku) lub jeśli tekst alternatywny ma więcej niż 150 pikseli wysokości (może się to zdarzyć w małym oknie przeglądarki) .
Edycja: dla każdego, kto chce zobaczyć kod:
$(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));
}
});
Aktualizacja : Dzięki za sugestie. Istnieje ryzyko, że zdarzenie nie zostanie uruchomione, jeśli ustawię wywołanie zwrotne dla $("#photo").load
zdarzenia, więc zdefiniowałem zdarzenie onLoad bezpośrednio w tagu obrazu. Dla przypomnienia, oto kod, z którym skończyłem:
<img id="photo"
onload="photoLoaded();"
src="a_really_big_file.jpg"
alt="this is some alt text"
title="this is some title text" />
Następnie w 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));
}
});
źródło
max-width
imax-height
stylizowaniu obrazu za pomocą JavaScript? W ten sposób unikniesz CAŁEGO kodu, który musiałeś napisać, ustawiając maksymalną szerokość / wysokość na rozmiar szerokości / wysokości widoku.max-width
imax-height
zmienić rozmiar. Ale to dość łatwe zadanie,.resize()
w rzeczywistości jedno liniowiec .Odpowiedzi:
Dodaj detektor zdarzeń lub poproś, aby obraz ogłosił się za pomocą funkcji onload. Następnie ustal wymiary stamtąd.
<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" />
źródło
Korzystając z magazynu danych jquery można zdefiniować stan „załadowany”.
<img id="myimage" onload="$(this).data('loaded', 'loaded');" src="lolcats.jpg" />
Następnie możesz zrobić gdzie indziej:
if ($('#myimage').data('loaded')) { // loaded, so do stuff }
źródło
jQuery(this)
zamiast$(this)
dla lepszej kompatybilności z innymi bibliotekami (jquery nie jest właścicielem $), zwłaszcza gdy masz JavaScript w html.Prawidłową odpowiedzią jest użycie event.special.load
Zgodnie z dokumentacją w .load ()
źródło
$.ready
robi. Miałem zamiar zasugerować sprawdzenie szerokości, ale to ma swoje problemy, naprawdę podoba mi się to rozwiązanie.Chcesz zrobić to, co powiedział Allain, jednak pamiętaj, że czasami obraz ładuje się, zanim dom gotowy, co oznacza, że twój nośnik ładunku nie uruchomi się. Najlepszym sposobem jest zrobienie tego, co mówi Allain, ale ustaw src obrazu za pomocą javascript po dołączeniu modułu obsługi ładowania. W ten sposób możesz zagwarantować, że odpali.
Jeśli chodzi o dostępność, czy Twoja witryna będzie nadal działać dla osób bez javascript? Możesz zechcieć nadać tagowi img poprawne src, dołączyć moduł obsługi gotowej do uruchomienia js: wyczyść obraz src (nadaj mu stałą z i wysokość za pomocą css, aby zapobiec migotaniu strony), a następnie ustaw moduł obsługi ładowania img, następnie zresetuj src do prawidłowego pliku. W ten sposób pokryjesz wszystkie bazy :)
źródło
Zgodnie z jednym z ostatnich komentarzy do Twojego pierwotnego pytania
$(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 { ... } });
Ostrzeżenie Ta odpowiedź może spowodować poważną pętlę w wersji IE8 i wcześniejszych, ponieważ img.complete nie zawsze jest poprawnie ustawiana przez przeglądarkę. Jeśli musisz obsługiwać IE8, użyj flagi, aby zapamiętać, że obraz został załadowany.
źródło
Spróbuj czegoś takiego:
$("#photo").load(function() { alert("Hello from Image"); });
źródło
Istnieje wtyczka jQuery o nazwie „imagesLoaded”, która zapewnia metodę zgodną z różnymi przeglądarkami, aby sprawdzić, czy obrazy elementu zostały załadowane.
Witryna: https://github.com/desandro/imagesloaded/
Użycie dla kontenera, który ma wiele obrazów w środku:
$('container').imagesLoaded(function(){ console.log("I loaded!"); })
Wtyczka jest świetna:
źródło
Jakieś komentarze na ten temat?
...
doShow = function(){ if($('#img_id').attr('complete')){ alert('Image is loaded!'); } else { window.setTimeout('doShow()',100); } }; $('#img_id').attr('src','image.jpg'); doShow();
...
Wygląda na to, że działa wszędzie ...
źródło
setTimeout
Właśnie utworzyłem funkcję jQuery do ładowania obrazu za pomocą jQuerys Deferred Object, co bardzo ułatwia reakcję na zdarzenie ładowania / błędu:
$.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"); }); } });
Stosowanie:
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'); });
Zobacz, jak działa: http://jsfiddle.net/roberkules/AdWZj/
źródło
error
zdarzenie obsługiwane przez.error(function(e) { defer.rejectWith($img); })
. Jeśli spojrzysz na jsFiddle, zobaczysz, żehttp://www.google.com/abc.png not found
tekst jest wyświetlany natychmiast w okienku wyników (nie czeka nafile://
ograniczeniach - nigdy nie musiałem łączyć obrazów za pomocą protokołu pliku i nie sądzę, aby było to zbyt potrzebne.Ta funkcja sprawdza, czy obraz jest załadowany na podstawie mierzalnych wymiarów. Ta technika jest przydatna, jeśli skrypt jest wykonywany po załadowaniu niektórych obrazów.
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; };
źródło
Odkryłem, że to działa dla mnie
document.querySelector("img").addEventListener("load", function() { alert('onload!'); });
Kredyt w całości przypada Frankowi Schwietermanowi, który skomentował zaakceptowaną odpowiedź. Musiałem to tutaj umieścić, jest zbyt cenne ...
źródło
Stworzyliśmy stronę, na której ładowano kilka obrazów, a następnie wykonywaliśmy inne funkcje dopiero po załadowaniu obrazu. To była ruchliwa witryna, która generowała duży ruch. Wygląda na to, że następujący prosty skrypt działał praktycznie na wszystkich przeglądarkach:
$(elem).onload = function() { doSomething(); }
ALE JEST TO POTENCJALNY PROBLEM DLA IE9!
JEDYNA przeglądarka, w której zgłaszaliśmy problemy, to IE9. Czy nie jesteśmy zaskoczeni? Wydaje się, że najlepszym sposobem rozwiązania tego problemu jest nie przypisywanie src do obrazu, dopóki nie zostanie zdefiniowana funkcja onload PO:
$(elem).onload = function() { doSomething(); } $(elem).attr('src','theimage.png');
Wygląda na to, że IE 9 czasami nie wyrzuca pliku
onload
jakiegokolwiek powodu zdarzenia. Inne rozwiązania na tej stronie (na przykład to od Evana Carrolla) nadal nie działały. Logicznie rzecz biorąc, sprawdziliśmy, czy stan ładowania już się powiódł i wyzwolił funkcję, a jeśli nie, to ustaw procedurę obsługi ładowania, ale nawet gdy to zrobisz, zademonstrowaliśmy w testowaniu, że obraz może załadować się między tymi dwoma wierszami js pojawia się jako nie załadowany w pierwszym wierszu, a następnie ładuje się przed ustawieniem modułu obsługi ładowania.Odkryliśmy, że najlepszym sposobem uzyskania tego, czego chcesz, jest nie definiowanie źródła obrazu, dopóki nie ustawisz
onload
wyzwalacza zdarzenia.Dopiero niedawno przestaliśmy wspierać IE8, więc nie mogę mówić o wersjach wcześniejszych niż IE9, w przeciwnym razie ze wszystkich innych przeglądarek używanych w witrynie - IE10 i 11, a także Firefox, Chrome, Opera, Safari i tak dalej przeglądarka mobilna, z której ludzie korzystali - ustawienie
src
przed przypisaniemonload
obsługi nie było nawet problemem.źródło
Czy mogę w ogóle zaproponować czyste rozwiązanie CSS?
Wystarczy mieć element DIV, w którym chcesz wyświetlić obraz. Ustaw obraz jako tło. Następnie masz nieruchomość
background-size: cover
lub wbackground-size: contain
zależności od tego, jak chcesz.cover
przycina obraz, aż mniejsze boki zakryją pudełko.contain
zachowa cały obraz wewnątrz elementu div, pozostawiając spacje po bokach.Sprawdź poniższy fragment.
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>
źródło
Uważam, że to proste rozwiązanie działa najlepiej dla mnie:
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>
źródło