打开另一个面板时关闭一个面板

时间:2017-03-12 03:52:50

标签: javascript jquery html css

如果其中一个面板处于打开状态,我希望这样做,当您点击另一个面板时,它会关闭。 我查看了一些类似于我的其他问题,但似乎它们都使用了不同的方法。

这是一个小提琴:https://jsfiddle.net/3q87y2u8/

继承人JS:

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

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

我也希望得到&#39; +&#39;在盘旋时改变颜色。有点像目前的文字。我似乎无法在CSS中直接调用它。

谢谢!

6 个答案:

答案 0 :(得分:1)

更可读和更有效的方法是简单地保存对先前切换的手风琴项目的引用。

当调用onclick时,您首先要检查cur是否是单击面板。这样,切换cur就会关闭它。接下来,将cur设置为null,以便在单击其他面板时不会打开上一个面板。然后确保退出该功能。请注意,您必须在非空检查cur。

之前执行此操作

否则,将现在活动的项检查为当前以确保它不为空,然后切换cur和this。通过将cur设置为此来包装它,所以下次它可以重新执行它!

另外,这是一个小提琴:https://jsfiddle.net/d7smh9ru/4/

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

for (i = 0; i < acc.length; i++) {
  acc[i].onclick = function() {

    // Only close already open panel
    if (cur == this) {
      toggleItem(cur);
      cur = null;
      return;
    }

    // Close current panel, and open this panel
    if (cur) {
      toggleItem(cur);
    }

    toggleItem(this);
    cur = this;
  }
}

function toggleItem(item) {
  item.classList.toggle("active");
  var panel = item.nextElementSibling;
  if (panel.style.maxHeight) {
    panel.style.maxHeight = null;
  } else {
    panel.style.maxHeight = panel.scrollHeight + "px";
  }
}

答案 1 :(得分:1)

您可以获取当前处于活动状态的元素,然后删除活动类,如下所示:

// Is an array of elements matching the selector
var active = document.getElementsByClassName('active');

// If there are any matching elements and it is not the same one that has just been clicked on
if (active.length && active[0] !== this) {
    active[0].classList.remove('active');
}

一方评论(您当然可以忽略!):对于最大高度,您不需要计算高度(除非它会干扰您已经设置了页面结构的方式)。您可以使用一些较大的高度,因为它是您设置的最大高度而不是高度,它将自动达到其自然高度。您也可以使用CSS(包括动画)来实现这一点,并且还会在下面包含更新加号上的悬停文本。

// Set regular state height to 0 and add a transition effect
.panel {
    max-height: 0px;
    transition: max-height .25s ease;
}

// For whatever button is active find the adjacent panel and set its max height and a transition effect
.active + .panel {
  max-height: 250px;
  transition: max-height .25s ease;
}

// Here is where you change the color of the active and hovered plus/minus sign
button.accordion.active:after,
button.accordion:hover:after {
  color: red;
}

https://jsfiddle.net/xz2mpzg2/1/ https://jsfiddle.net/xz2mpzg2/2/

答案 2 :(得分:0)

单击按钮后,

缩小所有div。这里的jsfiddle https://jsfiddle.net/3q87y2u8/3/

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

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

答案 3 :(得分:0)

在审核您的代码后,我发现您只打开了当前标签,未关闭其他标签。所以试试这个

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

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

答案 4 :(得分:0)

只需使用jQuery即可轻松使用:

A。) .toggle();

B。).change();

C。).addClass(); / removeClass();

答案 5 :(得分:0)

我相信你正在寻找这样的事情:JSFiddle

我将完成我所做的每一项更改,并且每个语句也会被注释,但作为一般原则,我更改了您的代码,以便在每组按钮/文本周围使用包装器div,并且我将文本放在内部div内,以便尊重max-height。而不是事件处理程序修改其下一个兄弟,这将失败,例如,如果您的段落被单独括在p标记中而不是使用br内的p标记进行换行。这也使得使用父:hover伪类实现悬停变化加彩色效果变得微不足道。

因此,如果您更改按钮/文本组:

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

为:

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

并更新您的CSS,将您的panel课程更改为content(之前从您的JSFiddle第50行开始):

.content {
  overflow: hidden;
  transition: max-height 0.2s ease-out;
  padding-left: 50px;
  background-color: #f6f6f6;
  width: 220px;
  font-size: 10px;
  max-height: 100px;
}

并使用CSS在未打开的面板上将max-height设置为0

div.panel:not(.opened) > .content {
  max-height: 0;
}

然后,您可以在按钮上设置事件侦听器,只需切换父opened类:

document.querySelectorAll('.accordion')
  .forEach(element => {
    element.onclick = function() {

      // first, iterate over other open panels and close them...
      // note: using Array.from(...) so we can filter the result below.
      Array.from(document.querySelectorAll('.panel.opened'))

        // ...but skip the clicked panel, which will be dealt with below
        // [edit] we filter here so we can close an already-open panel
        .filter(panel => panel !== this.parentNode)

        .forEach(panel => {

          // toggle the 'opened' class, forcing `false`
          panel.classList.toggle('opened', false)

          // and remove styling that was set on the element itself
          panel.querySelector('.content').style.maxHeight = null;
        });

      // now toggle the clicked panel's 'opened' class and capture its new value
      const toggled = this.parentNode.classList.toggle('opened');

      // reference the new div.content, inside the button's parent
      const content = this.parentNode.querySelector('.content');

      // and either fix its max height or unset it, depending on new state
      content.style.maxHeight = toggled? `${content.scrollHeight}px` : null;
    }
  });

最后,如果你想改变&#39; +&#39;突出显示颜色,现在您可以使用:hover上的.panel伪类来执行此操作:

div.panel:hover > button.accordion:after {
  color: red;
}