在forEach循环中使用带参数的函数

cps*_*nte 3 javascript foreach function

为了让我的代码更干燥,我决定采用我经常使用的if/else语句并将其转换为函数.我尝试将此函数应用于forEach循环,但是,我收到一个错误,函数的参数未定义.

这是代码:

var addClass = (className) => {
    (this.classList.contains(className) === true)
        ? this.classList.remove('active') & this.classList.add(className)
        : this.classList.add(className);
}

exploreStory_buttons.forEach(el => el.addEventListener('mouseover'), addClass(active));
Run Code Online (Sandbox Code Playgroud)

任何洞察我做错的事情都将不胜感激.按照惯例,我觉得解决方案可能很简单:我只是没有看到它.

Tom*_*lak 6

您想在适当的上下文中调用该函数.就是Function#call为了这个目的.您还需要使用普通函数,因为"胖箭头"函数的处理方式this不同.

var addClass = function (className) {
    if (this.classList.contains(className)) {
        this.classList.remove('active');
        this.classList.add(className);
    } else {
        this.classList.add(className);
    }
}

exploreStory_buttons.forEach(el => {
    el.addEventListener('mouseover'); // where is the event listener??
    addClass.call(this, active);   // N.B. active is undefined here. Do you mean "active"?
});
Run Code Online (Sandbox Code Playgroud)

您也不想滥用语言功能来编写"智能"代码.对多个语句使用if/else和多行,您不是代码混淆器.


假设您要添加"悬停"行为,代码看起来像这样:

function addClass(className) {
    return function () {
        this.classList.add(className);
    }
}
function removeClass(className) {
    return function () {
        this.classList.remove(className);
    }
}

var activate = addClass('active');
var deactivate = removeClass('active');

exploreStory_buttons.forEach(el => {
    el.addEventListener('mouseenter', activate);
    el.addEventListener('mouseleave', deactivate);
});
Run Code Online (Sandbox Code Playgroud)

注意如何addClassremoveClass返回可以作为事件处理程序的函数.将它们存储到activatedeactivate变量意味着你没有创建循环内一个函数的多个拷贝等同,但实际上分配相同功能的所有元素.


activate/ deactivate变量和函数返回功能可以通过实现一个可以避免hover()功能(jQuery有一个类似的功能):

function hover(elements, onenter, onleave) {
    elements.forEach(el => {
        el.addEventListener('mouseenter', onenter);
        el.addEventListener('mouseleave', onleave);
    });
}

hover(exploreStory_buttons, function () {
    this.addClass('active');
}, function () {
    this.removeClass('active');
});
Run Code Online (Sandbox Code Playgroud)

这里,事件处理函数只创建一次,直接在需要它们的地方创建.比将它们存储在辅助变量中要好得多.