0

onmouseover箇条書きにイベントを追加する次のコードがありますonload

for (var i = 0; i <= 3; i++) {
    document.getElementById('menu').getElementsByTagName('li')[i].onmouseover = function () { addBarOnHover(i); };
}

これが呼び出している関数です。マウスが上に移動すると、メニュー項目に css クラスが追加されるはずです。

function addBarOnHover(node) {
    document.getElementById('menu').getElementsByTagName('li')[node].className = "current_page_item"; }

関数が呼び出されると、エラーが発生し続けます。

"document.getElementById("menu").getElementsByTagName("li")[ノード] は未定義です"

私を困惑させているのは、addBarOnHover関数に alert(node) ステートメントを追加して、パラメーターの値が何であるかを確認したことです。アラートは、渡されたパラメーターの値が 4 であると述べました。私が設定したループでこれがどのように発生するかはわかりません。

どんな助けでも大歓迎です。

4

2 に答える 2

4

これは、反復変数を閉じるときによくある問題です。for反復変数の値をキャプチャするために、追加のメソッドで本体をラップします。

for (var i = 0; i <= 3; i++) {
  (function(i){ //here
    document.getElementById('menu').getElementsByTagName('li')[i].onmouseover = function () { addBarOnHover(i); };
  })(i); //here
}

ループに入るたびに無名関数が作成され、反復変数の現在の値が渡されます。匿名関数の内部は、外部スコープではiなく、この関数の引数を参照します。i

わかりやすくするために、内部変数の名前を変更することもできます。

for(var i=0; i<=3; i++){
  (function(ii){
    //use ii as i
  })(i)
}

反復変数をキャプチャせずiに、匿名ハンドラで最終的に使用されるときの値はすでにに変更されてい4ます。iハンドラーのすべてのインスタンス間で共有される、外部スコープには1つだけがあります。匿名関数で値を取得する場合は、代わりにその関数の引数が使用されます。

于 2012-11-15T03:22:14.403 に答える
1

iは(値ではなく)参照として渡されているため、onmouseoverコールバックが呼び出されると、の値iはすでに。になってい4ます。

別の関数を使用してコールバック関数を作成する必要があります。

var menu = document.getElementById('menu');
var items = menu.getElementsByTagName('li');

for (var i = 0; i <= 3; i++) {
    items[i].onmouseover = (function(i) {
        return function() {
            addBarOnHover(i);
        };
    })(i);
}

ヘルパー関数を作成することで、もう少し読みやすくすることができます。

var createCallback = function(i) {
    return function() {
        addBarOnHover(i);
    };
};

for (var i = 0; i <= 3; i++) {
    items[i].onmouseover = createCallback(i);
}
于 2012-11-15T03:21:34.040 に答える