私は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属性も使用できます。
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で要素を作成し、作成されたオブジェクトの幅を取得します。
根本的な問題は、WebKitブラウザ(SafariとChrome)がJavaScriptとCSSの情報を並行して読み込むことです。そのため、CSSのスタイル効果が計算される前にJavaScriptが実行され、間違った答えが返されることがあります。 jQueryでは、解決策はdocument.readyState == 'complete'になるまで待つことです。
jQuery(document).ready(function(){
if (jQuery.browser.safari && document.readyState != "complete"){
//console.info('ready...');
setTimeout( arguments.callee, 100 );
return;
}
... (rest of function)
幅と高さに関する限り、あなたがしていることによりますが、offsetWidthとoffsetHeightが必要かもしれません。それらはボーダーとパディングのようなものを含みます。
画像が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);
});
画像がキャッシュから読み込まれてもonload
イベントが発生する理由について話すことはできません(jQuery 1.4/1.5の改善?)—それでもまだこの問題が発生している場合は、おそらく答えるとvar src = img.src; img.src = ""; img.src = src;
テクニックが機能します。
(私の目的のために、画像の属性またはCSSスタイルのいずれかで事前に定義された寸法については心配していませんが、Xaviの答えに従ってそれらを削除することもできます。または画像を複製します。)
window.onload
イベント内から起動することで、これは私にとってはうまくいきます(safari 3.2):
$(window).load(function() {
var pic = $('img');
pic.removeAttr("width");
pic.removeAttr("height");
alert( pic.width() );
alert( pic.height() );
});
あなたはプログラム的に画像を取得し、まったくDOMを台無しにする必要なしにJavascriptを使って寸法をチェックすることができます。
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ではまったく動作しません。
実画像を点滅させずに正しい実寸を取得する方法
(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"を使って動作します...
Jqueryには、naturalWidthとnaturalHeightという2つのプロパティがあります。この方法で使用できます。
$('.my-img')[0].naturalWidth
$('.my-img')[0].naturalHeight
My-imgは、画像を選択するためのクラス名です。
前述のように、 Xaviの答え は、画像がキャッシュにあると機能しません。この問題はwebkitがキャッシュされた画像でloadイベントを発生させないことに対応しているので、幅/高さattrsがimgタグで明示的に設定されていない場合、画像を取得する唯一の信頼できる方法はwindow.load
イベントが発生するのを待つことです。
window.load
イベントは常に/を発生させるので、そのあとのwidth/heightと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がある場合は、それを 解析し 、キャッシュをクリアするための追加のパラメータを追加する必要があります。
$("#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を使って画像のソースを動的に変更していて、新しい画像が(フォトギャラリーの)固定コンテナに合うように比例した大きさになるようにする必要があります。画像の読み込み後(画像の読み込みイベントを介して)、まず画像の幅と高さの属性を削除し、好みの寸法を計算した後にこれらをリセットします。ただし、それはSafariでは機能せず、おそらくIEでテストされていません(私はIEで徹底的にテストしていませんが、画像は表示されない、など)。
とにかく、Safariは前の画像の寸法を保持しているので、寸法は常に1画像後ろになります。これはキャッシュと関係があると思います。そのため、最も簡単な解決策は、イメージを複製してDOMに追加することです(DOMに追加して高さを取得することが重要です)。画像の可視性を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);
この解決策はどのような場合でも機能します。
Luke Smithが言っているように、 イメージのロードは混乱です 。すべてのブラウザで信頼できるわけではありません。この事実は私に大きな苦痛を与えました。キャッシュされた画像は、一部のブラウザではイベントをまったく起動しないため、「画像の読み込みはsetTimeoutよりも優れている」と言っている人は間違っています。
Luke Smithの解決策は です。
そして、この混乱がjQuery 1.4でどのように処理されるかについて 興味深い議論 があります。
幅を0に設定してから、 "complete"プロパティがtrueになり、widthプロパティが0より大きくなるのを待つのがかなり信頼できることがわかりました。あなたもエラーに注意するべきです。
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、functionそしてそのコンテキストを渡すことでこれを使うことができます。 imageがロードされて、作成されたimage、その幅と高さを返したあと、機能は実行されます。
waitForImageSize("image.png", function(w,h){alert(w+","+h)},this)
最近、グラフを表す.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、オペラ10、IE 8,7,6で動作します
P.Sあなたはライトボックスやカラーボックスのようないくつかのプラグインの中を見ていくつかの他の解決策を見つけるかもしれません
画像が既に使用されている場合は、sholud:
画像の寸法を初期値に設定
image.css( 'width'、 'initial'); image.css( 'height'、 'initial');
寸法を取得
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;
これはバージョン8以下のIEを除くすべてのブラウザで動作するようです。
これは、キャッシュされた画像と動的に読み込まれた画像の両方で機能します。
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);
キャッシュされたイメージのloadイベントが発生しない場合に対処するためのjQueryプラグインevent.special.load
があります。 http://github.com/peol/jquery.imgloaded/raw /master/ahpi.imgload.js
Xaviの答えに追加するには、 Paul Irishのgithub David DesandroのgitgubはimagesLoaded() という関数を提供しています。これは同じ原理で動作し、ブラウザのキャッシュされた画像が.loadを起動しない問題を回避します。 ()イベント(賢いoriginal_src - > data_uri - > original_src切り替えあり)。
これは広く使用されており、定期的に更新されています。これは、問題に対する最も堅牢な解決策であるIMOに貢献します。
私自身の質問に対する答えを見つけようとしているこのスレッドにつまずいた。私はローダーの後の関数で画像の幅/高さを取得しようとしていました、そして、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);
}
$(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サイズの画像を表示するのに役立ちます
私はDioの答えをチェックアウトしました、そしてそれは私にとって素晴らしい仕事です。
$('#image').fadeIn(10,function () {var tmpW = $(this).width(); var tmpH = $(this).height(); });
すべての関数を必ずasoと呼ぶようにしてください。 fadeIn()の再呼び出し関数の画像サイズでそのハンドル。
これをありがとう。
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>
別の提案は imagesLoadedプラグイン を使うことです。
$("img").imagesLoaded(function(){
alert( $(this).width() );
alert( $(this).height() );
});
これはクロスブラウザで動作します
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;
乾杯!
私は別の方法を使用します。画像オブジェクトが使用されているときに画像サイズを取得するために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);
?>
選択した画像が読み込まれたときにイベントをトリガーするクロスブラウザソリューションは次のとおりです。 http://desandro.github.io/imagesloaded/ あなたが調べることができますimagesLoaded()関数内の高さと幅.
元の配置や画像を変更したくない機能のために。
$(this).clone().removeAttr("width").attr("width");
$(this).clone().removeAttr("height").attr("height);