【问题标题】:Javascript collapsible panel open by defaultJavascript 可折叠面板默认打开
【发布时间】:2018-09-05 10:52:18
【问题描述】:

我正在按照此代码示例found here 使用 css/html/javascript 创建一个可折叠面板:

function toggleCollapsibleSectionWithAnimation() {
  this.classList.toggle("collapsible-active");
  var buttonId = this.id;
  var sectionId = buttonId.replace("button","section");
  var content = document.getElementById(sectionId);
  if (content.style.maxHeight) {
    content.style.maxHeight = null;
  } else {
    content.style.maxHeight = content.scrollHeight + "px";
  }
}
/* Style the button that is used to open and close the collapsible content */
.collapsible {
  background-color: transparent;
  color: #444;
  cursor: pointer;
  width: auto;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
}

/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */
.collapsible-active, .collapsible:hover {
  text-decoration: underline;
}

/* Style the collapsible content. Note: hidden by default */
.collapsible-content {
  max-height: 0;
  padding: 10px;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}

/* Style the collapsible content. Note: shown by default */
.collapsible-content-shown-by-default {
  max-height: 100%;
  padding: 10px;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}
<button class="collapsible" id="collapsible-button-0" onclick="toggleCollapsibleSectionWithAnimation.call(this)"><b>Model</b> (show/hide)</button>
<div class="collapsible-content" id="collapsible-section-0">
  <h1>
  content
  </h1>
</div>

此代码有效,默认情况下可折叠部分将被隐藏。

我想反转这个,所以我的面板默认显示,但它应该以完全相同的方式运行,单击可折叠按钮将打开或关闭下面的部分。

不确定如何反转起始变量。当它开始隐藏时,我们需要在内容面板上从 0 的 max-height 开始。在 javascript 中,这被更改为 content.scrollHeight 以打开面板。

这是一个 JSfiddle 示例:https://jsfiddle.net/trbk5vwg/9/

在 JSfiddle 中,如果您在“collapsible-content”和“collapsible-content-shown-by-default”之间交换 div 类,您将看到切换只能以一种方式工作。

我不确定如何在 css 中获得 scrollHeight,因此不确定如何初始化默认显示面板的 maxHeight(100% 不起作用)。

【问题讨论】:

  • 能否提供一个jsfiddle
  • jsfiddle.net/trbk5vwg/8 好的,试试这个 JSFiddle,它可以工作:如果你在 collapsible-content-shown-by-default 和 collapsible-content 之间更改内部 div 的类,那么你可以看到它只能以一种方式工作
  • 您是否尝试过通过模拟点击来欺骗可折叠设备? document.getElementById("collapsible-button-0").click()
  • 好主意,我现在试试,谢谢
  • 你可以做这个纯CSS。

标签: javascript html css


【解决方案1】:

快速简便的解决方案:

使用下面解释的逻辑(答案底部),我们可以通过简单地将 max-height 的内联声明添加到“collapsible-content” div 来解决问题:

<div class="collapsible-content" id="collapsible-section-0" style="max-height: 100%">

Javascript 解决方案:

工作代码是:

/* Style the button that is used to open and close the collapsible content */
.collapsible {
  background-color: transparent;
  color: #444;
  cursor: pointer;
  width: auto;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
}

/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */
.collapsible-active, .collapsible:hover {
  text-decoration: underline;
}

/* Style the collapsible content. Note: hidden by default */
.collapsible-content {
  max-height: 100%;
  padding: 10px;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}

/* Style the collapsible content. Note: shown by default */
.collapsible-content-shown-by-default {
  max-height: 100%;
  padding: 10px;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}
<script>
	function toggleCollapsibleSectionWithAnimation() {
		this.classList.toggle("collapsible-active");
		var buttonId = this.id;
		var sectionId = buttonId.replace("button","section");
		var content = document.getElementById(sectionId);
    var mHeight = window.getComputedStyle(content).maxHeight;
		if (mHeight !== "0px"){
		  content.style.maxHeight = "0px";
		} else {
		  content.style.maxHeight = "100%";
		}
	}</script>

<button class="collapsible" id="collapsible-button-0" onclick="toggleCollapsibleSectionWithAnimation.call(this)"><b>Model</b> (show/hide)</button>
<div class="collapsible-content" id="collapsible-section-0">

<h1>
content
</h1>


</div>

为什么这些工作:

您不能只在 css 文件中将 max-height 更改为 100% 的原因:在您的原始 JSFiddle 中,单击按钮时的第一个“if 语句”正在读取 content.style.maxHeight.style 实际上读取内联 css,在原始情况下,这意味着它将 maxHeight 读取为 null。将外部 css(非内联)更改为 100% 时,.style.maxHeight 函数仍将 maxHeight 读取为 null。

要在 html/css 中解决这个问题,我们只需将初始内联 css 设置为“max-height: 100%”,这样content.style.maxHeight 函数就会返回正确的值。

要在 JS 中解决这个问题,我们可以使用window.getComputedStyle(content).maxHeight,它将读取 computed 样式(包括内联和外部 css)。因为我们无法直接更改计算样式,所以我们可以编辑内联 css 以覆盖最初声明的外部 css (max-height: 100%)。当单击按钮时调用下一个“if 语句”时,计算的样式将返回内联 css。

【讨论】:

  • 很好的答案,感谢您的示例和解释
  • 谢谢,不客气。我实际上有一个面对面的时刻意识到我最初错过了最简单的解决方案。答案已被编辑以包含一个更简单的解决方案。祝你好运!
  • 另一种解决方案是一个不错的解决方案,但我喜欢 javascript 解决方案的明确性,并且我已经添加了该代码,所以我会继续使用它!
  • 您的快速简单的解决方案有一个问题,即在加载页面后第一次转换无法正常工作。我只是更改了 jsfiddle 中的两行:&lt;button class="collapsible collapsible-active" id="collapsible-button-0" onclick="toggleCollapsibleSectionWithAnimation.call(this)"&gt;&lt;b&gt;Model&lt;/b&gt; (show/hide)&lt;/button&gt; &lt;div class="collapsible-content" id="collapsible-section-0" style="max-height: 100%"&gt;
【解决方案2】:

试试这个

<script>

    function toggleCollapsibleSectionWithAnimation() {
     this.classList.toggle("collapsible-active");

        var buttonId = this.id;
        var sectionId = buttonId.replace("button","section");
        var content = document.getElementById(sectionId);

        var isDefaultMode = content.classList.contains('collapsible-content-shown-by-default');

    if (isDefaultMode) {
      content.classList.remove("collapsible-content-shown-by-default");
      content.style.maxHeight = 0;
    }

        if (content.style.maxHeight) {
          content.style.maxHeight = null;
        } else {
          content.style.maxHeight = content.scrollHeight + "px";
        }
    }</script>

<button class="collapsible collapsible-active" id="collapsible-button-0" onclick="toggleCollapsibleSectionWithAnimation.call(this)"><b>Model</b> (show/hide)</button>
<div class="collapsible-content collapsible-content-shown-by-default" id="collapsible-section-0">

<h1>
content
</h1>


</div>

我已将其设置为实质上的点击后模式。

【讨论】:

  • 感谢您的回答,我已接受 Zaks 的解释回答
猜你喜欢
  • 2018-07-02
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2015-07-17
  • 1970-01-01
  • 2020-06-22
  • 2022-01-03
  • 2012-09-23
相关资源
最近更新 更多