【问题标题】:Setting a global variable from within a nested private function从嵌套的私有函数中设置全局变量
【发布时间】:2014-06-17 09:33:04
【问题描述】:

您好,提前感谢您对这个难题的帮助!

我无法从 $.imgpreload() 函数中设置 globalMaxW

console.log(globalMaxW);$.imgpreload() 函数之后调用时返回0,而在$.imgpreload() 函数内部调用时返回正确的图像宽度。

如何在该嵌套函数中设置全局变量 globalMaxW

谢谢!

var globalMaxW = 0; 

function infoWidth() {

    $('.swipe-wrap img').each(function(){
        var $me = $(this),
            mysrc = $me.attr('src');

        var newimg = new Image();

        newimg.src = mysrc;

        $.imgpreload($me, function(){
            if(newimg.width > globalMaxW) {
                globalMaxW = newimg.width;
            }           
        });

        console.log(globalMaxW);
    });



    $('#info p').css({'width' : globalMaxW});
}

【问题讨论】:

  • 我认为$.imgpreload 是异步的,不是吗?
  • 在内部范围内设置全局变量(无论如何最好避免)是没有障碍的。你已经在做。这可能是年表问题,例如如果你的函数被异步调用。

标签: javascript jquery global-variables scope


【解决方案1】:

我假设这是jquery.imgpreload 插件。 imgpreload 是异步的,因此您的 globalMaxW 已设置,但仅在您作为调用的第二个参数传递的回调函数之后才设置,并且仅在以异步方式获取图像后才会发生这种情况。我了解您只想在预加载所有图像后设置 css 属性。因此,您可以使用 jquery 延迟对象的集合来完成此操作。

在下面的代码中,将为每个 imgpreload 调用创建 jQuery $.Deferred 对象并将其推送到一个数组中。您可以看到,一旦 imgpreload 调用了回调,deferred 就被解决了。

在底部的 $.when 函数基本上在 promises 集合中的每个 $.Deferred 被解析时调用一次 done 回调。

function infoWidth() {
    var promises = [];

    $('.swipe-wrap img').each(function(){
        var $me = $(this),
            mysrc = $me.attr('src');

        var newimg = new Image();

        newimg.src = mysrc;

        var def = new $.Deferred();
        promises.push(def);

        $.imgpreload($me, function(){
            if(newimg.width > globalMaxW) {
                globalMaxW = newimg.width;
            }           
            def.resolve();
        });

        console.log(globalMaxW);
    });

    $.when.apply($, promises).done(function(){
      // when all of the promises are resolved that means all imgpreload functions invoked the callbacks
      // and here your globalMaxW is set.
      $('#info p').css({'width' : globalMaxW});
    });
}

【讨论】:

    【解决方案2】:

    您的 console.log(globalMaxW) 发生在以下代码完成执行之前,是的,当时它确实等于零:

     $.imgpreload($me, function(){
                if(newimg.width > globalMaxW) {
                    globalMaxW = newimg.width;
                }           
            });
    

    由于该函数是异步的,它开始运行“imgpreload”并立即继续,无需等待它完成。 globalMaxW 将被设置,但在 console.log() 之后...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多