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

时间:2017-10-03 15:10:42

标签: javascript function foreach

为了让我的代码更干燥,我决定采用我经常使用的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));

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

2 个答案:

答案 0 :(得分: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"?
});

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

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

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

请注意addClassremoveClass如何返回可用作事件处理程序的函数。将它们存储到activatedeactivate变量意味着您不在循环内创建函数的多个等效副本,但事实上将相同的函数分配给所有元素。

通过实现activate函数(jQuery有similar feature)可以避免deactivate / hover()变量和函数返回函数:

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

此处事件处理函数仅在需要时创建一次并直接创建。比将它们存储在辅助变量中要好得多。

答案 1 :(得分:1)

您的代码存在以下问题:

  1. 我假设您在mouseover上想要将元素的类更改为活动状态。在这种情况下,addClass函数必须返回另一个函数,但是常规函数,而不是胖箭头,因此可以正确绑定。
  2. 你真的想在这一行上按位:

    this.classList.remove('active') & this.classList.add(className)

  3. 或逻辑AND?

    exploreStory_buttons = document.getElementsByClassName('explore-story');
    var addClass = (className) => function() {
        this.classList.contains(className)
            ? (this.classList.remove('active') && this.classList.add(className))
            : this.classList.add(className);
    }
    
    
    Array.prototype.forEach.call(exploreStory_buttons, (el) => el.addEventListener('mouseover', addClass.call(el, 'active')));
    .active {
      color: red
    }
    <button class="explore-story active">Story 1</button>
    <button class="explore-story">Story 2</button>