函数中的 jQuery 变量范围

jQuery variable scope in function

本文关键字:变量 范围 jQuery 函数      更新时间:2023-09-26

我对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变量在此范围内不可用。谁能告诉我为什么?

这不是范围的问题,这很好,而是同步性的问题:你在执行加载回调之前读取值。

您作为参数提供给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
});

请注意,在设置onload回调,应始终设置 src。某些浏览器(如果图像在缓存中)如果在设置源后设置了 onload 回调,则可能不会调用 onload 回调。

使用回调。其他答案是解释异步的东西,我不重复:-)

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);
});

加载函数完成之前调用第二个警报。使用回调...

试试这个

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);
});

对于来自其他语言的Javascript程序员来说,这是一个常见问题。Javascript 使用称为异步调用的执行模型。简而言之,当您为 .load() 事件注册函数时,函数的执行将推迟到加载图像时,而函数体的其余部分(即第二个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 );
});