0

我知道这可能是一个非常菜鸟的问题,但我看不出这里的问题是返回变量pic_real_width.

我认为这是一个范围的事情,但除了使其成为全球性(不能这样做)之外,我不确定如何设置和返回它。

提前致谢,

function get_real_width(img){
    var pic_real_width;
    $("<img/>") // Make in memory copy of image to avoid css issues
      .attr("src", $(img).attr("src"))
      .load(function() {
         pic_real_width = this.width;   
         console.log( pic_real_width ); // returns a number
       });
   console.log( pic_real_width ); //returns undefined
   return pic_real_width;
}
4

6 回答 6

1

您的函数将在 .load 调用完成之前退出,因此没有返回值。

'pic_real_width' 在加载回调函数期间设置,但与此同时,您的函数在等待 .load 完成时继续执行,因此在值设置之前退出。

于 2013-04-24T16:53:29.163 回答
1

简单来说,你传递给 load 的函数是异步的,异步函数有不同的模式函数上下文。

在示例中,无法遇到解决方案(我现在找不到解决方案),但是,您可以重构代码以异步获取图像的“真实宽度”,只需传递内部调用的其他回调传递给 load() 的函数。

例如:

function get_real_width(img, callback){
    var pic_real_width;
    $("<img/>") // Make in memory copy of image to avoid css issues
    .attr("src", $(img).attr("src"))
    .load(function() {
        pic_real_width = this.width;   
        callback( img, pic_real_width ); // Call the function with the number expected
    });
}

因为它只是获取宽度并将其返回给函数。

但是,我知道,它不能在某些情况下使用。

祝你好运。

于 2013-04-24T16:56:33.397 回答
0

默认情况下,ajax()请求是异步的,因此调用ajax()通常会在请求完成之前返回。您可以改用回调函数。

function get_real_width(img, callback){
    var pic_real_width;
    $("<img/>") // Make in memory copy of image to avoid css issues
    .attr("src", $(img).attr("src"))
    .load(function() {
        pic_real_width = this.width;   
        callback(pic_real_width ); // Call the function with the number expected
    });
}

 get_real_width(img, function(returnedData){ //anonymous callback function        
    console.log(myVariable);
    return returnedData;
 });

如果你绝对必须,你可以async: false在调用内部ajax()使用.

于 2013-04-24T17:15:19.960 回答
0

.load正在将load事件处理程序附加到图像并且该事件可能会被异步触发(如果浏览器缓存了图像,它可能是同步的),这意味着.load调用立即返回,并且当您到达return pic_real_width;.

但是,您可以使用$.Deferred优雅的方式解决此问题。

function get_real_width(img){
    var def = $.Deferred();
    $("<img/>")
      .load(function() {
         def.resolve(this.width);
       })
      .attr("src", $(img).attr("src"));
    return def;
}

get_real_width().done(function (width) {
    console.log(width);
});

请注意,我在设置源之前附加了处理程序,以防图像被缓存并且事件被同步触发

于 2013-04-24T17:04:47.310 回答
0

兑现承诺只是“一点点”更好......

function get_real_width(img, callback) {
    var dfd= $.Deferred(function (dfd) {

        $("<img/>")
            .attr("src", $(img).attr("src"))
            .load(function () {
                dfd.resolve(this.width);
            });
    });

    return dfd.promise();
}
于 2013-04-24T17:12:27.557 回答
0

在英语中,这是get_real_width目前正在做的事情:

  1. 创建一个名为pic_real_width.
  2. 使用复制的 src 属性创建一个新<img/>元素,一旦<img/>加载该元素,然后运行内部函数。“once/then”部分是每个人都描述为异步的部分,因为相对于您的代码的其余部分,您不知道或无法控制何时会发生这种情况。
  3. 立即登录并返回pic_real_width

请注意,pic_real_width只有在调用内部函数并完成时才会设置,但在get_real_width退出时可能不会发生,因此pic_real_width在您记录并返回它时将是未定义的。

那么,你如何解决这个问题?

这取决于您如何使用get_real_width. 例如,如果您从 的结果创建警报get_real_width,如下所示:

alert(get_real_width(some_img));

然后,您可以改为修改您的函数,以便在附加到 .load 的函数内部发生警报:

function alert_real_width(img){
    $("<img/>")
      .attr("src", $(img).attr("src"))
      .load(function() {
         var pic_real_width = this.width;   
         alert( pic_real_width );
       });
}

显然,我怀疑你正在做一个alert,但这应该让你知道如何解决这个问题。对于更通用的解决方案,您可以像其他用户建议的那样使用回调。

于 2013-04-24T17:10:35.017 回答