用JavaScript获取图像的真实宽度和高度? (在Safari / Chrome中)
我正在创build一个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();
但是在Webkit浏览器(如Safari和Google Chrome)中,值为0。
Webkit浏览器在加载图像后设置高度和宽度属性。 而不是使用超时,我build议使用图像的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可能对图像的尺寸产生任何影响,上面的代码会在图像的内存中进行复制。 这是FDiskbuild议的一个非常聪明的解决scheme。
您也可以使用naturalHeight
和naturalWidth
HTML5属性。
使用HTML5中的naturalHeight
和naturalWidth
属性。
例如:
var h = document.querySelector('img').naturalHeight;
适用于IE9 +,Chrome,Firefox,Safari和Opera( 统计 )。
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创build一个元素并获取创build的对象宽度。
根本问题是WebKit浏览器(Safari和Chrome)并行加载JavaScript和CSS信息。 因此,JavaScript可以在计算CSS的样式效果之前执行,返回错误的答案。 在jQuery中,我发现解决scheme是等到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,其中包括边界和填充的东西。
在接受的答案中,有许多关于如果从WebKitcaching中加载图像时onload
事件不会触发的问题的讨论。
在我的情况下, onload
激发caching的图像,但高度和宽度仍然是0.一个简单的setTimeout
解决了我的问题:
$("img").one("load", function(){ var img = this; setTimeout(function(){ // do something based on img.width and/or img.height }, 0); });
我不能说为什么即使图像从caching中加载(jQuery 1.4 / 1.5的改进?),为什么onload
事件正在触发 – 但是如果您仍然遇到这个问题,也许我的答案和var src = img.src; img.src = ""; img.src = src;
的组合var src = img.src; img.src = ""; img.src = src;
var src = img.src; img.src = ""; img.src = src;
技术将工作。
(请注意,对于我的目的,我不关心预定义的维度,无论是在图像的属性或CSS样式 – 但你可能要删除这些,按照哈维的答案或克隆图像。
这对我来说(safari 3.2),通过从window.onload
事件中发射:
$(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_ALLhttp://img.dovov.comlogo.gif';
我们如何在没有眨眼的真实图像的情况下获得真实的维度
(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();}); });
它适用于<img class =“toreaddimensions”…
那么image.naturalHeight
和image.naturalWidth
属性呢?
似乎在Chrome,Safari和Firefox中可以正常工作,但在IE8甚至IE9中都没有。
如前所述,如果图像在caching中, Xavi的回答将不起作用。 这个问题响应webkit不caching的caching图像上的负载事件,所以如果宽度/高度attrs没有明确设置在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; });
如果您需要获取可能被caching(之前加载)的dynamic加载图像的大小,则可以使用Xavi方法加查询string来触发caching刷新。 缺点是它会导致另一个请求到服务器,已经被caching,应该已经可用的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,你将不得不parsing它并添加额外的参数来清除caching。
jquery有两个名为naturalWidth和naturalHeight的属性,你可以这样使用。
$('.my-img')[0].naturalWidth $('.my-img')[0].naturalHeight
其中my-img是用于select我的图像的类名称。
正如卢克·史密斯所说, 图像加载是一团糟 。 在所有浏览器上都不可靠。 这个事实给了我很大的痛苦。 caching的图片在某些浏览器中根本不会触发事件,所以那些说“图片加载比setTimeout好”的人是错误的。
卢克·史密斯的解决scheme就在这里。
关于如何在jQuery 1.4中处理这个混乱,有一个有趣的讨论 。
我发现将宽度设置为0是非常可靠的,然后等待“完成”属性为true,宽度属性大于零。 你也应该注意错误。
$("#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/
我的情况可能有点不同。 我dynamic更改通过JavaScript的图像的src,并需要确保新的图像按比例resize,以适应一个固定的容器(在照片库中)。 我最初刚删除图像的宽度和高度属性(通过图像的加载事件),并重新计算后的首选尺寸。 然而,这并不适用于Safari和可能的IE浏览器(我没有在IE中彻底testing过,但图像甚至没有显示,所以…)。
无论如何,Safari保留了以前的图像的尺寸,所以维度总是一个图像的后面。 我认为这与caching有关。 所以最简单的解决scheme就是克隆图像并将其添加到DOM(重要的是它被添加到DOM获取和高度)。 给图像隐藏的可见性值(不要使用无显示,因为它不会工作)。 获得维度后,删除克隆。
这里是我使用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);
这个解决scheme在任何情况下。
现在有一个jQuery插件event.special.load
,用于处理caching图像上的加载事件不会触发的情况: http : //github.com/peol/jquery.imgloaded/raw/master/ahpi。 imgload.js
最近我需要find代表graphics的.dialog默认大小的宽度和高度。 我使用的解决scheme是:
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你可能会发现一些更多的解决scheme,看看像LightBox或ColorBox的插件
为了增加Xavi的答案, Paul Irish的github David Desandro的gitgub提供了一个叫做imagesLoaded()的函数 ,它遵循相同的原则,并且解决了某些浏览器的caching图片没有触发.load()事件的问题(用聪明的original_src – > data_uri – > original_src切换)。
它被广泛使用和定期更新,这有助于成为解决这个问题的最强大的解决scheme。
这适用于caching和dynamic加载的图像。
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/
我已经做了一些变通的实用程序function,使用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,函数和上下文来使用它。 加载图像后执行函数,并返回创build的图像,其宽度和高度。
waitForImageSize("image.png", function(w,h){alert(w+","+h)},this)
如果图像已经被使用,你可以使用sholud:
-
将图像尺寸设置为初始
image.css('width','initial'); image.css('height','initial');
-
获取尺寸
var originalWidth = $(this).width(); var originalHeight = $(this).height();
请使用下面的代码获取高度和宽度
var VarHeight = imgLogo.clientHeight; var VarWidth = imgLogo.clientWidth;
请检查完整的演示链接
DEMO
对于不想更改原始位置或图像的function。
$(this).clone().removeAttr("width").attr("width"); $(this).clone().removeAttr("height").attr("height);
我检查了Dio的答案,它对我很好。
$('#image').fadeIn(10,function () {var tmpW = $(this).width(); var tmpH = $(this).height(); });
确保你打电话所有的functionaso。 在fadeIn()的重算器函数中处理图像大小。
谢谢你。
我使用不同的方法,只需在图像对象正在使用时,使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;
干杯!
另一个build议是使用imagesLoaded插件 。
$("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尺寸的图像
下面是一个跨浏览器的解决scheme,当你select的图像被加载时触发一个事件: http ://desandro.github.io/imagesloaded/你可以在imagesLoaded()函数中查找高度和宽度。
陷入这个线索试图find我自己的问题的答案。 我试图在加载器之后的函数中获得一个图像的宽度/高度,并且不断地提出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>