在本地范围之外使用JQuery变量

时间:2014-10-24 06:12:41

标签: javascript jquery variables asynchronous scope

我正在努力解决一个我无法定义的问题。我把这个JQuery拼凑在一起上传图片。生成预览时,我正在使用FileReader来获取图像尺寸,以便控制预览的大小调整。据我所知,当我在console.log ($preview);img.onload = function() {};时,这种方法正常。但是,如果我在函数之外执行此操作,则它是未定义的。我需要在以下函数中访问变量。我一直在研究范围,根据我的理解,如果我没有像var variable = x;那样在函数内声明变量,那么它不应该是本地的。我也搜索并搜索了互联网和SO以寻求解决方案,但似乎没有什么适合。

这是异步问题还是范围问题,即使最初在这些函数之外定义了$preview?我可以像在PHP中一样从函数内部返回它吗?

var $preview;
if (previewsOn) {
    if (isImgFile(ui.file)) {

    var reader = new FileReader;

    reader.onload = function() {
        var img = new Image;

        img.onload = function() {

            if (img.width > 120 || img.height > 100) {

                var maxWidth = 120;
                var maxHeight = 100;
                var ratio = 0;
                var width = img.width;
                var height = img.height;

                if (width > maxWidth){
                   ratio = maxWidth / width;
                   $preview = $('<img/>').css("width", maxWidth);
                   $preview = $('<img/>').css("height", height * ratio);
                   height = height * ratio;
                   width = width * ratio;
                }

                if (height > maxHeight){
                   ratio = maxHeight / height;
                   $preview = $('<img/>').css("height", maxHeight);
                   $preview = $('<img/>').css("width", width * ratio);
                   width = width * ratio;
                   height = height * ratio;
                }
            } else {
                $preview = $('<img/>');
            }
        };

        img.src = reader.result;
     };

     reader.readAsDataURL(ui.file);

     ui.readAs('DataURL', function(e) {
        $preview.attr('src', e.target.result);
     });

        } else {

           $preview = $('<i/>');
           ui.readAs('Text', function(e) {
                $preview.text(e.target.result.substr(0, 15) + '...');
           });
        }

    } else {
       $preview = $('<i>no preview</i>');
    }

$($previewImg).empty(); $($preview).appendTo($previewImg);
    $('<td/>').text(Math.round(ui.file.size / 1024) + ' KB').appendTo($row);
        $('<td/>').append($pbWrapper).appendTo($row);
        $('<td/>').append($cancelBtn).appendTo($row);
        return $progressBar;
    };

1 个答案:

答案 0 :(得分:0)

您在.onload处理程序中为$ preview分配值,但稍后会调用它。根据您的代码,以下更改可能有所帮助:

var $preview;
if (previewsOn) {
    if (isImgFile(ui.file)) {
        $preview = $("<img/>");

(在if语句之后添加了初始化代码)

然后替换

之类的行
$preview = $('<img/>').css("width", maxWidth);

$preview.css("width", maxWidth);

并删除

} else {
    $preview = $('<img/>');

因此不会重新分配变量。

回复评论

失败情景时间表:

  1. 你代码注册onload handler
  2. 你的代码继续执行,尝试使用$ preview执行smth,这还没有价值
  3. 图像最终加载并触发onload处理程序,将值赋给$ preview