1

私はこのコードを持っています.andのようなJS関数を取り入れようとしてclassListquerySelectorますが、ハンドラのループなどのために非常に冗長になります:

var cg = document.querySelectorAll('.control-group'),
    cgL = cg.length;

while (cgL--) {
    var _cg = cg[cgL],
        inputs = _cg.querySelectorAll('input'),
        i = 0;

    for (l = inputs.length; i < l; i++) {
        inputs[i].addEventListener('focus', focus, false);
        inputs[i].addEventListener('blur', focus, false);
    }

    function focus() {
        _cg.classList.toggle('focus');
    }
}

フィドル: http://jsfiddle.net/YGeh5/3/

各要素にイベント ハンドラーを割り当てるために NodeList をループする必要を回避する方法はありますか?

4

3 に答える 3

3

You could use Array.forEach(). But since you have a NodeList returned, and does not have forEach() in its prototype, you need to use .call and provide it as context.

However, it's ES5. Most modern browsers have it though. Also, the polyfill is also a loop, just abstracted from you.

Here's your code, pretty much directly converted to use the forEach():

var cg = document.querySelectorAll('.control-group');

Array.prototype.forEach.call(cg, function (group) {
  var inputs = group.querySelectorAll('input');

  function focus() {
    group.classList.toggle('focus');
  }

  Array.prototype.forEach.call(inputs, function (input) {
    input.addEventListener('focus', focus, false);
    input.addEventListener('blur', focus, false);
  });

});
于 2013-05-23T11:23:20.927 に答える
1

ブラウザに がArray#forEachある場合は、NodeList を反復処理するために forEach を使用できます。最初に配列に変換する必要があります。これを行う 1 つの方法は、Array.prototype.slice を使用することです。

Array.prototype.slice.call(_cg.querySelectorAll('input'), 0).forEach(function (input) {
    input.addEventListener('focus', focus, false);
});

または、NodeList で Array.prototype.forEach を呼び出すだけです。

Array.prototype.forEach.call(_cg.querySelectorAll('input'), function (input) {
    input.addEventListener('focus', focus, false);
});

2 つの querySelectorAll を 1 つのクエリにグループ化できることに注意してください。

要素への参照が実際には必要ないため、フォーカス クロージャをループの外に移動することもできます。

そして、コード全体は次のようになります。

function focus(event) {
    event.target.classList.toggle('focus');
}

Array.prototype.forEach.call(document.querySelectorAll('.control-group input'), function (input) {
    input.addEventListener('focus', focus, false);
    input.addEventListener('blur', focus, false);
});
于 2013-05-23T11:24:40.207 に答える