2017-07-06 95 views
1

我一直在預覽多個圖像,然後嘗試使用@ ratan-paul對"Preview an image before it is uploaded"的響應非常有用。但是,當我試圖調整代碼有點我得到了一個意想不到的結果。我所做的是爲每個<image>創建一個<span>標籤以添加一些樣式選項。這裏是jQuery代碼我結束了:在上傳前預覽圖像時發生意外的行爲

$(function() { 
    var span_id = ""; 
    function readURL(input) { 
     for(var i =0; i< input.files.length; i++){ 
      var span = $('<span>'); 
      span_id = "span"+i; 
      span.attr('id',span_id); 
      span.appendTo('#img-previews'); 
      if (input.files[i]) { 
       var reader = new FileReader(); 
       reader.onload = function (e) { 
        var img = $('<img id="dynamic">'); 
        img.attr('src', e.target.result); 
        img.attr('height','150px'); 
        img.attr('width','200px'); 
        img.appendTo("#"+span_id); 
       }; 
       reader.readAsDataURL(input.files[i]); 
      } 
     } 
    } 

    $("#imgUpload").change(function(){ 
     readURL(this); 
    }); 
}); 

現在奇怪的是,當我運行上面的代碼我創建的每個圖像的<span>標籤,但所有的圖像得到塞進創建的最後一個<span>。另一方面,如果我調試腳本,我會得到想要的結果,其中每個圖像都插入到它自己的<span>標記中。我對此感到困惑,所以如果任何人有任何想法,爲什麼會發生這種情況,或者如何避免這種情況,將不勝感激。

這是當我運行該腳本無需調試的截屏: Screen grab of unexpected behavior

這裏是通過與JS調試 Result when stepping through a JS debugger

回答

1

短篇小說踩當結果的截屏:

你的循環改爲

for(let i =0; i< input.files.length; i++){ 

let keyword in the for loop

注意,letfor循環可能無法正常工作正如人們所預料的IE11和邊緣。您可以將創建的範圍移動到reader.onload事件中,以調整這些瀏覽器(您的代的ID將不得不更改)。

長的故事:

使用var i =0實例i在整個循環,而let i =0其綁定到當前迭代。

發生了什麼事情是for循環觸發異步調用reader.onload,該循環被添加到JS事件循環以供將來解析,並且for循環繼續進行下一次迭代。 重要位:在下一次迭代中,前面的reader.onload尚未解決

一段時間以後,該reader.onload異步調用 for循環後返回完成(其中i處於用於循環中的最大值),並追加所得img s到#span_(max i)

更新:OK,所以let可能不支持無處不在,caniuse將其定在80%,截至7月2017。

對於一致的結果,移動span元件的創建到onload事件:

function readURL(input) { 
    for(var i =0; i< input.files.length; i++){ 
     if (input.files[i]) { 
      var reader = new FileReader(); 
      reader.onload = function (e) { 
       var span = $('<span>'); 
       var uniqueId; 
       do { //simple loop to generate a unique id 
        uniqueId = 'img-' + (Math.random()+1).toString(36).substring(2, 7); 
       } while ($('#' + uniqueId).length > 0); //redo loop if id not unique 
       span.attr('id', uniqueId); 
       span.appendTo('#img-previews'); 

       var img = $('<img>'); 
       img.attr('src', e.target.result); 
       img.attr('height','150px'); 
       img.attr('width','200px'); 
       span.append(img); 
      }; 
      reader.readAsDataURL(input.files[i]); 
     } 
    } 
} 

注意,這些span元素的創建可能最終被亂序;如果您希望它們按添加的順序排列,請查看Promise.all(或jQuery版本)。

另外請注意,我沒有測試過上述所以一些按摩可能需要。

+0

我試着用let語句@duncan-smith切換我的for循環,但結果沒有改變。在我的IDE(phpstorm 2017.1.4)中,'let'被表示爲「當前JavaScript版本中不支持當前定義」的錯誤。我正在使用yii2框架,並且當前安裝的jquery版本是2.2.4。我目前正在測試的瀏覽器是Mozilla firefox 54.0(32位),firefox開發者版本55.0b6(64位)和chrome 59.0.3071.115(官方版本)(64位)。任何想法是什麼問題? – natral

+0

@natral,我已經更新了我的答案。看看它是否適合你。 –

+0

偉大的,幫助了很多@鄧肯。謝謝! – natral