Tia*_*usa 8 javascript foreach for-loop
我有一个这样的清单:
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
我需要将活动类分别添加到每个项目中,并在单击时将其从上一个项目中删除。
类似于这个问题Vanilla JS remove class from previous selection但是由于旧的浏览器兼容性,我需要使用 For 循环而不是 ForEach 。
我一直在努力使这个答案适应我的例子:
const items = document.querySelectorAll(".item");
for (let i = 0; i < items.length; i++) {
const item = items[i];
item.addEventListener("click", addActiveClass);
for (let i = 0; i < items.length; i++) {
const item = items[i];
item.addEventListener("click", removeClass);
}
}
function removeClass(e) {
e.target.classList.remove("active");
}
function addActiveClass(e) {
e.target.classList.add("active");
}
Run Code Online (Sandbox Code Playgroud)
但它仍然没有按预期工作:(
我假设您需要从其余项目中删除活动类,然后更新正确的项目。但是,我不确定classList在您寻求支持的旧浏览器中是否可用。你应该考虑的填充工具为老年人bowsers。
const items = document.querySelectorAll(".item");
for (let i = 0; i < items.length; i++) {
const item = items[i];
item.addEventListener("click", changeActiveClass);
}
function changeActiveClass(e)
{
for (let i = 0; i < items.length; i++) {
const item = items[i];
item.classList.remove('active');
}
e.target.classList.add('active');
}
Run Code Online (Sandbox Code Playgroud)
您当前的方法click向元素添加多个处理程序,这些处理程序按顺序依次触发,多次删除和添加类,并且由于嵌套循环而产生不可预测的结果。
现有答案使用 O(n) 解决方案,该解决方案涉及循环列表中的所有元素,但没有必要这样做。只需保留对最后一个选定元素的引用,并.active从该元素中删除类(如果已定义):
const list = [...document.querySelectorAll("ul li")];
let selectedEl;
for (const el of list) {
el.addEventListener("click", e => {
selectedEl && selectedEl.classList.remove("active");
selectedEl = e.target;
e.target.classList.add("active");
});
}Run Code Online (Sandbox Code Playgroud)
.active {
background: yellow;
}Run Code Online (Sandbox Code Playgroud)
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
</ul>Run Code Online (Sandbox Code Playgroud)
另一种方法是为tabindex每个元素设置一个属性,然后为focus和blur(或focusin/focusout如果您想要冒泡)添加侦听器,这可能会更准确地捕获您试图实现的选择/取消选择语义。与click上面显示的事件方法不同,将焦点移到任何地方将取消选择列表项。
for (const el of [...document.querySelectorAll("ul li")]) {
el.addEventListener("focus", e => e.target.classList.add("active"));
el.addEventListener("blur", e => e.target.classList.remove("active"));
}Run Code Online (Sandbox Code Playgroud)
.active {
background: yellow;
outline: none;
}Run Code Online (Sandbox Code Playgroud)
<ul>
<li class="item" tabindex="-1">Item 1</li>
<li class="item" tabindex="-1">Item 2</li>
<li class="item" tabindex="-1">Item 3</li>
</ul>Run Code Online (Sandbox Code Playgroud)
如果您希望支持旧版浏览器,您可以尝试(未经测试):
var list = document.getElementsByTagName("li");
var selectedEl;
for (var i = 0; i < list.length; i++) {
list[i].addEventListener("click", function (e) {
if (selectedEl) {
selectedEl.className = selectedEl.className
.split(/\s+/)
.filter(function (e) { e !== "active"; })
.join(" ");
}
selectedEl = e.target;
e.target.className += " active";
});
}Run Code Online (Sandbox Code Playgroud)
.active {
background: yellow;
}Run Code Online (Sandbox Code Playgroud)
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
</ul>Run Code Online (Sandbox Code Playgroud)
或者
var list = document.getElementsByTagName("li");
for (var i = 0; i < list.length; i++) {
list[i].addEventListener("focusin", function (e) {
e.target.className += " active";
});
list[i].addEventListener("focusout", function (e) {
e.target.className = e.target.className
.split(/\s+/)
.filter(function (e) { e !== "active"; })
.join(" ");
});
}Run Code Online (Sandbox Code Playgroud)
.active {
background: yellow;
outline: none;
}Run Code Online (Sandbox Code Playgroud)
<ul>
<li class="item" tabindex="-1">Item 1</li>
<li class="item" tabindex="-1">Item 2</li>
<li class="item" tabindex="-1">Item 3</li>
</ul>Run Code Online (Sandbox Code Playgroud)