为什么单击标题图标时手风琴不切换?

Why doesn't my accordion toggle when clicking on the heading icons?

需要以下手风琴的帮助。当您单击标题时,手风琴会下降,这很棒并且效果很好。但是,当您单击 + / - 时,手风琴不会下拉。不确定如何解决此问题,如果有人提供帮助,将不胜感激。不完全确定如何修改 before/after 使其可点击。

function initAcc(elem, option){
    document.addEventListener('click', function (e) {
        if (!e.target.matches(elem+' .a-btn')) return;
        else{
            if(!e.target.parentElement.classList.contains('active')){
                if(option==true){
                    var elementList = document.querySelectorAll(elem+' .a-container');
                    Array.prototype.forEach.call(elementList, function (e) {
                        e.classList.remove('active');
                    });
                }            
                e.target.parentElement.classList.add('active');
            }else{
                e.target.parentElement.classList.remove('active');
            }
        }
    });
}

initAcc('.accordion.v1', true);
.container {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 1000px;
  margin: 0 auto;
  padding: 10px 10px 100px 10px;
}
.container h1 {
  text-align: center;
  margin-bottom: 30px;
  font-weight: 500;
}
.container h2 {
  font-weight: 500;
}

.accordion {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: auto;
}
.accordion .a-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding-bottom: 5px;
}
.accordion .a-container .a-btn {
  margin: 0;
  position: relative;
  padding: 15px 30px;
  width: 100%;
  color: #bdbdbd;
  font-weight: 400;
  display: block;
  font-weight: 500;
  background-color: #262626;
  cursor: pointer;
  transition: all 0.3s ease-in-out;
  border-radius: 5px;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.15), 0 10px 10px -5px rgba(0, 0, 0, 0.1) !important;
}
.accordion .a-container .a-btn span {
  display: block;
  position: absolute;
  height: 14px;
  width: 14px;
  right: 20px;
  top: 18px;
}
.accordion .a-container .a-btn span:after {
  content: "";
  width: 14px;
  height: 3px;
  border-radius: 2px;
  background-color: #fff;
  position: absolute;
  top: 6px;
}
.accordion .a-container .a-btn span:before {
  content: "";
  width: 14px;
  height: 3px;
  border-radius: 2px;
  background-color: #fff;
  position: absolute;
  top: 6px;
  transform: rotate(90deg);
  transition: all 0.3s ease-in-out;
}
.accordion .a-container .a-panel {
  width: 100%;
  color: #262626;
  transition: all 0.2s ease-in-out;
  opacity: 0;
  height: auto;
  max-height: 0;
  overflow: hidden;
  padding: 0px 10px;
}
.accordion .a-container.active .a-btn {
  color: #fff;
}
.accordion .a-container.active .a-btn span::before {
  transform: rotate(0deg);
}
.accordion .a-container.active .a-panel {
  padding: 15px 10px 10px 10px;
  opacity: 1;
  max-height: 500px;
}
    <div class="container">
        <div class="accordion v1">
            <div class="a-container">
                <p class="a-btn">One <span></span></p>
                <div class="a-panel">
                    <h4>Lorem ipsum dolor sit amet.</h4>
                    <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Laudantium minima dolores assumenda id. Porro consequuntur at dolor eum, neque labore!</p>
                    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur non sint sequi ipsa laudantium, iure rem vel nemo soluta temporibus, consectetur at corrupti aspernatur maxime, iusto ne blanditiis deleniti.</p>
                </div>
            </div>
            <div class="a-container">
                <p class="a-btn">Two <span></span></p>
                <div class="a-panel">
                    <h4>Lorem ipsum dolor sit amet.</h4>
                    <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Laudantium minima dolores assumenda id. Porro consequuntur at dolor eum, neque labore!</p>
                    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur non sint sequi ipsa laudantium, iure rem vel nemo soluta temporibus, consectetur at corrupti aspernatur maxime, iusto ne blanditiis deleniti.</p>
                </div>
            </div>
        </div>
    </div>

目标就是您点击的内容。 + 不是您要查找的元素,因此您必须查看它是否为子元素。最简单的方法是最接近的。

function initAcc(elem, option){
    document.addEventListener('click', function (e) {
      const clickedElem = e.target.closest(elem+' .a-btn');
        if (!clickedElem) return;
        else{
            if(!clickedElem.parentElement.classList.contains('active')){
                if(option==true){
                    var elementList = document.querySelectorAll(elem+' .a-container');
                    Array.prototype.forEach.call(elementList, function (e) {
                        e.classList.remove('active');
                    });
                }            
                clickedElem.parentElement.classList.add('active');
            }else{
                clickedElem.parentElement.classList.remove('active');
            }
        }
    });
}

initAcc('.accordion.v1', true);
.container {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 1000px;
  margin: 0 auto;
  padding: 10px 10px 100px 10px;
}
.container h1 {
  text-align: center;
  margin-bottom: 30px;
  font-weight: 500;
}
.container h2 {
  font-weight: 500;
}

.accordion {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: auto;
}
.accordion .a-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding-bottom: 5px;
}
.accordion .a-container .a-btn {
  margin: 0;
  position: relative;
  padding: 15px 30px;
  width: 100%;
  color: #bdbdbd;
  font-weight: 400;
  display: block;
  font-weight: 500;
  background-color: #262626;
  cursor: pointer;
  transition: all 0.3s ease-in-out;
  border-radius: 5px;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.15), 0 10px 10px -5px rgba(0, 0, 0, 0.1) !important;
}
.accordion .a-container .a-btn span {
  display: block;
  position: absolute;
  height: 14px;
  width: 14px;
  right: 20px;
  top: 18px;
}
.accordion .a-container .a-btn span:after {
  content: "";
  width: 14px;
  height: 3px;
  border-radius: 2px;
  background-color: #fff;
  position: absolute;
  top: 6px;
}
.accordion .a-container .a-btn span:before {
  content: "";
  width: 14px;
  height: 3px;
  border-radius: 2px;
  background-color: #fff;
  position: absolute;
  top: 6px;
  transform: rotate(90deg);
  transition: all 0.3s ease-in-out;
}
.accordion .a-container .a-panel {
  width: 100%;
  color: #262626;
  transition: all 0.2s ease-in-out;
  opacity: 0;
  height: auto;
  max-height: 0;
  overflow: hidden;
  padding: 0px 10px;
}
.accordion .a-container.active .a-btn {
  color: #fff;
}
.accordion .a-container.active .a-btn span::before {
  transform: rotate(0deg);
}
.accordion .a-container.active .a-panel {
  padding: 15px 10px 10px 10px;
  opacity: 1;
  max-height: 500px;
}
<div class="container">
        <div class="accordion v1">
            <div class="a-container">
                <p class="a-btn">One <span></span></p>
                <div class="a-panel">
                    <h4>Lorem ipsum dolor sit amet.</h4>
                    <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Laudantium minima dolores assumenda id. Porro consequuntur at dolor eum, neque labore!</p>
                    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur non sint sequi ipsa laudantium, iure rem vel nemo soluta temporibus, consectetur at corrupti aspernatur maxime, iusto ne blanditiis deleniti.</p>
                </div>
            </div>
            <div class="a-container">
                <p class="a-btn">Two <span></span></p>
                <div class="a-panel">
                    <h4>Lorem ipsum dolor sit amet.</h4>
                    <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Laudantium minima dolores assumenda id. Porro consequuntur at dolor eum, neque labore!</p>
                    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur non sint sequi ipsa laudantium, iure rem vel nemo soluta temporibus, consectetur at corrupti aspernatur maxime, iusto ne blanditiis deleniti.</p>
                </div>
            </div>
        </div>
    </div>

pointer-events:none 添加到您的 span 将对您有效:-

