ループ、JavaScriptのイベントを添付

私はこれが "クラシック"であることを知っていますが、私はすでにこのテーマに関する別の説明記事を読もうとしましたが、何とかそれをやっています。私は、イベントハンドラと関数をjavascriptループで追加することについて話しています。

ここに問題のあるコードがあります(これはおすすめボックス/自動完成です)

function autoCompleteCB(results) {
document.getElementById('autocom').innerHTML = '';
if (results.length == 0) {
    document.getElementById('autocom').style.display = 'none';
} else {
    document.getElementById('autocom').style.display = 'block';
    var divholders = [];
    for (var i = 0; i < results.length; i++) {
        divholders[i] = document.createElement('div');
        divholders[i].style.width = '350px';
        var divrestext = document.createElement('div');
        divrestext.className = 'autocom0';
        divrestext.innerHTML = results[i][0];
        divholders[i].appendChild(divrestext);
        var divrestype = document.createElement('div');
        divrestype.className = 'autocom1' + results[i][1];
        divrestype.innerHTML = results[i][1];
        divholders[i].appendChild(divrestype);
        divholders[i].attachEvent('onmouseover', (function(i) { return function() { divholders[i].style.backgroundColor='#266699'; }; })(i));
        divholders[i].attachEvent('onmouseout', (function (i) { return function() { divholders[i].style.backgroundColor = '#F5F5F5'; }; })(i));
        document.getElementById('autocom').appendChild(divholders[i]);
    }
}
}

それは(もちろん)動作しないアタシェントラインです。 JavaScriptのこの部分はとても奇妙な/トリッキー:)親切な専門家は、私はそれらの2つの行を修正することができますか?


