简体   繁体   English

当孩子展开时,嵌套的可折叠不能正确显示其内容

[英]Cannot have nested collapsible showing their content properly when children expand

Starting from the code found at https://www.w3schools.com/howto/howto_js_collapsible.asp , I would like to create a collapsible menu which would work also for nested content.https://www.w3schools.com/howto/howto_js_collapsible.asp中的代码开始,我想创建一个可折叠菜单,它也适用于嵌套内容。

 var coll = document.getElementsByClassName("collapsible"); var i; for (i = 0; i < coll.length; i++) { coll[i].addEventListener("click", function() { this.classList.toggle("active"); var content = this.nextElementSibling; if (content.style.maxHeight){ content.style.maxHeight = null; } else { content.style.maxHeight = content.scrollHeight + "px"; } }); }
 .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; }.collapsible:after { content: '\002B'; color: white; font-weight: bold; float: right; margin-left: 5px; }.active:after { content: "\2212"; }.content { padding: 0 18px; max-height: 0; overflow: hidden; transition: max-height 0.2s ease-out; background-color: #f1f1f1; }
 <button class="collapsible">Open Collapsible</button> <div class="content"> <button class="collapsible">Open Collapsible</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 class="collapsible">Open Collapsible</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> </div>

The code above works for the first (root) collapsible.上面的代码适用于第一个(根)可折叠。

However, when the child collapsible are expanded, there is no space enough for seeing their content.然而,当子折叠屏展开时,没有足够的空间来查看它们的内容。

Only if they are kept opened, closing the root collapsible and reopening it will show the child content correctly.只有当它们保持打开时,关闭根可折叠并重新打开它才能正确显示子内容。

I know the problem is in that when the root collapsible is expanded, its content maxHeight is set to scrollHeight + "px";我知道问题在于当根可折叠展开时,它的内容maxHeight设置为scrollHeight + "px"; , and this will be the height of the child collapsible which are still closed. ,这将是仍然关闭的可折叠子项的高度。

How can I make the maxHeight of the collapsibles dynamically change as their children collapsible expand?如何使可折叠的maxHeight在其子可折叠展开时动态变化?

You should check and modify max-height for elements on child opening and closing (partial code).您应该检查和修改子打开和关闭时元素的最大高度(部分代码)。

for (i = 0; i < coll.length; i++) {
  coll[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var content = this.nextElementSibling;
    if (content.style.maxHeight){
      content.style.maxHeight = null;
    } else {
      content.style.maxHeight = content.scrollHeight + "px";
    }
    // from last to first to recalculate parent height after child
    for (var j = coll.length - 1; j >= 0;  j--) {
      if (coll[j].classList.contains('active')) {
        console.log(j, coll[j].classList);
        var c2 = coll[j].nextElementSibling;
        console.log(c2);
        c2.style.maxHeight = null;
        c2.style.maxHeight = c2.scrollHeight + "px";
      }
    }
  });
}

But code above will work if css transition is disabled (because js triggers immediately before transition completed).但是如果 css 转换被禁用,上面的代码将起作用(因为 js 在转换完成之前立即触发)。

So, if transition is necessary you can add timeout to check for modification after transition ends.因此,如果需要转换,您可以添加超时以在转换结束后检查修改。 Something like this:像这样的东西:

var coll = document.getElementsByClassName("collapsible");
var i;

var checkCollapsible = function() {
  for (var j = coll.length - 1; j >= 0;  j--) {
      if (coll[j].classList.contains('active')) {
        console.log(j, coll[j].classList);
        var c2 = coll[j].nextElementSibling;
        console.log(c2);
        c2.style.maxHeight = null;
        c2.style.maxHeight = c2.scrollHeight + "px";
      }
    }
};

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

https://jsfiddle.net/6yn0mewz/3/ https://jsfiddle.net/6yn0mewz/3/

There are also bunch of transitionend events available.还有一堆可用的 transitionend 事件。 So for webkit you may use something like (partial code)所以对于 webkit,你可以使用类似(部分代码)的东西

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

https://jsfiddle.net/6yn0mewz/4/ https://jsfiddle.net/6yn0mewz/4/

See CSS3 transition events and TransitionEnd Event not firing?请参阅CSS3 转换事件TransitionEnd 事件未触发? for examples.举些例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM