javascript - 我正在尝试制作一个可折叠菜单,一次只打开 1 个纯 javascript

标签 javascript html css menu

这是我的代码和 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>

最佳答案

实际上有一种更简单的方法来遍历您的 DOM 元素并使您的代码更易于理解。

Working example

这些是所需的编辑。 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;
}

推理

此处唯一需要更改的是调整 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 循环附加事件监听器。
  3. 您将处理程序重构为一个可以重复使用的简单函数。此功能所做的一切,就是确保您在单击自身时切换当前事件的功能,并关闭所有其余功能。

关于javascript - 我正在尝试制作一个可折叠菜单,一次只打开 1 个纯 javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58631046/

相关文章:

css - Magento - 显示没有任何类别的 magento 导航

javascript - 如何在我的 ERB 模板中使用 Javascript var 值制作 MD5 摘要?

javascript - Sails.js 使用带有 promise 的事务的最佳实践(Postgres)

javascript - 重置复选框选中状态从历史记录中返回

java - Servlet 不转发 - Servlet 异常

html - 多个 float div,它们之间没有空格

javascript - 在 CapserJS 中操作 http 响应正文

javascript - 将显示设置为内联提交表单但不阻止

html - css 中的边框图像问题

css - 如何将正文内容复制到元标题?