function initAcc(elem, option){
    document.addEventListener('click', function (e) {
        if (!e.target.matches(elem+' .a-btn')) return;
        else{
            if(!e.target.parentElement.classList.contains('active')){
                if(option==true){
                    var elementList = document.querySelectorAll(elem+' .a-container');
                    Array.prototype.forEach.call(elementList, function (e) {
                        e.classList.remove('active');
                    });
                }            
                e.target.parentElement.classList.add('active');
            }else{
                e.target.parentElement.classList.remove('active');
            }
        }
    });
}

initAcc('.accordion.v1', true);
.container {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 1000px;
  margin: 0 auto;
  padding: 10px 10px 100px 10px;
}
.container h1 {
  text-align: center;
  margin-bottom: 30px;
  font-weight: 500;
}
.container h2 {
  font-weight: 500;
}

.accordion {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: auto;
}
.accordion .a-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding-bottom: 5px;
}
.accordion .a-container .a-btn {
  margin: 0;
  position: relative;
  padding: 15px 30px;
  width: 100%;
  color: #bdbdbd;
  font-weight: 400;
  display: block;
  font-weight: 500;
  background-color: #262626;
  cursor: pointer;
  transition: all 0.3s ease-in-out;
  border-radius: 5px;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.15), 0 10px 10px -5px rgba(0, 0, 0, 0.1) !important;
}
.accordion .a-container .a-btn span {
  display: block;
  position: absolute;
  pointer-events:none;
  height: 14px;
  width: 14px;
  right: 20px;
  top: 18px;
}
.accordion .a-container .a-btn span:after {
  content: "";
  width: 14px;
  height: 3px;
  border-radius: 2px;
  background-color: #fff;
  position: absolute;
  top: 6px;
}
.accordion .a-container .a-btn span:before {
  content: "";
  width: 14px;
  height: 3px;
  border-radius: 2px;
  background-color: #fff;
  position: absolute;
  top: 6px;
  transform: rotate(90deg);
  transition: all 0.3s ease-in-out;
}
.accordion .a-container .a-panel {
  width: 100%;
  color: #262626;
  transition: all 0.2s ease-in-out;
  opacity: 0;
  height: auto;
  max-height: 0;
  overflow: hidden;
  padding: 0px 10px;
}
.accordion .a-container.active .a-btn {
  color: #fff;
}
.accordion .a-container.active .a-btn span::before {
  transform: rotate(0deg);
}
.accordion .a-container.active .a-panel {
  padding: 15px 10px 10px 10px;
  opacity: 1;
  max-height: 500px;
}
<div class="container">
        <div class="accordion v1">
            <div class="a-container">
                <p class="a-btn">One <span></span></p>
                <div class="a-panel">
                    <h4>Lorem ipsum dolor sit amet.</h4>
                    <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Laudantium minima dolores assumenda id. Porro consequuntur at dolor eum, neque labore!</p>
                    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur non sint sequi ipsa laudantium, iure rem vel nemo soluta temporibus, consectetur at corrupti aspernatur maxime, iusto ne blanditiis deleniti.</p>
                </div>
            </div>
            <div class="a-container">
                <p class="a-btn">Two <span></span></p>
                <div class="a-panel">
                    <h4>Lorem ipsum dolor sit amet.</h4>
                    <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Laudantium minima dolores assumenda id. Porro consequuntur at dolor eum, neque labore!</p>
                    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur non sint sequi ipsa laudantium, iure rem vel nemo soluta temporibus, consectetur at corrupti aspernatur maxime, iusto ne blanditiis deleniti.</p>
                </div>
            </div>
        </div>
    </div>

解释 - 这样做是因为您的 e.target 需要与特定选择器匹配,但您的 e.target 会根据您点击的位置而有所不同,它会变成当您单击 +/- 图标时,此 span。所以我已经阻止了 pointer-events span。我也喜欢@espascarello 的closest 方法。