これは半分の修正です(私は(:

function bindEvent(element, type, listener) {
if (element.addEventListener) {
    element.addEventListener(type, listener, false);
} else if (element.attachEvent) {
    element.attachEvent('on' + type, listener);
}
}
function autoCompleteCB(results) {
document.getElementById('autocom').innerHTML = '';
if (results.length == 0) {
    document.getElementById('autocom').style.display = 'none';
} else {
    document.getElementById('autocom').style.display = 'block';
    var divholders = [];
    for (var i = 0; i < results.length; i++) {
        divholders[i] = document.createElement('div');
        divholders[i].style.width = '350px';
        var divrestext = document.createElement('div');
        divrestext.className = 'autocom0';
        divrestext.innerHTML = results[i][0];
        divholders[i].appendChild(divrestext);
        var divrestype = document.createElement('div');
        divrestype.className = 'autocom1' + results[i][1];
        divrestype.innerHTML = results[i][1];
       //BIND THE EVENTS
        divholders[i].appendChild(divrestype);
        document.getElementById('autocom').appendChild(divholders[i]);
    }
}
}

これは今のように見えますが、まだ "行動"はありません。

function autoComplete() {
var ss = document.getElementById('txbkeyword').value;
if (ss.length > 0) { CSearch.SearchAutoComplete(ss, 3, autoCompleteCB); }
else { document.getElementById('autocom').style.display = 'none'; }

}
function bindEvent(element, type, listener) {
if (element.addEventListener) {
    element.addEventListener(type, listener, false);
} else if (element.attachEvent) {
    element.attachEvent('on' + type, listener);
}
}
function autoCompleteCB(results) {
document.getElementById('autocom').innerHTML = '';
if (results.length == 0) {
    document.getElementById('autocom').style.display = 'none';
} else {
    document.getElementById('autocom').style.display = 'block';
    var divholders = [];
    for (var i = 0; i < results.length; i++) {
        divholders[i] = document.createElement('div');
        divholders[i].style.width = '350px';
        var divrestext = document.createElement('div');
        divrestext.className = 'autocom0';
        divrestext.innerHTML = results[i][0];
        divholders[i].appendChild(divrestext);
        var divrestype = document.createElement('div');
        divrestype.className = 'autocom1' + results[i][1];
        divrestype.innerHTML = results[i][1];
        (function (i) {
            bindEvent(divholders[i], 'mouseover', function() {
                divholders[i].style.backgroundColor = '#266699';
            });
            bindEvent(divholders[i], 'mouseout', function() {
                divholders[i].style.backgroundColor = '#F5F5F5';
            });
        })(i);
        divholders[i].appendChild(divrestype);
        document.getElementById('autocom').appendChild(divholders[i]);
    }
}
}
1
それは働かないアタッチェントラインです(もちろん)。彼らは何のために働かないのでしょうか?
追加された 著者 Felix Kling,
あなたのコードは私にとってうまく見えますが、もっとエレガントな方法があるかもしれません...イベントハンドラをデバッグして、 i の値を確認しましたか?
追加された 著者 Felix Kling,
なぜ this の代わりに i のインデックスを渡していますか?関数は divholders にアクセスできますか?
追加された 著者 Melvin Protacio,
彼らはonmouseoverの色を変更しません
追加された 著者 Jesper,

2 答え

1つの可能性は、 attachEvent がIE-特定。 attachEventListener を他の多くの方法で使用する必要がありますブラウザ。

現在のブラウザに「適切な」方法を使用するには、それらの機能を検出する必要があります( MDNから抜粋):

if (el.addEventListener){
  el.addEventListener('click', modifyText, false);
} else if (el.attachEvent){
  el.attachEvent('onclick', modifyText);
}

これを支援する関数を作成することもできます:

function bindEvent(element, type, listener) {
    if (element.addEventListener) {
        element.addEventListener(type, listener, false);
    } else if (element.attachEvent) {
        element.attachEvent('on' + type, listener);
    }
}

次に、これらの2行の代わりに:

divholders[i].attachEvent('onmouseover', (function(i) { return function() { divholders[i].style.backgroundColor='#266699'; }; })(i));
divholders[i].attachEvent('onmouseout', (function (i) { return function() { divholders[i].style.backgroundColor = '#F5F5F5'; }; })(i));

...関数を使用してハンドラをバインドします(イベント型引数の on をスキップします)。

(function (i) {
    bindEvent(divholders[i], 'mouseover', function() {
        divholders[i].style.backgroundColor = '#266699';
    });
    bindEvent(divholders[i], 'mouseout', function() {
        divholders[i].style.backgroundColor = '#F5F5F5';
    });
})(i);

You could also just enclose the <div>:

(function (div, i) {
    bindEvent(div, 'mouseover', function() {
        div.style.backgroundColor = '#266699';
    });
    bindEvent(div, 'mouseout', function() {
        div.style.backgroundColor = '#F5F5F5';
    });
})(divholders[i], i);
2
追加された
@ジェスパー謝罪。スニペットは、2つの divholders [i] .attachEvent(...); の呼び出し(または //イベントのバインド編集)。
追加された 著者 Jonathan Lonowski,
こんにちは、私は完全にあなたのポイントとクロスブラウザのアタッチイベント機能を参照してください、どのように/最後の2つのスニペットの1つを入れて使用するかわからない...私のループ内に?もう少しお手伝いできますか?私の質問には半分の解決策を入れておきます
追加された 著者 Jesper,
ありがとう、私はそれを考え出した:)しかし、彼らはまだ色を変更しません。最新の書き換えを貼り付けた
追加された 著者 Jesper,
それはうまく動作します。内側のdivに浮動小数点数があるため、それが分かりました。左に0pxの高さで表示されるため、色は変わりません。したがって、divholders [i] .style.overflow = 'hidden'を追加する。すべてがうまくいった。奇妙な問題:)すべての助けをありがとう
追加された 著者 Jesper,

これを試して:

divholders[i].attachEvent('onmouseover', this.style.backgroundColor='#266699');
1
追加された
this.style .... の周りで function(){...} を忘れているかもしれませんが、それでもうまくいきません。 IEは、イベントハンドラがアタッチされている要素に thisholder を設定しません(ただし、 divholders [i] .onmouseover = function(){...}
追加された 著者 Felix Kling,
それでも正しいわけではありません。 obj.style.backgroundColor = '#266699' がすぐに実行され、その結果がイベントハンドラとして設定されます。あなたはおそらく依然としてクロージャの問題を抱えているでしょう。
追加された 著者 Felix Kling,
いいえ、それは簡単ではありません。私は別の範囲にあるからです。それは私のコードとして "ほぼ"見える必要がありますが、いくつかの変更があります...あなたの例では、 'this'は定義されていません
追加された 著者 Jesper,
謝罪;急いでその返信を書いた。なぜ設定しないのですか?var obj = divholders [i]; obj.attachEvent( 'onmouseover'、obj.style.backgroundColor = '#266699');を実行します。
追加された 著者 user879355,
JavaScript - 日本のコミュニティ
JavaScript - 日本のコミュニティ
2 参加者の

日本人コミュニティのjavascript