2017-05-09 19 views
3

私は非常に単純なアプリケーションで作業しています。ユーザーが任意のリスト項目(li)の上を移動すると、テキストの色は緑に変わり、マウスが外に出ると黒に戻ります。引数としての無名関数の範囲

lis[i]を、thisキーワードではなく、匿名関数内の次のコードに使用できないのはなぜですか?

var lis = document.querySelectorAll('li'); 
var i = 0; 
for(; i < lis.length; i++){ 

    lis[i].addEventListener('mouseover', function(){ 

    this.style.color = 'green'; 

    }); 
    lis[i].addEventListener('mouseout', function(){ 

    this.style.color ="black"; 
    }); 
}; 

答えて

2

この関数が呼び出された時点で、ループは完了しています。変数はiに1つしかなく、この関数は常に現在の値を認識します。したがって、関数内からiを使用すると、値lis.lengthが表示されます。

周囲には方法があります。

const lis = document.querySelectorAll('li'); 
for(let i = 0; i < lis.length; i++){ 

    lis[i].addEventListener('mouseover',() => lis[i].style.color = 'green'); 
    lis[i].addEventListener('mouseout',() => lis[i].style.color ="black"); 
}; 

を、今、あなたはループラウンドたびにi異なっを持っている:あなたは(おそらくtranspiler経由)ES2015を使用することができる場合は、書くことができます。

古いコードでは、ループ本体を別の関数にプッシュし、パラメータとしてiを渡すことができます。 、

var lis = document.querySelectorAll('li'); 

var _loop = function _loop(i) { 

    lis[i].addEventListener('mouseover', function() { 
     return lis[i].style.color = 'green'; 
    }); 
    lis[i].addEventListener('mouseout', function() { 
     return lis[i].style.color = "black"; 
    }); 
}; 

for (var i = 0; i < lis.length; i++) { 
    _loop(i); 
} 

コールバック関数が実行される

3

(自動Iは、上記得られたES2015例からバベルにより生成されたコードである)。すなわち、各イベントに対して異なる変数を結合同じ効果を有しますループのため変数の値はlis.lengthになり、lis[i]の値はundefinedになります。

代わりに、forEach関数を使用します。

var lis = document.querySelectorAll('li'); 
 
lis.forEach(function (li) { 
 
    li.addEventListener('mouseover', function(){ 
 
    li.style.color = 'green'; 
 
    }); 
 
    li.addEventListener('mouseout', function(){ 
 
    li.style.color ="black"; 
 
    }); 
 
});
<ul> 
 
    <li>First LI</li> 
 
    <li>Second LI</li> 
 
</ul>

+0

のように現在のターゲットを取得するには、 "e.srcElement" を使用することができ、 '' 'i'''はまだでしょうforループの最後の値(この場合はlis.length、 '' 'lis [i]' '' undefined)に固定されています。これはJavascriptのクロージャによるものです。 @ Duncanの答えを見てください。 –

+1

@MichaelYangそれを指摘してくれてありがとう、私は問題の根よりも解決策に重点を置いていた – Erazihel

+1

もちろん、あなたのソリューションは非常に良いです!私はちょうどそれを指摘したかった:-) –

-1

あなたが実際にこの

let lis = document.querySelectorAll('li'); 
 

 
for (let i = 0; i < lis.length; i++) { 
 
    lis[i].addEventListener('mouseover', function(e){ 
 
    e.srcElement.style.color = 'green'; 
 
    }) 
 
    lis[i].addEventListener('mouseout', function(e){ 
 
    e.srcElement.style.color = 'black'; 
 
    }) 
 
}
<ul> 
 
    <li>First LI</li> 
 
    <li>Second LI</li> 
 
</ul>

+0

彼らはすることができますが、彼らは彼らが尋ねた質問とは関係がありません – Quentin

関連する問題