我正在创建一个 jQuery 插件。
如何在 Safari 中使用 Javascript 获取真实的图像宽度和高度?
以下适用于 Firefox 3、IE7 和 Opera 9:
var pic = $("img")
// need to remove these in of case img-element has set width and height
pic.removeAttr("width");
pic.removeAttr("height");
var pic_real_width = pic.width();
var pic_real_height = pic.height();
但在 Safari 和 Google Chrome 等 Webkit 浏览器中,值为 0。
Webkit 浏览器在加载图像后设置 height 和 width 属性。我建议不要使用超时,而是使用图像的 onload 事件。这是一个简单的例子:
var img = $("img")[0]; // Get my img elem
var pic_real_width, pic_real_height;
$("<img/>") // Make in memory copy of image to avoid css issues
.attr("src", $(img).attr("src"))
.load(function() {
pic_real_width = this.width; // Note: $(this).width() will not
pic_real_height = this.height; // work for in memory images.
});
为了避免 CSS 可能对图像尺寸产生任何影响,上面的代码在内存中创建了图像的副本。这是 FDisk 提出的一个非常聪明的解决方案。
您还可以使用 naturalHeight
和 naturalWidth
HTML5 属性。
使用 HTML5 中的 naturalHeight
和 naturalWidth
属性。
例如:
var h = document.querySelector('img').naturalHeight;
适用于 IE9+、Chrome、Firefox、Safari 和 Opera (stats)。
function getOriginalWidthOfImg(img_element) {
var t = new Image();
t.src = (img_element.getAttribute ? img_element.getAttribute("src") : false) || img_element.src;
return t.width;
}
您不需要从图像或图像尺寸属性中删除样式。只需使用 javascript 创建一个元素并获取创建的对象宽度。
Image
对象,然后查看它的 width
属性。这是一种简单、优雅的方法。 FDisk,你有我的投票权。 :)
window.onload
之前调用此代码,则可能会返回 0 的宽度。
在接受的答案中有很多关于如果从 WebKit 缓存加载图像时不会触发 onload
事件的问题的讨论。
在我的例子中,onload
触发缓存图像,但高度和宽度仍然为 0。一个简单的 setTimeout
为我解决了这个问题:
$("img").one("load", function(){
var img = this;
setTimeout(function(){
// do something based on img.width and/or img.height
}, 0);
});
我无法解释为什么即使从缓存加载图像(jQuery 1.4/1.5 的改进?)也会触发 onload
事件 - 但如果您仍然遇到此问题,可能是我的回答和var src = img.src; img.src = ""; img.src = src;
技术将起作用。
(请注意,出于我的目的,我不关心图像的属性或 CSS 样式中的预定义尺寸 - 但您可能希望按照 Xavi 的回答删除这些尺寸。或者克隆图像。)
根本问题是 WebKit 浏览器(Safari 和 Chrome)并行加载 JavaScript 和 CSS 信息。因此,JavaScript 可能在计算 CSS 的样式效果之前执行,返回错误的答案。在 jQuery 中,我发现解决方案是等到 document.readyState == 'complete', .eg,
jQuery(document).ready(function(){
if (jQuery.browser.safari && document.readyState != "complete"){
//console.info('ready...');
setTimeout( arguments.callee, 100 );
return;
}
... (rest of function)
就宽度和高度而言...取决于您在做什么,您可能需要 offsetWidth 和 offsetHeight,其中包括边框和填充等内容。
$(window).load(function(){ ... });
对我有帮助
通过从 window.onload
事件中触发,这对我有用(safari 3.2):
$(window).load(function() {
var pic = $('img');
pic.removeAttr("width");
pic.removeAttr("height");
alert( pic.width() );
alert( pic.height() );
});
您可以使用 Javascript 以编程方式获取图像并检查尺寸,而完全不必弄乱 DOM。
var img = new Image();
img.onload = function() {
console.log(this.width + 'x' + this.height);
}
img.src = 'http://www.google.com/intl/en_ALL/images/logo.gif';
image.naturalHeight
和 image.naturalWidth
属性呢?
似乎在 Chrome、Safari 和 Firefox 中的很多版本都可以正常工作,但在 IE8 甚至 IE9 中根本不行。
Jquery 有两个属性叫做 naturalWidth 和 naturalHeight,你可以这样使用。
$('.my-img')[0].naturalWidth
$('.my-img')[0].naturalHeight
其中 my-img 是用于选择我的图像的类名。
naturalWidth
(和高度)是图像元素对象的属性。 developer.mozilla.org/en/docs/Web/API/HTMLImageElement
我们如何在不闪烁真实图像的情况下获得正确的真实尺寸:
(function( $ ){
$.fn.getDimensions=function(){
alert("First example:This works only for HTML code without CSS width/height definition.");
w=$(this, 'img')[0].width;
h=$(this, 'img')[0].height;
alert("This is a width/height on your monitor: " + $(this, 'img')[0].width+"/"+$(this, 'img')[0].height);
//This is bad practice - it shows on your monitor
$(this, 'img')[0].removeAttribute( "width" );
$(this, 'img')[0].removeAttribute( "height" );
alert("This is a bad effect of view after attributes removing, but we get right dimensions: "+ $(this, 'img')[0].width+"/"+$(this, 'img')[0].height);
//I'am going to repare it
$(this, 'img')[0].width=w;
$(this, 'img')[0].height=h;
//This is a good practice - it doesn't show on your monitor
ku=$(this, 'img').clone(); //We will work with a clone
ku.attr( "id","mnbv1lk87jhy0utrd" );//Markup clone for a final removing
ku[0].removeAttribute( "width" );
ku[0].removeAttribute( "height" );
//Now we still get 0
alert("There are still 0 before a clone appending to document: "+ $(ku)[0].width+"/"+$(ku)[0].height);
//Hide a clone
ku.css({"visibility" : "hidden",'position':'absolute','left':'-9999px'});
//A clone appending
$(document.body).append (ku[0]);
alert("We get right dimensions: "+ $(ku)[0].width+"/"+$(ku)[0].height);
//Remove a clone
$("#mnbv1lk87jhy0utrd").remove();
//But a next resolution is the best of all. It works in case of CSS definition of dimensions as well.
alert("But if you want to read real dimensions for image with CSS class definition outside of img element, you can't do it with a clone of image. Clone method is working with CSS dimensions, a clone has dimensions as well as in CSS class. That's why you have to work with a new img element.");
imgcopy=$('<img src="'+ $(this, 'img').attr('src') +'" />');//new object
imgcopy.attr( "id","mnbv1lk87jhy0aaa" );//Markup for a final removing
imgcopy.css({"visibility" : "hidden",'position':'absolute','left':'-9999px'});//hide copy
$(document.body).append (imgcopy);//append to document
alert("We get right dimensions: "+ imgcopy.width()+"/"+imgcopy.height());
$("#mnbv1lk87jhy0aaa").remove();
}
})( jQuery );
$(document).ready(function(){
$("img.toreaddimensions").click(function(){$(this).getDimensions();});
});
它适用于
如前所述,如果图像在缓存中,Xavi answer 将不起作用。该问题响应 webkit 未触发缓存图像的加载事件,因此如果未在 img 标记中明确设置宽度/高度属性,则获取图像的唯一可靠方法是等待触发 window.load
事件.
window.load
事件将始终触发,因此在此之后访问 img 的宽度/高度是安全的,无需任何技巧。
$(window).load(function(){
//these all work
$('img#someId').css('width');
$('img#someId').width();
$('img#someId').get(0).style.width;
$('img#someId').get(0).width;
});
如果您需要获取可能被缓存(先前加载)的动态加载图像的大小,您可以使用 Xavi 方法加上一个查询字符串来触发缓存刷新。缺点是它会导致对服务器的另一个请求,对于一个已经缓存并且应该已经可用的 img。愚蠢的Webkit。
var pic_real_width = 0,
img_src_no_cache = $('img#someId').attr('src') + '?cache=' + Date.now();
$('<img/>').attr('src', img_src_no_cache).load(function(){
pic_real_width = this.width;
});
ps:如果您已经在 img.src
中有一个 QueryString,您将必须 parse it 并添加额外的参数以清除缓存。
正如卢克史密斯所说,image load is a mess。它在所有浏览器上都不可靠。这个事实给了我很大的痛苦。在某些浏览器中,缓存的图像根本不会触发事件,所以那些说“图像加载比 setTimeout 更好”的人是错误的。
Luke Smith 的解决方案是 here.
还有 an interesting discussion 关于如何在 jQuery 1.4 中处理这种混乱。
我发现将宽度设置为 0 非常可靠,然后等待“完成”属性变为真并且宽度属性大于零。你也应该注意错误。
$("#myImg").one("load",function(){
//do something, like getting image width/height
}).each(function(){
if(this.complete) $(this).trigger("load");
});
来自 Chris 的评论:http://api.jquery.com/load-event/
我的情况可能有点不同。我正在通过 javascript 动态更改图像的 src,并且需要确保新图像的大小按比例调整以适合固定容器(在照片库中)。我最初只是在加载图像后(通过图像的加载事件)删除了图像的宽度和高度属性,并在计算了首选尺寸后重置了这些属性。但是,这在 Safari 和可能的 IE 中不起作用(我没有在 IE 中彻底测试过它,但图像甚至没有显示,所以......)。
无论如何,Safari 会保留前一张图片的尺寸,因此尺寸总是在一张图片后面。我认为这与缓存有关。因此,最简单的解决方案是克隆图像并将其添加到 DOM(重要的是,将其添加到 DOM 以获取 with 和 height)。将图像的可见性值设置为 hidden(不要使用 display none,因为它不起作用)。获得尺寸后,删除克隆。
这是我使用 jQuery 的代码:
// Hack for Safari and others
// clone the image and add it to the DOM
// to get the actual width and height
// of the newly loaded image
var cloned,
o_width,
o_height,
src = 'my_image.jpg',
img = [some existing image object];
$(img)
.load(function()
{
$(this).removeAttr('height').removeAttr('width');
cloned = $(this).clone().css({visibility:'hidden'});
$('body').append(cloned);
o_width = cloned.get(0).width; // I prefer to use native javascript for this
o_height = cloned.get(0).height; // I prefer to use native javascript for this
cloned.remove();
$(this).attr({width:o_width, height:o_height});
})
.attr(src:src);
该解决方案在任何情况下都有效。
现在有一个 jQuery 插件 event.special.load
来处理缓存图像上的加载事件不触发的情况:http://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js
最近我需要找到宽度和高度来设置 .dialog 表示图形的默认大小。我使用的解决方案是:
graph= $('<img/>', {"src":'mySRC', id:'graph-img'});
graph.bind('load', function (){
wid = graph.attr('width');
hei = graph.attr('height');
graph.dialog({ autoOpen: false, title: 'MyGraphTitle', height:hei, width:wid })
})
对我来说,这适用于 FF3、Opera 10、IE 8、7、6
PS 您可能会在 LightBox 或 ColorBox 等插件中找到更多解决方案
要添加到 Xavi 的答案, Paul Irish's github David Desandro's gitgub offers a function called imagesLoaded() 工作原理相同,并解决了某些浏览器的缓存图像未触发 .load() 事件的问题(使用聪明的 original_src -> ; data_uri -> original_src 切换)。
它被广泛使用并定期更新,这有助于它成为解决问题的最强大的解决方案,IMO。
imagesLoaded
函数的更新版本:github.com/desandro/imagesloaded
这适用于缓存和动态加载的图像。
function LoadImage(imgSrc, callback){
var image = new Image();
image.src = imgSrc;
if (image.complete) {
callback(image);
image.onload=function(){};
} else {
image.onload = function() {
callback(image);
// clear onLoad, IE behaves erratically with animated gifs otherwise
image.onload=function(){};
}
image.onerror = function() {
alert("Could not load image.");
}
}
}
要使用此脚本:
function AlertImageSize(image) {
alert("Image size: " + image.width + "x" + image.height);
}
LoadImage("http://example.org/image.png", AlertImageSize);
演示:http://jsfiddle.net/9543z/2/
我使用 imagesLoaded jquery 插件完成了一些变通实用功能:https://github.com/desandro/imagesloaded
function waitForImageSize(src, func, ctx){
if(!ctx)ctx = window;
var img = new Image();
img.src = src;
$(img).imagesLoaded($.proxy(function(){
var w = this.img.innerWidth||this.img.naturalWidth;
var h = this.img.innerHeight||this.img.naturalHeight;
this.func.call(this.ctx, w, h, this.img);
},{img: img, func: func, ctx: ctx}));
},
您可以通过传递 url、函数及其上下文来使用它。加载图像后执行函数并返回创建的图像,其宽度和高度。
waitForImageSize("image.png", function(w,h){alert(w+","+h)},this)
如果图像已被使用,您应该:
将图像尺寸设置为初始 image.css('width', 'initial'); image.css('高度', '初始');获取尺寸 var originalWidth = $(this).width(); var originalHeight = $(this).height();
您可以使用 HTML 图像元素的 naturalWidth 和 naturalHeight 属性。 (这里有更多info)。
你会像这样使用它:
//you need a reference to the DOM element, not a jQuery object. It would be better if you can use document.getElementByTagsName or ID or any other native method
var pic = $("img")[0];
var pic_real_width = pic.naturalWidth;
var pic_real_height = pic.naturalHeight;
似乎这适用于所有浏览器,但 IE 版本 8 及以下版本除外。
我查看了 Dio 的答案,它对我很有用。
$('#image').fadeIn(10,function () {var tmpW = $(this).width(); var tmpH = $(this).height(); });
确保你调用了所有的函数。在fadeIn() 的recaller 函数中处理图像大小。
谢谢你。
我使用不同的方法,只需在使用图像对象时对服务器进行 Ajax 调用以获取图像大小。
//make json call to server to get image size
$.getJSON("http://server/getimagesize.php",
{"src":url},
SetImageWidth
);
//callback function
function SetImageWidth(data) {
var wrap = $("div#image_gallery #image_wrap");
//remove height
wrap.find("img").removeAttr('height');
//remove height
wrap.find("img").removeAttr('width');
//set image width
if (data.width > 635) {
wrap.find("img").width(635);
}
else {
wrap.find("img").width(data.width);
}
}
当然还有服务器端代码:
<?php
$image_width = 0;
$image_height = 0;
if (isset ($_REQUEST['src']) && is_file($_SERVER['DOCUMENT_ROOT'] . $_REQUEST['src'])) {
$imageinfo = getimagesize($_SERVER['DOCUMENT_ROOT'].$_REQUEST['src']);
if ($imageinfo) {
$image_width= $imageinfo[0];
$image_height= $imageinfo[1];
}
}
$arr = array ('width'=>$image_width,'height'=>$image_height);
echo json_encode($arr);
?>
这适用于跨浏览器
var img = new Image();
$(img).bind('load error', function(e)
{
$.data(img, 'dimensions', { 'width': img.width, 'height': img.height });
});
img.src = imgs[i];
通过使用获取尺寸
$(this).data('dimensions').width;
$(this).data('dimensions').height;
干杯!
另一个建议是使用 imagesLoaded plugin。
$("img").imagesLoaded(function(){
alert( $(this).width() );
alert( $(this).height() );
});
$(document).ready(function(){
var image = $("#fix_img");
var w = image.width();
var h = image.height();
var mr = 274/200;
var ir = w/h
if(ir > mr){
image.height(200);
image.width(200*ir);
} else{
image.width(274);
image.height(274/ir);
}
});
// 此代码有助于显示 200*274 尺寸的图像
这是一个跨浏览器解决方案,当您选择的图像被加载时会触发一个事件:http://desandro.github.io/imagesloaded/ 您可以在 imagesLoaded() 函数中查找高度和宽度。
偶然发现这个线程试图为我自己的问题找到答案。我试图在加载器之后的函数中获取图像的宽度/高度,并不断提出 0。不过,我觉得这可能是您正在寻找的,因为它对我有用:
tempObject.image = $('<img />').attr({ 'src':"images/prod-" + tempObject.id + ".png", load:preloader });
xmlProjectInfo.push(tempObject);
function preloader() {
imagesLoaded++;
if (imagesLoaded >= itemsToLoad) { //itemsToLoad gets set elsewhere in code
DetachEvent(this, 'load', preloader); //function that removes event listener
drawItems();
}
}
function drawItems() {
for(var i = 1; i <= xmlProjectInfo.length; i++)
alert(xmlProjectInfo[i - 1].image[0].width);
}
在 github 中查看这个存储库!
使用Javascript检查宽度和高度的好例子
https://github.com/AzizAK/ImageRealSize
---从一些评论中要求编辑..
Javascript代码:
function CheckImageSize(){
var image = document.getElementById("Image").files[0];
createReader(image, function (w, h) {
alert("Width is: " + w + " And Height is: "+h);
});
}
function createReader(file, whenReady) {
var reader = new FileReader;
reader.onload = function (evt) {
var image = new Image();
image.onload = function (evt) {
var width = this.width;
var height = this.height;
if (whenReady) whenReady(width, height);
};
image.src = evt.target.result;
};
reader.readAsDataURL(file);
}
和 HTML 代码:
<html>
<head>
<title>Image Real Size</title>
<script src="ImageSize.js"></script>
</head>
<body>
<input type="file" id="Image"/>
<input type="button" value="Find the dimensions" onclick="CheckImageSize()"/>
</body>
<html>
对于您不想更改原始位置或图像的功能。
$(this).clone().removeAttr("width").attr("width");
$(this).clone().removeAttr("height").attr("height);
width
和height
,您可能还应该删除min-width
、min-height
、max-width
和max-height
,因为它们也会影响图像尺寸。window.onload
之前调用此代码,则可能会返回 0 的高度/宽度。无论如何,我已经将 FDisk 的想法整合到了上面的解决方案中。load()
将异步执行,因此如果您想访问width
和height
— 它们可能尚未设置。而是在load()
本身中做“魔术”!