简体   繁体   中英

Multiple javascript toggle for tree structure

I have a Tree structure with Unlimited Nodes, How to put Togglable content under each node? I mean Togglable content is same for all nodes. I set min-width and min-height for .tree li a and I want Togglable content be under .tree li a .
Now toggle work for 1 node and that is'nt under each node.
Photo: 照片

  var toggle = document.getElementById("toggle"); var content = document.getElementById("content"); toggle.addEventListener("click", function () { content.classList.toggle("appear"); }, false); 
  body { font-family: sans-serif; font-size: 15px; } .tree { transform: rotate(0deg); transform-origin: 50%; } .tree ul { position: relative; padding: 1em 0; white-space: nowrap; margin: 0 auto; text-align: center; } .tree ul::after { content: ''; display: table; clear: both; } .tree li { display: inline-block; vertical-align: top; text-align: center; list-style-type: none; position: relative; padding: 1em 0.5em 0 0.5em; } .tree li::before, .tree li::after { content: ''; position: absolute; top: 0; right: 50%; border-top: 1px solid #ccc; width: 50%; height: 1em; } .tree li::after { right: auto; left: 50%; border-left: 1px solid #ccc; } .tree li:only-child::after, .tree li:only-child::before { display: none; } .tree li:only-child { padding-top: 0; } .tree li:first-child::before, .tree li:last-child::after { border: 0 none; } .tree li:last-child::before { border-right: 1px solid #ccc; border-radius: 0 5px 0 0; } .tree li:first-child::after { border-radius: 5px 0 0 0; } .tree ul ul::before { content: ''; position: absolute; top: 0; left: 50%; border-left: 1px solid #ccc; width: 0; height: 1em; } .tree li a { min-width: 16em; min-height: 5em; border: 1px solid #ccc; padding: 0.5em 0.75em; text-decoration: none; display: inline-block; border-radius: 5px; color: #333; position: relative; top: 1px; transform: rotate(0deg); } .tree li a:hover, .tree li a:hover+ul li a { background: #e9453f; color: #fff; border: 1px solid #e9453f; } .tree li a:hover+ul li::after, .tree li a:hover+ul li::before, .tree li a:hover+ul::before, .tree li a:hover+ul ul::before { border-color: #e9453f; } #content { /* DON'T USE DISPLAY NONE/BLOCK! Instead: */ background: #cf5; padding: 10px; position: inherit; visibility: hidden; opacity: 0.4; transition: 0.6s; -webkit-transition: 0.6s; transform: translateY(-20%); -webkit-transform: translateY(-20%); } #content.appear { visibility: visible; opacity: 1; transform: translateX(0); -webkit-transform: translateX(0); } 
 <body> <div class="row"> <div class="col-sm-12 text-center tree"> <ul> <li id="toggle"> <a href="#">parent</a> <ul> <li id="toggle"> <a href="#">boy</a> </li> <li id="toggle"> <a href="#">girl</a> </li> </ul> </li> </ul> <div id="content">This Togglable content is same for all id="toggle"</div> </div> </div> </body> 

Do not use the same id for multiple elements, id should always be unique.

Use class instead.

<li class="toggle"> ... </li>

Then you can create an array of objects in JavaScript to access these elements:

let toggle_list = document.querySelectorAll(".toggle");

Then you can use a for loop (or, forEach method, if you want to be fancy) to assign an event listener to each of them:

for(let i = 0; i < toggle_list.length; i++) {
  toggle_list[i].addEventListener("click", toggleClick);
}

Now you can define your toggleClick function something like this:

function toggleClick(e) {
  e.target.children[0].classList.toggle("appear");
}

In this example, children[0] will target the first element inside the <li> that is clicked, and that child element does not need a separate class="content" attribute. You can change it to something else, if that's not what you want (perhaps children[1] :D ).

More info: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll

As far as i know id attribute should be unique for html document

You can try do use data- attribute and then match an element for example by data-toggle

link for documentation

✔️ Solved With This way:

  function toggleDocs(event) { var next = event.target.nextElementSibling; if (next.style.display == "none") { next.style.display = "block"; } else { next.style.display = "none"; } } document.addEventListener('click', toggleDocs, true); 
  body { font-family: sans-serif; font-size: 15px; } .tree { transform: rotate(0deg); transform-origin: 50%; } .tree ul { position: relative; padding: 1em 0; white-space: nowrap; margin: 0 auto; text-align: center; } .tree ul::after { content: ''; display: table; clear: both; } .tree li { display: inline-block; vertical-align: top; text-align: center; list-style-type: none; position: relative; padding: 1em 0.5em 0 0.5em; } .tree li::before, .tree li::after { content: ''; position: absolute; top: 0; right: 50%; border-top: 1px solid #ccc; width: 50%; height: 1em; } .tree li::after { right: auto; left: 50%; border-left: 1px solid #ccc; } .tree li:only-child::after, .tree li:only-child::before { display: none; } .tree li:only-child { padding-top: 0; } .tree li:first-child::before, .tree li:last-child::after { border: 0 none; } .tree li:last-child::before { border-right: 1px solid #ccc; border-radius: 0 5px 0 0; } .tree li:first-child::after { border-radius: 5px 0 0 0; } .tree ul ul::before { content: ''; position: absolute; top: 0; left: 50%; border-left: 1px solid #ccc; width: 0; height: 1em; } .tree li a { min-width: 16em; min-height: 5em; border: 1px solid #ccc; padding: 0.5em 0.75em; text-decoration: none; display: inline-block; border-radius: 5px; color: #333; position: relative; top: 1px; transform: rotate(0deg); } .tree li a:hover, .tree li a:hover+ul li a { background: #e9453f; color: #fff; border: 1px solid #e9453f; } .tree li a:hover+ul li::after, .tree li a:hover+ul li::before, .tree li a:hover+ul::before, .tree li a:hover+ul ul::before { border-color: #e9453f; } #content { /* DON'T USE DISPLAY NONE/BLOCK! Instead: */ background: #cf5; padding: 10px; position: inherit; visibility: hidden; opacity: 0.4; transition: 0.6s; -webkit-transition: 0.6s; transform: translateY(-20%); -webkit-transform: translateY(-20%); } #content.appear { visibility: visible; opacity: 1; transform: translateX(0); -webkit-transform: translateX(0); } 
 <body> <div class="row"> <div class="col-sm-12 text-center tree"> <ul> <li class="clickable-heading"> <a href="#">parent</a> <div style="display:none">This is Togglable 1</div> <ul> <li class="clickable-heading"> <a href="#">boy</a> <div style="display:none">This is Togglable 2</div> </li> <li class="clickable-heading"> <a href="#">girl</a> <div style="display:none">This is Togglable 3</div> </li> </ul> </li> </ul> </div> </div> </body> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM