2017-07-06 2 views
1

アップロードする前に複数の画像をプレビューしていて、"Preview an image before it is uploaded"への@ ratan-paul応答を使用して試してみました。しかし、コードをちょっと微調整しようとすると、予期しない結果になりました。私がしたのは、各<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>タグに挿入されている望みの結果が得られます。私はこれにちょっと戸惑っています。なぜ誰かがこれが起こっているかどうか、あるいは避ける方法が援助に感謝しているようなアイデアがあれば。ここで

は、私はデバッグなしでスクリプトを実行する際の画面のグラブです:ショートストーリー Result when stepping through a JS debugger

答えて

1

JSデバッガを通じ踏ん Screen grab of unexpected behavior

そして、ここでは、結果の画面のグラブです。

for(let i =0; i< input.files.length; i++){ 
にあなたのループを変更

一つはIE11とエッジに対して期待どおりforループ0

let keyword in the for loop

注、letは機能しないことがあります。あなたはあなたのスパンの作成をreader.onloadイベントに移動して、それらのブラウザに合わせて調整することができます(あなたの世代のIDは変更する必要があります)。

長い物語:let i =0は、現在の繰り返しにバインドし、一方、

var i =0を使用しては、ループ全体にわたりiをインスタンス化します。何が起こっている

は、その次の反復への将来の解像度のためのJSのイベントループに追加された非同期呼び出しreader.onloadオフforループ火災、およびforループが進行するということです。 重要なビット:次の反復では、前のreader.onloadはまだ解決されていませんでした。 (iループの最大値である)、及び#span_(max i)に得img Sを追加

はいつか後、reader.onload非同期呼び出しが完了したforループ後を返します。

更新:OK、そうletcaniuseは、2017年7月の時点で80%でそれを置く、どこでもサポートされない場合があります。一貫性のある結果を得るため

onloadイベントにspan要素の作成を移動これらspan要素の作成が順不同になってしまうことが

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]); 
     } 
    } 
} 

注。あなたが追加された順にそれらを望むなら、Promise.all(またはjQueryバージョン)を見てみてください。

また、私は上記をテストしていないので、いくつかのマッサージが必要な場合があります。

+0

私はlet文@duncan-smithでforループを切り替えようとしましたが、結果は変更されませんでした。私のIDE(phpstorm 2017.1.4)では、「letは、現在のJavaScriptバージョンでは現在の定義ではサポートされていません」というエラーが表示されています。私はyii2フレームワークで作業しており、インストールされている現在のjqueryバージョンは2.2.4です。私が現在テストしているブラウザは、mozilla firefox 54.0(32bit)、firefox開発者版55.0b6(64bit)、chrome 59.0.3071.115(official build)(64bit)です。何が問題なのか? – natral

+0

@natral、私は私の答えを更新しました。それがあなたのために働くかチェックしてください。 –

+0

@ダンカンが大いに役立つ素晴らしい。ありがとう! – natral

関連する問題