簡體   English   中英

有沒有更簡潔的方法來隱藏和顯示 div 與 Javascript?

[英]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 設置的任意內聯樣式。

添加另一個部分也很容易:

  1. 添加一個帶有一些 id 的新部分(例如awesome-section
  2. 添加一個帶有屬性data-toggle-section的導航條目,其 id 為值<li data-toggle-section="awesome-section">Awesome Section</li>
  3. 利潤

您也不限於僅使用 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類; 您的divli元素也應該使用類進行分組。

然后您可以簡單地引用這些類並通過以下方式添加顯示/隱藏邏輯:

$('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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM