为了让我的代码更干燥,我决定采用我经常使用的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));
任何对我做错事情的见解都将不胜感激。按照惯例,我觉得解决方案可能很简单:我只是没有看到它。
答案 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);
});
请注意addClass
和removeClass
如何返回可用作事件处理程序的函数。将它们存储到activate
和deactivate
变量意味着您不在循环内创建函数的多个等效副本,但事实上将相同的函数分配给所有元素。
通过实现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)
您的代码存在以下问题:
mouseover
上想要将元素的类更改为活动状态。在这种情况下,addClass
函数必须返回另一个函数,但是常规函数,而不是胖箭头,因此可以正确绑定。你真的想在这一行上按位:
this.classList.remove('active') & this.classList.add(className)
或逻辑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>