繁体   English   中英

函数中的jQuery变量范围

[英]jQuery variable scope in function

我有一个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回调。

在加载功能完成之前调用第二个警报。使用回调...

尝试这个

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

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

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

对于来自其他语言的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 );
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM