Несколько Javascript переключатель для древовидной структуры - PullRequest
0 голосов
/ 01 декабря 2018

У меня есть древовидная структура с неограниченным количеством узлов. Как разместить Togglable content под каждым узлом?Я имею в виду Togglable content одинаково для всех узлов.Я установил min-width и min-height для .tree li a и хочу, чтобы Togglable content был ниже .tree li a.
Теперь переключение работает для 1 узла, а это не под каждым узлом.
Фото: 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>

Ответы [ 3 ]

0 голосов
/ 01 декабря 2018

Не используйте один и тот же id для нескольких элементов, id всегда должен быть уникальным.

Используйте взамен class.

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

Затем вы можете создать массивобъектов в JavaScript для доступа к этим элементам:

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

Затем вы можете использовать цикл for (или метод forEach, если хотите быть модным), чтобы назначить прослушиватель событий каждому изих:

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

Теперь вы можете определить свою функцию toggleClick примерно так:

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

В этом примере children[0] нацелится на первый элемент внутри <li>, которыйщелкнул, и этот дочерний элемент не нуждается в отдельном атрибуте class="content".Вы можете изменить его на что-то другое, если это не то, что вы хотите (возможно, children[1]: D).

Дополнительная информация: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll

0 голосов
/ 02 декабря 2018

✔️ Решено таким образом:

  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>
0 голосов
/ 01 декабря 2018

Насколько я знаю, атрибут id должен быть уникальным для HTML-документа

. Вы можете попробовать использовать атрибут data-, а затем сопоставить элемент, например, с помощью data-toggle

. ссылка на документацию

...