Javascript 避免在JS中分配事件处理程序的循环

Javascript 避免在JS中分配事件处理程序的循环,javascript,Javascript,我有这段代码,在其中我尝试使用JS函数,如classList和querySelector,但由于处理程序的循环等,它最终非常冗长: var cg = document.querySelectorAll('.control-group'), cgL = cg.length; while (cgL--) { var _cg = cg[cgL], inputs = _cg.querySelectorAll('input'), i = 0; f

我有这段代码,在其中我尝试使用JS函数,如classList和querySelector,但由于处理程序的循环等,它最终非常冗长:

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');
    }
}
小提琴:

是否有任何方法可以避免在节点列表周围循环以将事件处理程序分配给它的每个元素?

您可以使用。但是,由于您返回了一个节点列表,并且其原型中没有forEach,因此需要使用.call并将其作为上下文提供

然而。还有,只是从你那里抽象出来的

,几乎直接转换为使用forEach:

你可以用。但是,由于您返回了一个节点列表,并且其原型中没有forEach,因此需要使用.call并将其作为上下文提供

然而。还有,只是从你那里抽象出来的

,几乎直接转换为使用forEach:

如果浏览器具有ArrayforEach,则可能需要使用forEach在节点列表上进行迭代。首先必须将其转换为数组。一种方法是使用Array.prototype.slice

Array.prototype.slice.call(_cg.querySelectorAll('input'), 0).forEach(function (input) {
    input.addEventListener('focus', focus, false);
});
或者只需在节点列表上调用Array.prototype.forEach:

Array.prototype.forEach.call(_cg.querySelectorAll('input'), function (input) {
    input.addEventListener('focus', focus, false);
});
请注意,您可以将两个querySelectorAll分组到一个查询中

您还可以将焦点闭包移出循环,因为它实际上不需要对元素的引用

您的整个代码变成:

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);
});
如果浏览器具有ArrayforEach,则可能需要使用forEach在节点列表上进行迭代。首先必须将其转换为数组。一种方法是使用Array.prototype.slice

Array.prototype.slice.call(_cg.querySelectorAll('input'), 0).forEach(function (input) {
    input.addEventListener('focus', focus, false);
});
或者只需在节点列表上调用Array.prototype.forEach:

Array.prototype.forEach.call(_cg.querySelectorAll('input'), function (input) {
    input.addEventListener('focus', focus, false);
});
请注意,您可以将两个querySelectorAll分组到一个查询中

您还可以将焦点闭包移出循环,因为它实际上不需要对元素的引用

您的整个代码变成:

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);
});

您可以将事件委派到“.control group”上,然后按e.target筛选输入。它还将在大量输入上使用更少的内存。工作示例:


您可以将事件委派到“.control group”上,然后按e.target筛选输入。它还将在大量输入上使用更少的内存。工作示例:


你可以创建一个循环函数,然后只写一次循环。。。e、 例如,函数addEventListenerToEverynodeList,eventsArray,funcy你可以创建一个循环函数,然后只写一次循环。。。e、 例如,function addEventListenerToEverynodeList,eventsArray,function很酷,我想你也可以使用nodeName属性:很酷,我想你也可以使用nodeName属性: