javascript - 可折叠的 div block 嵌套在另一个 block 中以重新调整整个 block 的最大高度

标签 javascript html css

题目的问题很难用一句话来说明,总结一下:

我有一个可折叠的 div 元素,由 .collapsible 类突出显示,并且在我们内部有一个 .content 类。如果父元素没有 .active 类,则最大高度设置为 null,但当处于事件状态时,它使用最大高度计算,然后设置为样式。

运行这一切的 JavaScript:

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

相当直接,从w3school得到它.我对其进行了更多调整并进行了操作以更好地适应我的功能。

我试图嵌套这些可折叠组件,但事情变得很奇怪,可折叠组件的子组件会计算出其正确的最大高度并将其他内容向下推。

这是实际错误的 JavaScript 片段:

	var coll = document.getElementsByClassName("collapsible");
	var i;
	for (i = 0; i < coll.length; i++) {
		if (coll[i].classList.contains('active')) {
			var content_tmp = coll[i].nextElementSibling;
			if (content_tmp.style.maxHeight){
				content_tmp.style.maxHeight = null;
			} else {
				content_tmp.style.maxHeight = content_tmp.scrollHeight + "px";
			} 
		}
		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: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
}
.active, .collapsible:hover {
  background-color: #ccc;
}

.content {
  max-height: 0;
  transition: max-height 0.2s ease-out;
  padding: 0 18px;
  overflow: hidden;
  background-color: #f1f1f1;
}
<button class="collapsible"><span>Main Parent</span></button>
<div class="content">
  <button class="collapsible"><span>Child 1</span>       </button>
  <div class="content">
    <p>
      Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to
      be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.
    </p>
  </div>
  <button class="collapsible"><span>Child 2</span></button>
  <div class="content">
    <p>
      Some Text of child 2 that is very long and needs to be pushed down.<br><br><br>Some Text of child 2 that is very long and needs to be pushed down.
    </p>
  </div>
</div>

最佳答案

您应该在每次点击时检查父级可折叠元素并调整它们的最大高度值。另一件事要记住......一旦我们开始转换,我们就必须延迟最大高度计算。使用 jQuery 会更容易,但这是一个普通的 JS 解决方案:

var coll = document.getElementsByClassName("collapsible");
var animationDelay = 200; /* Gotta delay max-height value */
function calcMaxHeight(elem) {
    var content = elem.nextElementSibling;
    if (elem.classList.contains("active")) {
        content.style.maxHeight = content.scrollHeight + "px";
    } else {
        content.style.maxHeight = "0";
    };
    var nextParentContent = elem.closest(".content");
    if (nextParentContent !== null) {
        var nextParentCollapsible = nextParentContent.previousElementSibling;
        setTimeout(function() {
            calcMaxHeight(nextParentCollapsible);
        }, animationDelay);
    };
};
for (let i = 0; i < coll.length; i++) {
    coll[i].addEventListener("click", function() {
        this.classList.toggle("active");
        calcMaxHeight(this);
    });
}
.collapsible {
    background-color: #eee;
    color: #444;
    cursor: pointer;
    padding: 18px;
    width: 100%;
    border: none;
    text-align: left;
    outline: none;
    font-size: 15px;
}

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

.content {
    max-height: 0;
    transition: max-height 0.2s ease-out;
    padding: 0 18px;
    overflow: hidden;
    background-color: #f1f1f1;
}
<button class="collapsible"><span>Main Parent</span></button>
<div class="content">
    <button class="collapsible"><span>Child 1</span> </button>
    <div class="content">
        <p>
            Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to
            be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.
        </p>
    </div>
    <button class="collapsible"><span>Child 2</span></button>
    <div class="content">
        <p>
            Some Text of child 2 that is very long and needs to be pushed down.<br><br><br>Some Text of child 2 that is very long and needs to be pushed down.
        </p>
    </div>
</div>

也在 JSFiddle

你可能会改进这个脚本,只是想向你展示一个 jQuery 解决方案:

$('.collapsible').on('click', function(e) {
	var thisCollapsible = $(this);
	var thisContent = thisCollapsible.next();
	thisCollapsible.toggleClass('active');
	if( thisCollapsible.hasClass('active') ) {
		thisContent.slideDown(200);
	} else {
		thisContent.slideUp(200);
	};
});
.collapsible {
    background-color: #eee;
    color: #444;
    cursor: pointer;
    padding: 18px;
    width: 100%;
    border: none;
    text-align: left;
    outline: none;
    font-size: 15px;
}

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

.content {
    display: none;
    padding: 0 18px;
    overflow: hidden;
    background-color: #f1f1f1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="collapsible"><span>Main Parent</span></button>
<div class="content">
    <button class="collapsible"><span>Child 1</span> </button>
    <div class="content">
        <p>
            Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to
            be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.Some Text of child 1 that is very long and needs to be pushed down.
        </p>
    </div>
    <button class="collapsible"><span>Child 2</span></button>
    <div class="content">
        <p>
            Some Text of child 2 that is very long and needs to be pushed down.<br><br><br>Some Text of child 2 that is very long and needs to be pushed down.
        </p>
    </div>
</div>

也在 Playground here

关于javascript - 可折叠的 div block 嵌套在另一个 block 中以重新调整整个 block 的最大高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58383432/

相关文章:

javascript - 我正在尝试通过 url 传递 javascript 变量

javascript - 创建 Wordpress 网站的移动版本

html - CSS - 显示 :none on hover self

javascript - 尝试创建大量变量和 for 循环是行不通的

javascript - Visual Studio 2013 - AngularJS 基本问题

jquery - Bootstrap 侧边栏仅切换顶部

java - 使用 Java 自动提交 HTML 表单以查找杂货店营业时间

php - 使用我的网络表单和 api 上传到我的 soundcloud 帐户?

javascript - 如何使用 jquery isotope 按日期排序(新)

HTML 不允许我添加上边距