0

バナーには、clickTag1、clickTag2、clickTag3 などの名前を持つ 3 つの clickTag を追加する必要があります。コードは次のようになります。

for(var i = 1; i <= 3; i++) {
    document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
        window.open(clickTag2, '_blank'); //here I want clickTag look like clickTag + i, but its not working.
    })
  }

問題は、変数名をループする方法です。現在のように、手動で配置する必要はありません。

4

3 に答える 3

1

これには配列を使用します。配列は、インデックス付きの値のリストです。

var clickTags = ["","www.nba.com","www.nhl.com","www.nfl.com"];
for(var i = 1; i <= 3; i++) {
    document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
        window.open(clickTags[i], '_blank'); //here I want clickTag look like clickTag + i, but its not working.
    })
}

1ではなく でループを開始しているため、配列0のインデックス 0 に空白のエントリを追加したことに注意してください。clickTags

于 2016-12-06T23:13:48.430 に答える
1

現在、意図したとおりに機能していない理由:

for (var i = 1; i <= 3; i++) {
  // During your first loop there is a local variable `i` whose value is 1
  document.getElementById('Destination_cta_' + i)
    // Here you pass an anonymous function as the second argument to addEventListener
    // This creates a closure, which means the function's context includes variables
    // that were in scope when it was created. Right now we have the `for` loop's variable
    // `i` in the current scope, so the function keeps a *reference* to that variable.
    .addEventListener('click', function() {
     
      // When this get executed in the future, the function has to know about the variable `i`,
      // and thankfully there is a reference to it in this function's closure. But remember that
      // the for loop executed 3 times, using that same variable. That means that every function
      // was created with a closure that is keeping a reference to the same variable, whose final 
      // value after the loop finished, was 4. 
      window.alert('clickTag' + i);  // Will always alert 'clickTag4' no matter which is clicked
  })
}
<div id="Destination_cta_1">1</div>
<div id="Destination_cta_2">2</div>
<div id="Destination_cta_3">3</div>

この問題を解決するには?

addEventListener呼び出しが、独自のクロージャーで正しい値を持つ関数を取得することを確認してください。これを行う方法は、すぐに呼び出される関数式を使用して、必要な値を渡すことです。

for (var i = 1; i <= 3; i++) {
  var element = document.getElementById('Destination_cta_' + i)

  element.addEventListener('click', (function(index) {
    // This function is now a closure with a reference to index
    return function() { 
      window.alert('clickTag' + index);
    }
  })(i)) // calling the anonymous function with the current value of `i` binds that value
         // to the function's scope
}
<div id="Destination_cta_1">1</div>
<div id="Destination_cta_2">2</div>
<div id="Destination_cta_3">3</div>

于 2016-12-06T23:41:22.193 に答える
1

この問題を解決する最もクリーンな方法は、Arrayを使用することです。

[, clickTag1, clickTag2, clickTag3].forEach(function(e, i) {
    document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
        window.open(e, '_blank');
    })
})

別の方法: s がグローバル変数の場合、オブジェクトclickTagのグローバル プロパティとしていつでもアクセスできます。window

for(var i = 1; i <= 3; i++) (function (i) {
    document.getElementById('Destination_cta_' + i).addEventListener('click', function() {
        window.open(window['clickTag' + i], '_blank')
    })
)(i)

追加のラッピング機能により、上記のコメントで言及された閉鎖バグが修正されます。

于 2016-12-06T23:16:41.747 に答える