我正在编写一些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 x 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));
}
});
答案 0 :(得分:31)
添加事件侦听器,或让图像通过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" />
答案 1 :(得分:14)
使用jquery data store,您可以定义“已加载”状态。
<img id="myimage" onload="$(this).data('loaded', 'loaded');" src="lolcats.jpg" />
然后在其他地方你可以做到:
if ($('#myimage').data('loaded')) {
// loaded, so do stuff
}
答案 2 :(得分:9)
正确答案是使用event.special.load
如果从浏览器缓存加载图像,则可能无法触发加载事件。为了解释这种可能性,我们可以使用特殊的加载事件,如果图像准备就会立即触发。 event.special.load目前作为插件提供。
根据.load()
上的文档答案 3 :(得分:5)
你想做Allain所说的,但要注意有时候图像会在dom准备好之前加载,这意味着你的加载处理程序不会触发。最好的方法是按照Allain的说法进行操作,但在附加加载程序后用javascript设置图像的src。这样你就可以保证它会被激发。
在可访问性方面,您的网站是否仍适用于没有javascript的用户?你可能想给img标签正确的src,附上你的dom ready处理程序来运行你的js:清除图像src(用css给它一个固定的和高度以防止页面闪烁),然后设置你的img加载处理程序,然后将src重置为正确的文件。这样你就涵盖了所有基础:)
答案 4 :(得分:4)
根据您最初对原始问题的评论之一
$(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,请使用标记来记住加载的图像。
答案 5 :(得分:3)
尝试类似:
$("#photo").load(function() {
alert("Hello from Image");
});
答案 6 :(得分:2)
对此有何评论?
...
doShow = function(){
if($('#img_id').attr('complete')){
alert('Image is loaded!');
} else {
window.setTimeout('doShow()',100);
}
};
$('#img_id').attr('src','image.jpg');
doShow();
...
似乎无处不在......
答案 7 :(得分:2)
有一个名为“imagesLoaded”的jQuery插件,它提供了一种跨浏览器兼容的方法来检查元素的图像是否已被加载。
网站:https://github.com/desandro/imagesloaded/
用于内部有许多图像的容器:
$('container').imagesLoaded(function(){
console.log("I loaded!");
})
该插件很棒:
答案 8 :(得分:2)
我发现这对我有用
document.querySelector("img").addEventListener("load", function() { alert('onload!'); });
信用完全归功于Frank Schwieterman,他评论了接受的答案。我不得不把它放在这里,它太有价值......
答案 9 :(得分:1)
我刚创建了一个jQuery函数来使用jQuerys Deferred Object加载图像,这使得它很容易对加载/错误事件做出反应:
$.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');
});
答案 10 :(得分:1)
此功能根据具有可测量的尺寸检查是否加载了图像。如果在加载了某些图像后执行脚本,此技术非常有用。
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;
};
答案 11 :(得分:0)
我们开发了一个页面,其中加载了许多图像,然后仅在加载图像后执行其他功能。这是一个繁忙的网站,产生了大量的流量。似乎以下简单的脚本几乎适用于所有浏览器:
$(elem).onload = function() {
doSomething();
}
但这是IE9的潜在问题!
我们报告过的唯一浏览器是IE9。我们不感到惊讶吗?似乎解决问题的最佳方法是在定义onload函数之后不将src分配给图像,如下所示:
$(elem).onload = function() {
doSomething();
}
$(elem).attr('src','theimage.png');
似乎IE 9有时不会因任何原因抛出onload
事件。此页面上的其他解决方案(例如Evan Carroll的解决方案)仍无效。逻辑上,它检查了加载状态是否已经成功并触发了该功能,如果它不是,则设置onload处理程序,但即使你这样做,我们在测试中证明图像可以在这两行之间加载因此,js显示未加载到第一行,然后在设置onload处理程序之前加载。
我们发现获得所需内容的最佳方法是在设置onload
事件触发器之前不定义图像的src。
我们最近才停止支持IE8,所以我不能说IE9之前的版本,否则,在网站上使用的所有其他浏览器 - IE10和11以及Firefox,Chrome, Opera,Safari以及人们使用的任何移动浏览器 - 在分配src
处理程序之前设置onload
甚至不是问题。
答案 12 :(得分:0)
我可以完全建议一个纯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 style="background-image:url(https://assets1.ignimgs.com/2019/04/25/avengers-endgame-1280y-1556226255823_1280w.jpg)" class="cover-image">
</div>
<br/>
<div style="background-image:url(https://assets1.ignimgs.com/2019/04/25/avengers-endgame-1280y-1556226255823_1280w.jpg)" class="contain-image">
</div>
答案 13 :(得分:0)
我发现这个简单的解决方案最适合我:
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>
答案 14 :(得分:0)
image.complete 可能是另一种选择 https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/complete