3

jQueryに問題があります。

の実際の幅/高さを取得したかったimg
今、私はそれを得るためにこの関数を使用しました:

var imageSize = function(image) {
    var realImageSize = { };

    $("<img/>") // Make in memory copy of image to avoid css issues
    .attr("src", $(image).attr("src"))
    .load(function() {
        realImageSize.width = this.width;   // Note: $(this).width() will not
        realImageSize.height = this.height; // work for in memory images.

        alert(realImageSize['height']); // Valid height
    });

    alert(realImageSize['height']); // Undefined

    return realImageSize;
}

そのため、画像をメモリにコピーしてから、.loadメソッドで画像の実際のサイズを取得して設定します。

ここで問題となるのは、var realImageSize何らかの理由で変数がこのスコープで使用できないことです。誰か教えてもらえますか?

4

4 に答える 4

6

これはスコープの問題ではなく、問題ありませんが、同期性の問題です。ロードコールバックが実行される前に値を読み取っています。

引数として指定したコールバックloadはすぐには実行されませんが、画像が読み込まれた後にのみ実行されます。

通常の解決策は、値を返さずにコールバックを提供することです。

var fetchImageSize = function(image, callback) {
    $("<img/>") // Make in memory copy of image to avoid css issues
    .load(function() {
        var realImageSize = { };
        realImageSize.width = this.width;   // Note: $(this).width() will not
        realImageSize.height = this.height; // work for in memory images.
        callback(realImageSize);
    }).attr("src", image.src);
};

fetchImageSize(myImage, function(realImageSize){
    alert(realImageSize['height']); // NOT Undefined
});

コールバックを設定したは、常にsrcを設定する必要があることに注意してくださいonload。一部のブラウザでは、画像がキャッシュにある場合、ソースを設定した後に画像を設定すると、onloadコールバックが呼び出されない場合があります。

于 2013-01-31T10:02:08.003 に答える
2

これは、他の言語を使用するJavascriptプログラマーに共通の問題です。Javascriptは、非同期呼び出しと呼ばれる実行モデルを使用します。一言で言えば、イベントに関数を登録すると、関数の実行は、画像が読み込まれたときに.load()延期され、関数本体の残りの部分(つまり、second )はすぐに実行されます。alert()

var imageSize = function(image) {
    //runs now
    var realImageSize = { };

    //runs now
    $("<img/>") // Make in memory copy of image to avoid css issues
    .attr("src", $(image).attr("src"))
    .load(function() {
        //this code can run say 5 sec later
        realImageSize.width = this.width;   // Note: $(this).width() will not
        realImageSize.height = this.height; // work for in memory images.

        alert(realImageSize['height']); // Valid height
    });

    //runs now. The realImageSize variable is yet to be created in 5 sec
    alert(realImageSize['height']); // Undefined

    //runs now
    return realImageSize;
}

この種の問題を解決するための一般的なパターンは、時間がかかる関数にコールバックを渡すことです。

//** Get an image URL and a callback function that will be called when the image is loaded and the size is detected
function imageSize ( src, callback ) {
    $("<img src="' + src + '"/>").load( function () {
        //here we call the callback which will be called when the image is loaded
        callback({
            width: this.width,
            height: this.height
        });
    });
}

imageSize( 'my/image/path.png', function ( imageSize ) {
    //this callback function will be called when the image is loaded
    alert( 'width: ' + imageSize.width + ', height: ' + imageSize.height );
});
于 2013-01-31T10:12:29.180 に答える
2

ロード関数が完了する前に2番目のアラートが呼び出されます。コールバックを使用してください。

これを試して

var imageSize = function(image,callback) {
  var realImageSize = { };

  $("<img/>") // Make in memory copy of image to avoid css issues
  .attr("src", $(image).attr("src"))
  .load(function() {
    realImageSize.width = this.width;   // Note: $(this).width() will not
    realImageSize.height = this.height; // work for in memory images.

    alert(realImageSize['height']); // Valid height
    callback(realImageSize);
  });


}

imageSize(img, function(realImageSize) {
   alert(realImageSize.height);
});
于 2013-01-31T10:02:43.820 に答える
2

コールバックを使用します。他の答えは非同期のものを説明しています、私は繰り返していません:-)

var imageSize = function(image, callback) {
.
.
.
    .load(function() {
        realImageSize.width = this.width;   // Note: $(this).width() will not
        realImageSize.height = this.height; // work for in memory images.

        callback(realImageSize);
    });

次に、次のように関数を呼び出すことができます。

imageSize(img, function(size) {
    alert(size.height);
});
于 2013-01-31T10:07:37.537 に答える