[英]Is there a shorter more concise way to hide & show div with Javascript?
我正在創建一個儀表板,其中包含大約 20 個以“display: none;”開頭的 div。
當使用側邊欄中的 .onClick() 時,它將顯示特定的 div 並隱藏所有其他 div。 我使用了為每個 div 創建一個函數的經典解決方案,但是非常冗長,代碼看起來很亂。
有沒有更好更簡潔的方法來使用 Javascript 實現這一目標?
這是我的代碼:
function presale() { var x = document.getElementById("presale"); var y = document.getElementById("claim"); var z = document.getElementById("stake"); if (x.style.display === "grid") { x.style.display = "none"; } else { x.style.display = "grid"; y.style.display = "none"; z.style.display = "none"; } } function claim() { var x = document.getElementById("presale"); var y = document.getElementById("claim"); var z = document.getElementById("stake"); if (y.style.display === "grid") { y.style.display = "none"; } else { x.style.display = "none"; y.style.display = "grid"; z.style.display = "none"; } } function stake() { var x = document.getElementById("presale"); var y = document.getElementById("claim"); var z = document.getElementById("stake"); if (z.style.display === "grid") { z.style.display = "none"; } else { x.style.display = "none"; y.style.display = "none"; z.style.display = "grid"; } }
*, html { color: #fff; background-color: black; } #presale, #claim, #stake /* Here I have many other divs like below */ { display: none; }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script> <link rel="stylesheet" href="MOD.CSS"> <script src="main2.js"></script> <title>Base Template</title> </head> <body> <div> <ul> <!-- Here I have other 20 options like the above --> <li onclick="presale()">Presale</li> <li onclick="claim()">Claim</li> <li onclick="stake()">Stake</li> <!-- Here I have other 20 options like the above --> </ul> <div id="presale"> <h1>Presale</h1> </div> <div id="claim"> <h1>Claim</h1> </div> <div id="stake"> <h1>Stake</h1> </div> </div> </body> </html>
有沒有更好的方法來做到這一點,而無需創建一個函數並為每個 div 一遍又一遍地重復相同的事情?
在這里,您會看到一個普通的 Javascript 解決方案。
默認情況下, content
div 是隱藏的。
如果單擊一個元素,則相應的data-id
會得到類show
。
window.onload = function () { document.querySelectorAll('#nav li').forEach((elements) => { elements.addEventListener('click', (el) => { document.querySelectorAll('.content').forEach((item) => { // hide all item.classList.remove('show'); }); // show one document.getElementById(el.target.getAttribute('data-id')).classList.add('show'); }); }); };
.content { display: none; } .show { display: block; }
<ul id="nav"> <li data-id="presale">Presale</li> <li data-id="claim">Claim</li> <li data-id="stake">Stake</li> </ul> <div id="presale" class="content"> <h1>Presale</h1> </div> <div id="claim" class="content"> <h1>Claim</h1> </div> <div id="stake" class="content"> <h1>Stake</h1> </div>
根本不需要JS。 您可以簡單地使用錨點並將#id
用作超參考。 然后,您可以使用:target
-selector 通過 CSS 顯示元素:
*, html { color: #fff; background-color: black; } .d-none /* Here I have many other divs like below */ { display: none; } div:target { display: grid; }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script> <link rel="stylesheet" href="MOD.CSS"> <script src="main2.js"></script> <title>Base Template</title> </head> <body> <div> <ul> <!-- Here I have other 20 options like the above --> <li><a href ="#presale">Presale</a></li> <li><a href ="#claim">Claim</a></li> <li><a href ="#stake">Stake</a></li> <!-- Here I have other 20 options like the above --> </ul> <div id="presale" class="d-none"> <h1>Presale</h1> </div> <div id="claim" class="d-none"> <h1>Claim</h1> </div> <div id="stake" class="d-none"> <h1>Stake</h1> </div> </div> </body> </html>
像這樣使用數據屬性和類列表切換的東西也應該起作用。
我會考慮通過使用通用 CSS 選擇器來隱藏/顯示各個部分來最小化您的代碼(和 CSS)。 這也使下一個人更容易實現可擴展性和可維護性。
這有一個額外的好處,即您的樣式可以 100% 使用 CSS 進行控制,而不是由 javascript 設置的任意內聯樣式。
添加另一個部分也很容易:
awesome-section
)data-toggle-section
的導航條目,其 id 為值<li data-toggle-section="awesome-section">Awesome Section</li>
您也不限於僅使用 nav 元素本身,因為事件偵聽器是使用[data-toggle-section]
選擇器綁定的,這意味着基本上任何東西都可以顯示或隱藏一個部分,只要它具有正確的屬性價值。
const buttons = Array.from(document.querySelectorAll("[data-toggle-section]")); const sections = buttons.map(element => { return document.getElementById(element.dataset.toggleSection) }); buttons.forEach(element => { element.addEventListener('click', event => { const selected = element.dataset.toggleSection; sections.forEach(section => { if(section.id === selected) { section.classList.toggle('shown'); } else { section.classList.remove('shown'); } }) }); });
*, html { color: #fff; background-color: black; } .option-section { display: none; } .option-section.shown { display: grid; }
<div> <ul> <!-- Here I have other 20 options like the above --> <li data-toggle-section="presale">Presale</li> <li data-toggle-section="claim">Claim</li> <li data-toggle-section="stake">Stake</li> <!-- Here I have other 20 options like the above --> </ul> <div id="presale" class="option-section"> <h1>Presale</h1> </div> <div id="claim" class="option-section"> <h1>Claim</h1> </div> <div id="stake" class="option-section"> <h1>Stake</h1> </div> </div>
您可以簡單地將相同的類(例如my_div
)分配給每個可顯示的div
,然后將id
傳遞給您的函數(這將顯示並隱藏所有其他類)。
function show_hide(id) { document.querySelectorAll('.my_div').forEach(my_div => { my_div.style.display = my_div.getAttribute('id') == id ? 'block' : 'none'; }); }
.my_div { display: none; }
<div> <ul> <li onclick="show_hide('presale')">Presale</li> <li onclick="show_hide('claim')">Claim</li> <li onclick="show_hide('stake')">Stake</li> </ul> <div class="my_div" id="presale"> <h1>Presale</h1> </div> <div class="my_div" id="claim"> <h1>Claim</h1> </div> <div class="my_div" id="stake"> <h1>Stake</h1> </div> </div>
這是代碼審查部分的問題https://codereview.stackexchange.com/
但是,您可以像這樣嘗試:
const elems = ["presale", "claim", "stake"];
function toggle(elem) {
elems.map(i => {
let el = document.getElementById(i);
el.style.display = "none";
});
let active_el = document.getElementById(elem);
active_el.style.display = "grid";
}
並在 html 中添加 elem 名稱作為參數,因此,替換它
<li onclick="presale()">Presale</li>
<li onclick="claim()">Claim</li>
<li onclick="stake()">Stake</li>
有了這個
<li onclick="toggle('presale')">Presale</li>
<li onclick="toggle('claim')">Claim</li>
<li onclick="toggle('stake')">Stake</li>
這是我的嘗試。 這與@ztom 的答案明顯相同,但我嘗試避免使用foreach
。
document.querySelectorAll("li").forEach(e => e.addEventListener("click", () => { let shown = document.querySelector(".action:not(.d-none)") if(shown){ shown.classList.add("d-none") if(e.dataset.id != shown.id){ document.getElementById(e.dataset.id).classList.remove("d-none") } }else{ document.getElementById(e.dataset.id).classList.remove("d-none") } }))
.action{ display:grid; } .d-none{ display:none; }
<ul> <li data-id="presale">Presale</li> <li data-id="claim">Claim</li> <li data-id="stake">Stake</li> </ul> <div class="action d-none" id="presale">Presale</div> <div class="action d-none" id="claim">Claim</div> <div class="action d-none" id="stake">Stake</div>
當涉及在多個元素上使用相同的邏輯時,請使用類而不是 id,並且默認情況下會縮短您的解決方案。
使用jQuery
,它基本上是一個 2-liner:
在 CSS 中,使用display:none;
創建一個.hidden
類; 您的div
和li
元素也應該使用類進行分組。
然后您可以簡單地引用這些類並通過以下方式添加顯示/隱藏邏輯:
$('h1:contains('+$(this).text()+')').parent().toggleClass("hidden");
$('h1:not(:contains('+$(this).text()+'))').parent().addClass("hidden");
$('document').ready(function(){ $('.toggle').on('click',function(){ $('h1:contains('+$(this).text()+')').parent().toggleClass("hidden"); $('h1:not(:contains('+$(this).text()+'))').parent().addClass("hidden"); }); });
*, html { color: #fff; background-color: black; } .hidden { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <link rel="stylesheet" href="MOD.CSS"> <script src="main2.js"></script> <title>Base Template</title> </head> <body> <div> <ul> <!-- Here I have other 20 options like the above --> <li class="toggle">Presale</li> <li class="toggle">Claim</li> <li class="toggle">Stake</li> <!-- Here I have other 20 options like the above --> </ul> <div class="hidden"> <h1>Presale</h1> </div> <div class="hidden"> <h1>Claim</h1> </div> <div class="hidden"> <h1>Stake</h1> </div> </div> </body> </html>
如果您將數據屬性附加到列表項和“面板”,您可以使用一個函數來匹配它們,並使用 CSS 類來確定它是否應該處於活動狀態。
// Cache the elements, the panels container, and the list element // separately adding one event listener to the list. We're using // event delegation for this - one listener captures all // the events from its child elements const allElements = document.querySelectorAll('.list li, .panels .panel'); const panels = document.querySelector('.panels'); const list = document.querySelector('ul'); list.addEventListener('click', handlePanel); // When the listener is triggered function handlePanel(e) { // Check if it's a list item if (e.target.matches('li')) { // Destructure its id from the dataset const { id } = e.target.dataset; // Remove all the active classes from the elements allElements.forEach(el => el.classList.remove('active')); // And then add an active class to the list item, // and the panel where their ids match const selector = `[data-id="${id}"]`; const item = list.querySelector(`li${selector}`); const panel = panels.querySelector(`.panel${selector}`); item.classList.add('active'); panel.classList.add('active'); } }
.panel { display: none; } .panel h1 { font-size: 1.2em; color: darkblue; } ul { list-style-type: none; margin-left: 0; padding: 0; } li { padding: 0.3em; border: 1px solid white; } li:hover { background-color: thistle; cursor: pointer; } li.active { border: 1px solid #454545; background-color: lightyellow; } .panel.active { display: block; }
<ul class="list"> <li data-id="presale">Presale</li> <li data-id="claim">Claim</li> <li data-id="stake">Stake</li> </ul> <div class="panels"> <div data-id="presale" class="panel"> <h1>Presale</h1> </div> <div data-id="claim" class="panel"> <h1>Claim</h1> </div> <div data-id="stake" class="panel"> <h1>Stake</h1> </div> </div>
附加文件
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.