Javascript 在局部范围外使用JQuery变量

Javascript 在局部范围外使用JQuery变量,javascript,jquery,variables,asynchronous,scope,Javascript,Jquery,Variables,Asynchronous,Scope,我正在努力解决一个我无法定义的问题。我拼凑了这个JQuery来上传图像。生成预览时,我使用FileReader获取图像尺寸,以便控制预览的大小。据我所知,当我做console.log($preview)时,这工作正常内部img.onload=function(){}。但是,如果我在函数之外这样做,它是未定义的。我需要访问以下函数中的变量。我一直在研究范围,从我的理解来看,如果我不在函数中声明变量,比如var variable=x它不应该是本地的。我也在互联网上搜索了又搜索,寻找一个解决方案,但似

我正在努力解决一个我无法定义的问题。我拼凑了这个JQuery来上传图像。生成预览时,我使用FileReader获取图像尺寸,以便控制预览的大小。据我所知,当我做
console.log($preview)时,这工作正常内部
img.onload=function(){}。但是,如果我在函数之外这样做,它是未定义的。我需要访问以下函数中的变量。我一直在研究范围,从我的理解来看,如果我不在函数中声明变量,比如
var variable=x它不应该是本地的。我也在互联网上搜索了又搜索,寻找一个解决方案,但似乎什么都不合适

这是一个异步问题还是一个范围问题,即使
$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;
    };
var$preview;
如果(预演){
if(isImgFile(ui.file)){
var reader=新文件读取器;
reader.onload=函数(){
var img=新图像;
img.onload=函数(){
如果(img.width>120 | | img.height>100){
var maxWidth=120;
var maxHeight=100;
var比率=0;
变量宽度=img.width;
var高度=img高度;
如果(宽度>最大宽度){
比率=最大宽度/宽度;
$preview=$('');
ui.readAs('Text',函数(e){
$preview.text(e.target.result.substr(0,15)+'…');
});
}
}否则{
$preview=$(“无预览”);
}
$($PreviewMg).empty();$($preview).appendTo($PreviewMg);
$('').text(Math.round(ui.file.size/1024)+“KB”).appendTo($row);
$('').append($pbWrapper).appendTo($row);
$(“”).append($cancelBtn).appendTo($row);
返回$progressBar;
};

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

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

} else {
    $preview = $('<img/>');
}其他{
$preview=$('');
所以变量不会被重新赋值

回复评论

故障场景时间线:

  • 您可以编写寄存器onload处理程序
  • 您的代码将继续执行,尝试使用$preview执行smth,但它还没有值
  • 最终加载图像并触发onload处理程序,将值分配给$preview

  • 这是一个异步问题。对如何解决它有什么建议吗?请使用
    $.Deferred()
    或使用回调函数,或仅在初始化后使用变量。但最重要的是:使用正确的代码缩进样式。现在它很奇怪和令人困惑。我尽了最大努力缩进它,但这很困难。它在粘贴之前已正确缩进。嗯,它似乎起了作用,但我希望了解原因。问题是t
    $preview
    需要默认值
    $(“”)
    ?然后该元素就被其他函数修改了?请参见上面的答案,我添加了故障场景
    $preview.css("width", maxWidth);
    
    } else {
        $preview = $('<img/>');