我正在通过一个数组来根据外部设置的状态应用不同的类。这就是我现在的表现,但我觉得自己很重复自己。有干燥的方法吗?如果有帮助的话,类名可能是其他的东西。
var children2 = Array.from(wrapper.children);
var s = state.state;
children2.forEach((child, i) => {
var classes = [];
child.classList.remove('active', 'before', 'previous', 'next', 'after');
if(i < s) { classes.push('before'); };
if(i > s) { classes.push('after'); };
if(i === s) { classes.push('active') }
if(i === s - 1) { classes.push('previous') }
if (i === s + 1) { classes.push('next') }
child.classList.add(...classes)
})
答案 0 :(得分:6)
最简单的解决方案是使用toggle
:
toggle( String [, force] )
当只存在一个参数时:切换类值;即,如果类存在则删除它并返回false,如果不存在,则添加它 返回true。
当存在第二个参数时:如果第二个参数的计算结果为true,则添加指定的类值,如果它的计算结果为 是的,删除它。
例如:
let classes = child.classList;
classes.toggle('before', i < s);
classes.toggle('after', i > s);
classes.toggle('active', i === s);
classes.toggle('previous', i === s-1);
classes.toggle('next', i === s+1);
您还可以创建一个包含键和条件的对象,然后将它循环到toggle
个别区域:
const classes = {
before: i < s,
after: i > s,
active: i === s,
previous: i === s - 1,
next: i === s + 1,
};
Object.entries(classes).forEach(([className, condition]) => child.classList.toggle(className, condition));
(请注意Object.entries
是一项ECMAScript 2017功能。)
答案 1 :(得分:0)
这是一种方式:
var children2 = Array.from(wrapper.children);
var s = state.state;
//Represent your states as StateName-Predicate map
const States = {
'active': (i,s) => i===s,
'before': (i,s) => i<s},
'previous': (i,s) => i===s-1,
'next': (i,s) => i===s+1,
'after': (i,s) => i>s
};
children2.forEach((child, i) => {
const classList = child.classList;
//Iterate over all available states
Object.keys(States).forEach(stateName => {
//Extract predicate function for a state
const predicate = States[stateName];
//If predicate evaluates to true - set class, otherwise - remove it
classList.toggle(stateName, predicate(i,s) );
});
})
答案 2 :(得分:0)
目前在您的代码中有一种模式非常重复:&#34; if(某些条件),添加此类&#34;。你可能会做这样的事情:
var classes = [
i < s && 'before',
i > s && 'after',
i === s && 'active',
i === s - 1 && 'previous',
i === s + 1 && 'next'
].filter(x => x)
该代码的第一部分var classes = [...]
通过有条件地添加项目来创建类似[false, false, 'active', false, false]
的数组。例如,假设i
为3而s
也为3.当JavaScript评估i === s && 'active'
时,它会看到i (3) === s (3)
,因此它会转到下一个值,即'active'
,并将其粘贴在数组中。在评估i === s + 1 && 'next'
时,它会发现i (3)
不与s + 1 (4)
相同,因此它会立即显示为false并将其添加到列表中。
然后,我们使用filter
来删除那些false
项,因此我们得到一个更像['active']
的数组。基本上,filter接受一个函数并将数组项中的每一个逐个传递给它;当函数返回truthy值时,它会保留项目,否则会删除该项目。我们传递的函数是arrow function;它只返回传递给它的值。您可以将其替换为function(x) { return x }
,它在功能上也是相同的。
(我有时会使用.filter(Boolean)
代替.filter(x => x)
。Boolean可以用作将值转换为布尔值的函数(根据上面的"truthy"链接) - 如果您以前见过!!x
syntax,它会做同样的事情。我发现.filter(Boolean)
更多语法:&#34;保持真实的项目(如布尔值)&#34;。但这完全没有必要,因为filter
本身会自动检查你的函数的返回值是否真实。所以如果你使用它只是一个品味问题!)
另一种选择是摆脱不必要的括号和分号,如下所示:
if (i < s) classes.push('before')
if (i > s) classes.push('after')
// ..and so on.
它肯定有点冗长,但无论如何你可能更喜欢它!