0

Internet Explorer 7 のノード リスト内の項目に関数をバインドしようとしています。

for(var j = 0; j < navLabels.length; j++)
{
    navInsets[j].onmouseover = function(){showLabel(navLabels[j], true);};
    navInsets[j].onmouseout = function(){showLabel(navLabels[j], false);};
    navInsets[j].onclick = function(){selectNew(j);};
    navLabels[j].onclick = function(){selectNew(j);};
}

showLabel() と selectNew() は、それぞれ独自の関数です。それぞれにインデックス (この場合は j) を渡す必要があります。

無名関数内では、j が j の値ではなく、j への参照になることはわかっています。addEventListener または bind メソッドを使用してこれを行うことができることも知っていますが、どちらも IE 7 では許可されていません。匿名関数内の関数が attachEvent を使用する (少なくともそれが正しいと思われる)。これが元の問題です。

この件に関してハックすぎない考えはありますか?ありがとう。

4

4 に答える 4

3

匿名関数を使用してシャドウしjます。

(function(j) {
    navInsets[j].onclick = function() {selectNew(j);};
    ...
})(j);

jこれにより、関数のスコープ内で値渡しが強制されます。

于 2013-01-29T23:20:50.300 に答える
2

バインドされたイベントごとに必ずしも IIFE を使用する必要はありません。jすべてのイベント バインディングで同じキャプチャを使用できます。

for(var j = 0; j < navLabels.length; j++) {
    (function(j) {
        navInsets[j].onmouseover = function(){showLabel(navLabels[j], true);};
        navInsets[j].onmouseout = function(){showLabel(navLabels[j], false);};
        navInsets[j].onclick = function(){selectNew(j);};
        navLabels[j].onclick = function(){selectNew(j);};
    })(j);
}

それ以上の「きれい」を手に入れることはできないと思います。無名関数を抽出して名前付き関数にすることはできるかもしれませんが ( and と同じスコープ内navInsetsnavLabels)、ループが実際に何をするのかを理解するのが難しくなる可能性があります (使い捨て関数を調べなければならないため)。 . とにかく閉鎖が必要になるので、他の明らかな解決策はありません。

于 2013-01-29T23:24:19.863 に答える
0

コードを見ると、イベントバブリング/委任を利用することで、コードを大幅に最適化できると思います。ある程度の時間を投資する準備ができている場合は、jQuery を学ぶことでおそらく多くのことを得ることができます。

あなたのサイトの HTML コード (および showLabel() と selectNew() の正確な動作) がなければ、私はこれ以上あなたを助けることはできませんが、通常、ナビゲーション リストにクリック アンド マウス オーバー ハンドラーを設定するには、これ;

 $('ul#nav').on('click', 'label', function(){
     selectNew(this);
 });
于 2013-01-29T23:30:12.350 に答える
0

正直なところ、必要なのはインデックスだけであるこのようなケースでは、要素に直接格納します。

for(var j = 0; j < navLabels.length; j++)
{
    navInsets[j].j = j;
    navInsets[j].onmouseover = function(){showLabel(navLabels[this.j], true);};
    navInsets[j].onmouseout = function(){showLabel(navLabels[this.j], false);};
    navInsets[j].onclick = function(){selectNew(this.j);};
    navLabels[j].onclick = function(){selectNew(this.j);};
}

これは非常に軽く、クリーンで高速なソリューションです。要素自体を保存しないでください。リークが発生する可能性があります。

しかし、インデックスだけを保存しても害はなく、クロージャー リークの可能性を回避できます。


また、より良い「DOM トラバーサル」ソリューションがあるかもしれませんが、それはマークアップによって異なります。

于 2013-01-29T23:33:03.720 に答える