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>
添加回答
舉報