【问题标题】:Creating Multiple Accordions html/Javascript/CSS创建多个手风琴 html/Javascript/CSS
【发布时间】:2021-12-05 22:26:22
【问题描述】:

我正在尝试制作嵌套的手风琴(你展开一个,然后在里面你可以展开另一个),但由于某种原因,里面的手风琴不起作用。

这是基于 w3 school 的手风琴代码,但我用图像替换了按钮。我的逻辑是,如果我复制粘贴第一个手风琴并将其重命名为“手风琴 1”,我可以稍后调用手风琴 1,并且会发生与原始手风琴相同的事情。

但是当我单击内部手风琴按钮时,没有任何反应。我不太确定为什么会这样,因为它似乎是直接复制粘贴。我不确定这里是否需要做一些不同的事情

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    }
  });
}

var acc1 = document.getElementsByClassName("accordion1");
var i;

for (i = 0; i < acc1.length; i++) {
  acc1[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    }
  });
}
.accordion {
  background-image: url(https://i.imgur.com/Jqsaukf.png);
  background-repeat: no-repeat;
  background-position: 50% 50%;
  /* put the height and width of your image here */
  height: 50px;
  width: 200px;
  border: none;
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

.active,
.accordion:hover {
  background-color: #ccc;
}

.accordion:after {
  content: '\002B';
  color: #777;
  font-weight: bold;
  float: right;
  margin-left: 5px;
}

.active:after {
  content: "\2212";
}

.accordion1 {
  background-image: url(https://i.imgur.com/VXlZ0Ja.png);
  background-repeat: no-repeat;
  background-position: 50% 50%;
  /* put the height and width of your image here */
  height: 500px;
  width: 200px;
  border: none;
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

.active1,
.accordion1:hover {
  background-color: #ccc;
}

.accordion1:after {
  content: '\002B';
  color: #777;
  font-weight: bold;
  float: right;
  margin-left: 5px;
}

.active1:after {
  content: "\2212";
}

.panel {
  padding: 0 18px;
  background-color: white;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}
<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</p>

<button class="accordion"></button>
<div class="panel">
  <button class="accordion1"></button>
  <div class="panel1">
    <p>Lorem ipsum dolor sit amet</p>
  </div>
</div>
<br>
<button class="accordion"></button>
<div class="panel">
  <p><img src="https://i.imgur.com/Jqsaukf.png" alt="Italian Trulli"></p>
</div>

<button class="accordion"></button>
<div class="panel">
  <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>

编辑:我改变了我混淆的变量名;即 panel 和 panel1 以及 active 和 active 1 并且它可以工作,但我仍然想知道是否有更简洁/有效的方法来做到这一点。

我想要有 10 多个带有不同图像作为按钮的手风琴,所以如果没有办法压缩它,这个模块最终会很疯狂。也许是一个替换手风琴数组中每个图像的 for 循环?不确定这是否有意义,甚至可以使用 html/javascript/css。

【问题讨论】:

    标签: javascript html css accordion


    【解决方案1】:

    我做了这个例子来说明如何做到这一点。主要的是循环概念以及如何保持 HTML 简单以添加/删除多个手风琴元素。您可以随意嵌套。

    注意事项: 将 .accordion 元素命名为 .accordion-tab 会更有意义。我没有做太多的 CSS 样式,只是为了举例。在 Javascript 中,我展示了如何提取图像属性并随心所欲地使用它。您可能可以更好、更高效地编写很多这样的代码,但我试图让它变得快速且对人类可读。

    如果您需要任何帮助,请告诉我。上帝保佑!

    const acc = document.querySelectorAll(".accordion"); // Get all accordion tab elements
    let i;
    for (i = 0; i < acc.length; i++) {
        const accordion = acc[i];
        accordion.setAttribute('data-index', i);
    
        // Add content
        const content = accordion.getAttribute('data-content'); // Getting the accordion tab content
        const accordionContent = document.createElement("div"); // Create content element
        accordionContent.classList.add("accordion-content"); //Add content class
        accordionContent.innerHTML += content; // Add HTML
        accordion.prepend(accordionContent) // Add to DOM, if you want the nested accordions before the content, you can use append instead of prepend
    
    
        // Accordion button
        const imageData = accordion.getAttribute('data-image') ? accordion.getAttribute('data-image').split('|') : false; // Get image and alt text then split it by the | character in the attribute
        const button = document.createElement("button"); // Create a button
        button.classList.add("accordion-button"); // Add button class
        button.style.backgroundImage = "url('" + imageData[0] + "')"; // Add background image, you could instead create an image element and add the imageData[0] to the src, but you'd probably need to create your images at the perfect size or add and extract the dimensions in the data-image attribute. Ex: data-image="image1.png|Alt text for image|100px,100px"
    
        button.setAttribute('aria-label', imageData[1]); // Add image alt text
        accordion.prepend(button); // Add to DOM
        button.onclick = function() {
            togglePanel(accordion); // Add button click function, function is below in the code
        }
    
    }
    
    function togglePanel(accordion) {
        const button = accordion.querySelector('.accordion-button')
        const accordionContent = accordion.querySelector('.accordion-content')
        
        // Handle toggling here. I suggest set CSS styles, but you could use javascript to slide it
        accordion.classList.toggle('active');
    
    };
    /* I used display none and block just for the example. You can do the height transition with CSS or Javascript */ 
    .accordion .accordion,
    .accordion .accordion-content {
        display: none;
    }
    
    .accordion.active>.accordion,
    .accordion.active>.accordion-content {
        display: block;
    }
    
    
    
    /* Just for example styling*/
    button {
      cursor: pointer;
      height: 50px;
      width: 100%;
    }
    button:after {
      content: '+'
    }
    .accordion.active > button:after {
      content: '-'
    }
    .accordion-content {
        padding: 20px;
      width: 100%;
    }
    
    .accordion .accordion {
      margin-left: 20px;
    }
    .accordion.active > button {
      background: #4169e1;
     }
    .accordion .accordion.active > button {
      background: #a1caf1;
     }
     
     .accordion .accordion .accordion.active > button {
      background: #a4dded;
     }
    <!-- Main accordion -->
    <div class="accordion"
       data-image="image1.png|Alt text for image"
       data-content="Accordion 1 text"
       >
       <!-- Nested accordion -->
       <div class="accordion"
          data-image="image2.png|Alt text for image"
          data-content="Nested accordion 1 content. Image should show below: <img src=&quot;https://media.swncdn.com/via/11580-mount-zion-bst.jpg&quot; width=&quot;300&quot;>"
          ></div>
    </div>
    
    
    <div class="accordion"
       data-image="image2.png|Alt text for image"
       data-content="Accordion 2 text"
       >
       <!-- Nested accordion -->
       <div class="accordion"
          data-image="image2.png|Alt text for image"
          data-content="Nested accordion 2 text"
          ></div>
    </div>
    
    <div class="accordion"
       data-image="image3.png|Alt text for image"
       data-content="Accordion 3 has no nested accordion"
       >
    </div>
    
    <div class="accordion"
       data-image="image2.png|Alt text for image"
       data-content="Accordion 2 text"
       >
       <!-- Nested accordion -->
       <div class="accordion"
          data-image="image2a.png|Alt text for image"
          data-content="Nested accordion 2 text"
          >
        </div>
       <!-- Another nested accordion -->
       <div class="accordion"
          data-image="image2a.png|Alt text for image"
          data-content="Another nested accordion 2 text"
          >
             <!-- Double nested accordion -->
       <div class="accordion"
          data-image="image2b.png|Alt text for image"
          data-content="Double nested accordion 2 text"
          ></div>
          
          </div>
    </div>

    【讨论】:

    • 非常感谢!这个答案正是我所需要的。我很好奇如何将手风琴内的内容设置为图像而不是文本。您有 data-content="Nested Accordion 1 text," 那么如何将其更改为图像?
    • 您可以在 data-content 属性中添加任何内容,但对于图像,您只需使用 "而不是 " 符号,因为它在 " " 内部。我编辑了截图以显示它。
    猜你喜欢
    • 2021-03-12
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    相关资源
    最近更新 更多