使用纯JS制作多层手风琴,并使用nextElementSibling

问题描述 投票:1回答:2

是Java的新手。我最近发布了一个有关创建多个多层手风琴的问题。我收到了很多反馈,但是有人提到,如果我的HTML设置正确,则可以使用nextElementSibling达到相同的目标,因此可以使用更加简洁的JS。

我想出了如何仅使用queryselect来执行此操作。请参见以下示例:

HTML:

<div class="mainAccordion">
    <h2>dropdown one</h2>
    <h3>dropdown two</h3>
    <p>content content content content</p>
</div>

CSS:

.mainAccordion {
    background-color:lightblue;
    width:200px;
    margin:auto;
    padding:3%;
}
.mainAccordion :nth-child(1){
    background-color: blue;
    padding:3%;
    cursor:pointer;
    color:white;
}

.mainAccordion :nth-child(2){
    background-color:yellow;
    cursor:pointer;
    max-height:0;
    overflow:hidden;
}

.mainAccordion :nth-child(3){
    font-weight:bold;
    max-height:0;
    overflow:hidden;
}

和JS:

var mainAccordion = document.querySelector(".mainAccordion").addEventListener("click", function(e) {
    if (e.target.nextElementSibling.style.maxHeight) {
        e.target.nextElementSibling.style.maxHeight = null;
    } else {
        e.target.nextElementSibling.style.maxHeight = e.target.nextElementSibling.scrollHeight + "px";
    }
});

这按预期工作。但是,当我引入多个多层手风琴并切换到“ querySelectorAll”时,它将停止工作。同样取决于浏览器,有时我会收到一条错误消息,指出我的“ addEventListener”不是函数。

见下文:

HTML:

<div class="mainAccordion">
    <h2>dropdown one</h2>
    <h3>dropdown two</h3>
    <p>content content content content</p>
</div>

<div class="mainAccordion">
    <h2>dropdown one</h2>
    <h3>dropdown two</h3>
    <p>content content content content</p>
</div>

CSS:

body {
    display:flex;
    width: 900px;
    margin:auto;
}
.mainAccordion {
    background-color:lightblue;
    width:200px;
    margin:auto;
    padding:3%;
}
.mainAccordion :nth-child(1){
    background-color: blue;
    padding:3%;
    cursor:pointer;
    color:white;
}

.mainAccordion :nth-child(2){
    background-color:yellow;
    cursor:pointer;
    max-height:0;
    overflow:hidden;
}

.mainAccordion :nth-child(3){
    font-weight:bold;
    max-height:0;
    overflow:hidden;
}

和JS:

var mainAccordion = document.querySelectorAll(".mainAccordion").addEventListener("click", function(e) {
    if (e.target.nextElementSibling.style.maxHeight) {
        e.target.nextElementSibling.style.maxHeight = null;
    } else {
        e.target.nextElementSibling.style.maxHeight = e.target.nextElementSibling.scrollHeight + "px";
    }
});

我尝试将“ querySelectorAll(”。mainAccordion“)更改为getElementsByClassName(” mainAccordion“),但也无法正常工作。

每个人都参与其中吗?

注意:我知道您也可以通过切换具有“ max-height:0; overflow:hidden”的类来实现相同的目标。但是,这就是最初教我做手风琴的方式。

这是我的实践。

我感谢您的帮助。

javascript accordion addeventlistener queryselector
2个回答
0
投票

尝试一下:

let accordionElements = document.querySelectorAll(".mainAccordion");

    accordionElements.forEach(element => {
        element.addEventListener("click", function(e) {
            if (e.target.nextElementSibling.style.maxHeight) {
                e.target.nextElementSibling.style.maxHeight = null;
            } else {
                e.target.nextElementSibling.style.maxHeight = e.target.nextElementSibling.scrollHeight + "px";
            }
        })
    });

这是因为使用querySelector()返回了HTML元素。与querySelectorAll()一起,它是一个NodeList。在示例代码中,您尝试将事件附加到节点列表,这是不可能的。

您需要在其中循环,然后将事件附加到其中的每个HTML元素。


0
投票

我认为问题在于querySelector()返回文档中与指定选择器匹配的第一个Element。然后事件侦听器将应用于找到的第一个元素。

querySelectorAll()返回列表。您可以将其与forEach这样使用

  var mainAccordion = document.querySelectorAll(".mainAccordion");
  console.log(mainAccordion);
  mainAccordion.forEach(accordion => {
    accordion.addEventListener("click", function(e) {
      if (e.target.nextElementSibling.style.maxHeight) {
        e.target.nextElementSibling.style.maxHeight = null;
      } else {
        e.target.nextElementSibling.style.maxHeight =
          e.target.nextElementSibling.scrollHeight + "px";
      }
    });
  });
© www.soinside.com 2019 - 2024. All rights reserved.