Я пытаюсь сделать складное меню только с 1 открытым за раз чистым JavaScript - PullRequest
0 голосов
/ 30 октября 2019

Вот мой код и код JSfiddle, у меня сейчас проблема в том, что если один из них открыт, и вы пытаетесь закрыть его снова, он не закроется.

https://jsfiddle.net/k68z3aLv/

var coll = document.getElementsByClassName("collapsible");
var i;

for (i = 0; i < coll.length; i++) {
  coll[i].addEventListener("click", function() {
 
	  var b;
	  for(b = 0; b < coll.length; b++) {
     
	  if(coll[b] != coll[i]) {
		  if(coll[b].getAttribute('id') == 'submenuopened')
		  {
			   coll[b].classList.remove("active");
			  coll[b].setAttribute("id",'');
			   var content3 = coll[b].nextElementSibling;
			    content3.style.display = "none";
             
			// sleep(0);
	  }
	  }
	  }
    
    this.classList.toggle("active");
	if(this.getAttribute('id') == 'submenuopened') {
		this.setAttribute("id",'ha');
	} else { this.setAttribute("id", "submenuopened"); }
	
    var content = this.nextElementSibling;
    if (content.style.display == 'block'){
      content.style.display = "none";
    } else {
      content.style.display = "block";
    } 
  });
}
.collapsible {
  background-color: #777;
  color: white;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
}

.active, .collapsible:hover {
  background-color: #555;
}

.content {
  padding: 0 18px;
  display: none;
  overflow: hidden;
  background-color: #f1f1f1;
}
<button type="button" class="collapsible">Open Section 1</button>
<div class="content">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button type="button" class="collapsible">Open Section 2</button>
<div class="content">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button type="button" class="collapsible">Open Section 3</button>
<div class="content">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

Ответы [ 3 ]

1 голос
/ 30 октября 2019

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

Рабочий пример

Требуются правки. HTML и CSS - это очень маленькие корректировки, интересная часть JS.

HTML

<div class="collapsible">
  <header>
    Open Section 1
  </header>
  <div class="content">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
  </div>
</div>

...

Разум

Если ваши кнопки для открытия и закрытия складных объектов далекоВ отличие от фактического содержимого (что не так, как вы упомянули здесь), семантически полезно, чтобы весь элемент был сгруппирован вместе.

CSS


.collapsible header {
  ...
}

.collapsible.is-active .content {
  display: block;
}

Reasoning

Единственное изменение, которое требуется здесь, - это настройка CSS для целевого элемента header, поскольку класс .collapsible теперь применяется к родительскому элементу.

Кроме того, мы добавляем простой семантический класс, который сообщит нам, какойодин в данный момент активен, и покажите его.

JS

const collapsibles = Array.from(document.getElementsByClassName("collapsible"));

function toggleVisibility(e) {
  const parent = e.target.parentElement;

  parent.classList.toggle("is-active");

  collapsibles.forEach(collapsible => {
    if(collapsible === parent) return;

    collapsible.classList.remove("is-active")
  });
}

collapsibles.forEach(collapsible => {
    collapsible.querySelector("header").addEventListener("click", toggleVisibility);
});

Обоснование

  1. Сначала вы получаете массив родительских элементов DOM и сохраняете их в переменной,Вы будете использовать это, чтобы решить, какой из них показывать, а какой скрывать.
  2. К каждому из этих элементов DOM вы присоединяете прослушиватель событий, используя более простые и удобочитаемые методы Array вместо for loop.
  3. Вы превращаете ваш обработчик в простую функцию, которую можете использовать повторно. Все, что делает эта функция, это убедитесь, что вы toggle текущий активный, если вы нажмете на себя, и закройте все остальные.
1 голос
/ 30 октября 2019

Я немного оптимизировал Ваш кодпосмотрите более ясно

var coll = document.getElementsByClassName("collapsible");

for (let i = 0; i < coll.length; i++) {
  coll[i].addEventListener("click", function() {
	  for(let n = 0; n < coll.length; n++) {
      if(coll[n] == this) continue;
      coll[n].classList.remove("active");
	  }
    
    this.classList.toggle("active"); 
  });
}
.collapsible {
  background-color: #777;
  color: white;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
}

.active, .collapsible:hover {
  background-color: #555;
}

.collapsible.active + .content {
  display: block;
}

.content {
  padding: 0 18px;
  display: none;
  overflow: hidden;
  background-color: #f1f1f1;
}
<button type="button" class="collapsible">Open Section 1</button>
<div class="content">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button type="button" class="collapsible">Open Section 2</button>
<div class="content">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button type="button" class="collapsible">Open Section 3</button>
<div class="content">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
0 голосов
/ 30 октября 2019

Ваш код был довольно запутанным для меня, чтобы расшифровать, так что я просто переписал его так, как я считаю понятным. Это было достигнуто путем создания двух функций для открытия или закрытия подменю для определенного элемента.

var buttoncolumn = document.getElementsByClassName('collapsible');

function closesubmenu(el) {
  el.setAttribute('id', '');
  el.classList.remove('active');
  el.nextElementSibling.style.display = 'none';
}

function opensubmenu(el) {
  el.setAttribute('id', 'submenuopened');
  el.classList.add('active');
  el.nextElementSibling.style.display = 'block';
}

for (let button of buttoncolumn) {
  button.addEventListener('click', function() {
    if (this.getAttribute('id') == 'submenuopened') {
      closesubmenu(this);
    } else {
      for (let other of buttoncolumn) {
        closesubmenu(other);
      }
      opensubmenu(this);
    }
  });
};
.collapsible {
  background-color: #777;
  color: white;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
}

.active,
.collapsible:hover {
  background-color: #555;
}

.content {
  padding: 0 18px;
  display: none;
  overflow: hidden;
  background-color: #f1f1f1;
}
<button type="button" class="collapsible">Open Section 1</button>
<div class="content">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button type="button" class="collapsible">Open Section 2</button>
<div class="content">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<button type="button" class="collapsible">Open Section 3</button>
<div class="content">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...