Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/447.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用纯JS和nextElementSibling制作多层手风琴_Javascript_Accordion_Addeventlistener_Queryselector - Fatal编程技术网

Javascript 使用纯JS和nextElementSibling制作多层手风琴

Javascript 使用纯JS和nextElementSibling制作多层手风琴,javascript,accordion,addeventlistener,queryselector,Javascript,Accordion,Addeventlistener,Queryselector,Javascript的新特性。我最近发布了一个关于创建多层手风琴的问题。我得到了一些很好的反馈,但有人提到,如果我的HTML设置正确,我可以通过使用nextElementSibling实现同样的目标,从而使JS更干净 我只使用queryselect就知道了如何做到这一点。请参见以下示例: HTML: <div class="mainAccordion"> <h2>dropdown one</h2> <h3>dropdown two&

Javascript的新特性。我最近发布了一个关于创建多层手风琴的问题。我得到了一些很好的反馈,但有人提到,如果我的HTML设置正确,我可以通过使用
nextElementSibling
实现同样的目标,从而使JS更干净

我只使用queryselect就知道了如何做到这一点。请参见以下示例:

HTML:

<div class="mainAccordion">
    <h2>dropdown one</h2>
    <h3>dropdown two</h3>
    <p>content content content content</p>
</div>
.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;
}
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";
    }
});

<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>
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;
}
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";
    }
});
和JS:

<div class="mainAccordion">
    <h2>dropdown one</h2>
    <h3>dropdown two</h3>
    <p>content content content content</p>
</div>
.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;
}
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";
    }
});

<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>
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;
}
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”时,它停止工作。也取决于浏览器,有时我会收到一条错误消息,说我的“addEventListener”不是一个函数

见下文:

HTML:

<div class="mainAccordion">
    <h2>dropdown one</h2>
    <h3>dropdown two</h3>
    <p>content content content content</p>
</div>
.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;
}
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";
    }
});

<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>
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;
}
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";
    }
});
和JS:

<div class="mainAccordion">
    <h2>dropdown one</h2>
    <h3>dropdown two</h3>
    <p>content content content content</p>
</div>
.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;
}
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";
    }
});

<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>
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;
}
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(.mainCordrion”)更改为getElementsByClassName(“mainCordrion”),但也不起作用

forEach有什么关系吗

注意:我知道,通过切换具有“最大高度: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元素是return。querySelectorAll()的HTML元素是NodeList。在示例代码中,您尝试将事件附加到节点列表,但这是不可能的

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

尝试以下操作:

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元素是return。querySelectorAll()的HTML元素是NodeList。在示例代码中,您尝试将事件附加到节点列表,但这是不可能的


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

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

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";
      }
    });
  });

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

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";
      }
    });
  });

谢谢你,杰里米!我还在绞尽脑汁学习ES6语法及其函数之箭的用法。我所学的课程一定很旧,而且是ES5使用的。为了帮助我理解,如果第2行是用ES5写的,那将是“accordioelements.forEach(element){…}”?我的荣幸!在ES5中你应该写accordioelements.forEach(function(element){}。这里的主要好处是不必编写函数。但Arrow函数还有其他好处:将其绑定到周围的上下文、隐式返回和Arrow“=>“。这是一篇关于arrow函数的好文章:谢谢你,Jeremie!我仍然对ES6语法及其arrow of functions的用法耿耿于怀。我所学的课程一定是旧的,并且使用了ES5。为了帮助我理解,如果第2行是用ES5编写的,那么它将是“accordioElements.forEach(element){…}”我很乐意!在ES5中,您应该编写accordionElements.forEach(function(element){}。这里的主要好处是不必编写函数。但Arrow函数还有其他好处:将其绑定到周围的上下文、隐式返回和箭头“=>”。这是一篇关于Arrow函数的好文章: