5 回答
TA贡献1779条经验 获得超6个赞
如果您试图确保当前单击的项目变为打开状态,则需要首先确保关闭所有匹配的现有元素.dn
。您的代码仅解决第一个问题。
您的代码从未open
从任何 div 中删除。
最后,有两件事将极大地改进你的代码:
事件委托:这样您只需要一个处理程序
使用数据属性将按钮与其 div 相关联(其他人建议使用索引,这是可以的,但大多数人尝试远离并行数组)
document.getElementById('mainBOX').addEventListener('click', (e)=> {
// Ignore clicks not on buttons
if (e.target.tagName !== 'BUTTON') {
return;
}
// Close all divs
Array.from(document.querySelectorAll('.dn')).forEach(
dn => dn.classList.remove('open')
);
// Open the current one
document.querySelector('.' + e.target.dataset.for).classList.add('open');
});
.dn {
display: none;
}
.open {
display: block;
}
<div id="mainBOX" class="mainBOX">
<button data-for="content1" class="btn">btn1</button>
<button data-for="content2" class="btn">btn2</button>
<button data-for="content3" class="btn">btn3</button>
<div class="dn content1">
<h1>Lorem Ipsum</h1>
</div>
<div class="dn content2">
<h1>Lorem Ipsum2</h1>
</div>
<div class="dn content3">
<h1>Lorem Ipsum3</h1>
</div>
</div>
TA贡献1878条经验 获得超4个赞
我只是通过索引来定位你的 div:
$('.btn').click(function() {
// get the zero-based index of the clicked element
let index = $(this).index();
// hide all divs inside the container and remove the 'open' class
$('#mainBOX div').hide().removeClass('open');
// show just the div with the right index and add the 'open' class
$('#mainBOX div').eq(index).show().addClass('open');
});
.dn {
display: none;
}
<script
src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha256-4+XzXVhsDmqanXGHaHvgh1gMQKX40OUvDEBTu8JcmNs="
crossorigin="anonymous"></script>
<div id="mainBOX" class="mainBOX">
<button class="btn one">btn1</button>
<button class="btn two">btn2</button>
<button class="btn three">btn3</button>
<div class="dn content1">
<h1>Lorem Ipsum</h1>
</div>
<div class="dn content2">
<h1>Lorem Ipsum2</h1>
</div>
<div class="dn content3">
<h1>Lorem Ipsum3</h1>
</div>
</div>
总结一下:
使用 DOM 遍历来定位元素而不是特定的类名
使用类名来标识相似元素的集合
不必费心使用类来切换可见性(除非您想要精致的动画)
如果使用 jQuery,请熟悉它提供的常用方法,这样您就不会重新发明轮子
不必将开放类和非开放类分开,只需将其中一个设为默认并应用另一个即可
不要在代码中重复自己
TA贡献1776条经验 获得超12个赞
我已经使用forEach()方法和toggle()每个内容的方法缩短了您的代码。
有必要吗?
const btn = document.querySelectorAll('.btn');
const content = document.querySelectorAll('.dn');
Array.from(btn).forEach(function(btnArray, i) {
btnArray.addEventListener('click', function() {
content[i].classList.toggle('open');
});
});
.dn {
display: none;
}
.open {
display: block;
}
<div id="mainBOX" class="mainBOX">
<button class="btn one">btn1</button>
<button class="btn two">btn2</button>
<button class="btn three">btn3</button>
<div class="dn content1">
<h1>Lorem Ipsum</h1>
</div>
<div class="dn content2">
<h1>Lorem Ipsum2</h1>
</div>
<div class="dn content3">
<h1>Lorem Ipsum3</h1>
</div>
</div>
TA贡献1803条经验 获得超6个赞
看看这个。使用 forEach 函数处理具有特定类的所有按钮中的单击事件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hide and show</title>
<style>
.dn {
display: none;
}
.btn {
margin-right: 10px;
}
.open {
display: block;
}
</style>
</head>
<body>
<!-- Sample with three contents -->
<div id="c1" class="dn content">
<h1>Content 1</h1>
</div>
<div id="c2" class="dn content">
<h1>Content 2</h1>
</div>
<div id="c3" class="dn content">
<h1>Content 3</h1>
</div>
<!-- Sample with three buttons -->
<button id="btn1" class="action-btn">Button 1</button>
<button id="btn2" class="action-btn">Button 2</button>
<button id="btn3" class="action-btn">Button 3</button>
<button id="clean" class="action-btn">Limpiar</button>
<script>
const buttons = document.querySelectorAll(".action-btn");
const contents = document.querySelectorAll(".content");
buttons.forEach(function (item) {
item.addEventListener("click", function (e) {
if (item.id === "clean") {
contents.forEach((item) => item.classList.remove("open")); // Clean all the open classes
} else {
contents.forEach((item) => item.classList.remove("open"));
switch (item.id) {
case "btn1":
const c1 = document.getElementById("c1");
if (!c1.classList.contains("open")) {
c1.classList += " open";
}
break;
case "btn2":
const c2 = document.getElementById("c2");
if (!c2.classList.contains("open")) {
c2.classList += " open";
}
break;
case "btn3":
const c3 = document.getElementById("c3");
if (!c3.classList.contains("open")) {
c3.classList += " open";
}
break;
}
}
});
});
</script>
</body>
</html>
TA贡献1864条经验 获得超6个赞
好吧,我从头开始重写了我的贡献,因为我一开始没有正确阅读 OP 需求。
毫无疑问,@isherwood 的答案应该是这里可接受的答案,因为它使用了单击按钮的索引,并且因为它使用了 jQuery,这使得脚本更容易阅读!
然而,在我的贡献中,我想表明,即使没有 jQuery,同样的事情也是可能的。诚然,事情变得有点复杂:
整个操作发生在 IIFE ( (function(){...})()
) 内,以保持全局名称空间干净。mBox
是#mainBox
我为所有 s 附加委托单击事件的 DOM 元素BUTTON
。
mBox
每次触发单击事件处理程序时,它都会收集数组中的所有按钮btns
(该[...mBox.SelectorAll()]
构造对于从返回的集合创建 JavaScript 数组是必需的.querySelectorAll()
)。
odiv
是先前操作中(可能)打开的 div,需要通过open
从中删除类来再次关闭。
最终该类open
被添加到div
与行中单击的按钮具有相同索引的位置
mBox.querySelectorAll('div')[btns.indexOf(ev.target)].classList.add('open');
通过使用委托事件侦听并在每次单击后检查可用的button
s 和div
s ,可以动态地将按钮和 div 添加到页面,而无需将事件侦听器附加到这些元素。
(function(){
const mBox=document.getElementById('mainBOX');
mBox.onclick=ev=>{
const btns=[...mBox.querySelectorAll('button')];
if (ev.target.tagName=="BUTTON"){
let odiv=mBox.querySelector('div .open')
if (odiv) odiv.classList.remove('open');
mBox.querySelectorAll('div')[btns.indexOf(ev.target)].classList.add('open');
}
}
})()
.dn { display: none; }
.open { display: block;}
<div id="mainBOX" class="mainBOX">
<button class="btn one">first </button>
<button class="btn two">second</button>
<button class="btn three">third</button>
<button class="btn four">fourth</button>
<button class="btn five">fifth</button>
<button class="btn six">sixth</button>
<button class="btn seven">seventh</button>
<button class="btn eight">eighth</button>
<button class="btn nine">nineth</button>
<button class="btn ten">tenth</button>
<div class="dn content1">
<h1>Lorem Ipsum</h1>
</div>
<div class="dn content2">
<h1>Lorem Ipsum2</h1>
</div>
<div class="dn content3">
<h1>Lorem Ipsum3</h1>
</div>
<div class="dn content4">
<h1>Lorem Ipsum4</h1>
</div>
<div class="dn content5">
<h1>Lorem Ipsum5</h1>
</div>
<div class="dn content6">
<h1>Lorem Ipsum6</h1>
</div>
<div class="dn content7">
<h1>Lorem Ipsum7</h1>
</div>
<div class="dn content8">
<h1>Lorem Ipsum8</h1>
</div>
<div class="dn content9">
<h1>Lorem Ipsum9</h1>
</div>
<div class="dn content10">
<h1>Lorem Ipsum10</h1>
</div>
</div>
添加回答
举报