2012-03-16 10 views
0

これまでに遭遇したことがあります。私は無限の関数、forループの内部にパラメータとして文字列を渡そうとしています。私の理解から、これは再帰的なので、変数の文字列が何回変わっても、同じ文字列を送信します(1,2,3,4は(おそらく?)1,1,1,1が渡されます1,2,3,4)。私はこれを非再帰的にしたいので、以下の例では、複数のファイル入力要素のファイル名が異なっています(それらのどれも同じではないため)。JavaScript:変数を匿名関数にパラメータとして送信するときに再帰を削除します。

イベントリスナーに非再帰パラメータを受け取らせるにはどうすればよいですか?

function images_upload(e) 
{ 
for (var i = 0; i < document.getElementById('post_files').files.length; i++) 
{ 
    var file = document.getElementById('post_files').files[i]; 
    var n = images_name(file.name); 
    var xhr = new XMLHttpRequest(); 

    if (typeof xhr.upload=='object') 
    { 
    var upload = xhr.upload; 
    upload.addEventListener('progress', function(e,n) 
    { 
    alert('n = '+n); 
    }, false); 
    xhr.open('POST','upload.php'); 
    xhr.setRequestHeader('Cache-Control','no-cache'); 
    xhr.setRequestHeader('X-Requested-With','XMLHttpRequest'); 
    xhr.setRequestHeader('X-File-Name',file.name); 
    xhr.send(file); 
    } 
    else {var ns = true;} 
} 

if (ns) {alert('Error: your browser does not support AJAX file uploads.');} 
} 

私は何らかの説明をして投票を行い、有効な回答を受け入れることができます。

はい、私はテストしているもののコンテキストを知っています(Firefox 10、Chrome 17(?)、Opera 12でテストしています)。

+0

なぜ 'progress'イベントを使用していますか?代わりに 'readystatechange'イベントを使うでしょうか? – fcalderan

+0

readystatechangeイベントは私の質問とは関係ありません。私は実際には、リモートでも同様の状況でも問題を再現する別の方法を決定する時間がありません。 – John

答えて

2

は、以下の2つのスニペットを考えてみましょう:

var i; 

for (i = 0; i < 5; i += 1) { 
    setTimeout(function() { 
     // here, i will be the loop variable, and thus you'll get 
     // an ouput of 5, 5 times, because by the time this function will be 
     // called, the loop will be long finished 
     console.log(i); 
    }, 250); 
} 

for (i = 0; i < 5; i += 1) { 
    setTimeout(function (i) { 
     return function() { 
      // here, i will be the function parameter of the outer function 
      // which has been called immediately passing in a 'copy' of 
      // the loop variable. 
      // output will be: 0, 1, 2, 3, 4 
      console.log(i); 
     }; 
    }(i), 250); 
} 
​ 

デモ:http://jsfiddle.net/Hpxqq/

また、これは再帰とは何の関係もありません。

あなたのコードについて

、あなたは変更する必要があります。

upload.addEventListener('progress', function(e,n) 
{ 
    alert('n = '+n); 
}, false); 

へ:Javascriptがブロックスコープを持っていない

upload.addEventListener('progress', function (n) { 
    return function(e) { 
    alert('n = ' + n); 
    }; 
}(n), false); 
+0

私はsetTimeoutを使用したとコメントするつもりでしたが、手頃な価格(肯定的な含意)ではなく安価(否定的な意味合い)と考えています。ときどき動作し、時には動作しない場合があります。あなたの編集であなたがした提案は、Firefox 10ではなくChromeとOpera 12で動作します。 – John

+0

@John setTimeoutは非同期をデモするだけでした。関数呼び出し。ここで注意すべきことは、イベントコールバック関数の範囲です。 ffでデモ・フィドルをチェックすると、正しい出力が得られます。だから私はあなたのスクリプトがffで動作しないようにする何かがあるかもしれないと思います。 – Yoshi

0

...

はこれを試してみてください。

function images_upload(e) { 
    var ns = false; 

    for (var i = 0; i < document.getElementById('post_files').files.length; i++) { 
     (function(i) { 
      var file = document.getElementById('post_files').files[i]; 
      var n = images_name(file.name); 
      var xhr = new XMLHttpRequest(); 

      if (typeof xhr.upload == 'object') { 
       var upload = xhr.upload; 
       upload.addEventListener('progress', function(e, n) { 
        alert('n = ' + n); 
       }, false); 
       xhr.open('POST', 'upload.php'); 
       xhr.setRequestHeader('Cache-Control', 'no-cache'); 
       xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
       xhr.setRequestHeader('X-File-Name', file.name); 
       xhr.send(file); 
      } 
      else { 
       ns = true; 
      } 

     })(i); 
    } 

    if (ns) { 
     alert('Error: your browser does not support AJAX file uploads.'); 
    } 
} 
関連する問題