Open clicked tab and close the rest

你离开我真会死。 提交于 2020-06-17 09:38:09

问题


I'm using JQuery to adjust some accordions. I have the accordion logic ready, but can't get the desired result. I would like that when a tab is clicked, that particular tab opens and the others close if they are open. And if an open tab is clicked, that particular tab closes too. So at any given time, only one tab should be open, but all tabs can be closed. Here is the fiddle https://jsfiddle.net/4d5mjgza/

 $(function() {
    $('.collapsible-trigger').on('click', function() {
        var panel = $(this).next()[0];
        $('.collapsible-trigger').not($(this)).removeClass('is-open');
        $('.collapsible-content').not(collapsible-content).removeClass('is-open');
        $(this).toggleClass('is-open');
        $(panel).toggleClass("is-open");
    });
});

Here is the HTML:

<div class="collapsibles-wrapper collapsibles-wrapper--border-bottom">
  <button type="button" class="label collapsible-trigger collapsible-trigger-btn collapsible-trigger-btn--borders collapsible--auto-height" aria-controls="content" aria-expanded="false">
    TITLE 1 <span class="collapsible-trigger__icon collapsible-trigger__icon--open" role="presentation">
      <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon--wide icon-chevron-down" viewBox="0 0 28 16">
        <path d="M1.57 1.59l12.76 12.77L27.1 1.59" stroke-width="2" stroke="#000" fill="none" fill-rule="evenodd"></path>
      </svg>
    </span>

  </button>
  <div id="content1" class="collapsible-content collapsible-content--all is-open" style="height: auto;">
    <div class="collapsible-content__inner rte">
      hello 1
    </div>
  </div>

And the CSS:

/*================ Collapsible trigger ================*/

.collapsible-trigger-btn {
  text-align: left !important;
  @include baseTextCenter;
  @include accentFontStack;
  @include accentFontSmallSize;
  padding-left: 0px !important;
  display: block;
  width: 100%;
  padding: ($gutter / 1.75) 0;

  @include media-query($small) {
    padding: ($gutter / 2) 0;
  }
}

.collapsible-trigger-btn--borders {
  border: 1px solid $colorBorder;
  border-top: 0;
  border-right: 0;
  border-left: 0;
  padding: 12px;
  border-color: #343434 !important;
  padding-bottom: 0px !important;
  font-size: 13px;
  letter-spacing: normal;
  font-weight: 600;

  @include media-query($small) {
    font-size: 12px;
  }

  .collapsible-trigger__icon {
    right: 12px;
  }

  @include media-query($medium-up) {
    padding: 15px;

    .collapsible-trigger__icon {
      right: 15px;
    }
  }

  .collapsible-content+& {
    margin-top: -1px;
  }

  +.collapsible-content .collapsible-content__inner {
    @include baseExtraSmallFontStack;
    border: 0px solid $colorBorder;
    border-top: 0;
    padding: 15px 0px 10px 0px;

    @include media-query($medium-up) {
      @include baseSmallFontStack;
      font-size: 13px;
      line-height: 1.5;
    }

    @include media-query($small) {
      font-size: 12px;
      line-height: 1.5;
    }
  }

  +.collapsible-content--expanded {
    margin-bottom: $gutter;

    &:last-child {
      margin-bottom: -1px;
    }
  }
}

.collapsible-trigger-btn--borders-top {
  border-top: 1px solid $colorBorder;
}



  <button type="button" class="label collapsible-trigger collapsible-trigger-btn collapsible-trigger-btn--borders collapsible--auto-height" aria-controls="content" aria-expanded="true">
    TITLE 2 <span class="collapsible-trigger__icon collapsible-trigger__icon--open" role="presentation">
      <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon--wide icon-chevron-down" viewBox="0 0 28 16">
        <path d="M1.57 1.59l12.76 12.77L27.1 1.59" stroke-width="2" stroke="#000" fill="none" fill-rule="evenodd"></path>
      </svg>
    </span>

  </button>
  <div id="content2" class="collapsible-content collapsible-content--all is-open" style="height: auto;">
    <div class="collapsible-content__inner rte">
      hello 2
    </div>
  </div>





  <button type="button" class="label collapsible-trigger collapsible-trigger-btn collapsible-trigger-btn--borders" aria-controls="content" aria-expanded="true">
    TITLE 3 <span class="collapsible-trigger__icon collapsible-trigger__icon--open" role="presentation">
      <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon--wide icon-chevron-down" viewBox="0 0 28 16">
        <path d="M1.57 1.59l12.76 12.77L27.1 1.59" stroke-width="2" stroke="#000" fill="none" fill-rule="evenodd"></path>
      </svg>
    </span>

  </button>
  <div id="content3" class="collapsible-content collapsible-content--all is-open" style="height: auto;">
    <div class="collapsible-content__inner rte">
      hello 3
    </div>
  </div>

Could any of you please lend a helping hand? Would be much appreciated, thank you!


回答1:


In my opinion you have much of code which could be minified. But you can also just extract the core ideas of the following jQuery function.

If you have any questions or problems, you can write a short comment.

$(function() {

  // you can also use the whole item as a trigger with this: $('.accordion .accordion-item')
  $('.accordion .accordion-title').on('click', toggleAccordion);

  function toggleAccordion(event) {
    var target = $(event.target).closest('.accordion-item');

    target.parent('.accordion').find('.accordion-item').not(target).removeClass('is-open');
    target.toggleClass('is-open');
  }
  
});
.accordion .accordion-item {
  border-bottom: 1px solid #000;
}

.accordion .accordion-title {
  position: relative;
  padding: 15px;
  cursor: pointer;
}

.accordion .accordion-content {
  display: none;
  padding: 0 15px 15px;
}

.accordion .accordion-item.is-open .accordion-content {
  display: block;
}

.accordion .arrow {
  position: absolute;
  display: inline-block;
  padding: 5px;
  top: 13px;
  right: 15px;
  background-color: inherit;
  border: solid #000;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
}

.accordion .accordion-item.is-open .arrow {
  top: 20px;
  transform: rotate(-135deg);
  -webkit-transform: rotate(-135deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="accordion">
  <div class="accordion-item">
    <div class="accordion-title">
      TITLE 1
      <span class="arrow"></span>
    </div>
    <div class="accordion-content">
      CONTENT 1
    </div>
  </div>
  <div class="accordion-item">
    <div class="accordion-title">
      TITLE 2
      <span class="arrow"></span>
    </div>
    <div class="accordion-content">
      CONTENT 2
    </div>
  </div>
  <div class="accordion-item">
    <div class="accordion-title">
      TITLE 3
      <span class="arrow"></span>
    </div>
    <div class="accordion-content">
      CONTENT 3
    </div>
  </div>
</div>

Solution without an accordion-item element

This is a solution to your problem from your comment. I do not prefer this one, because it would be too unstructured for me. But it's your decision.

I hope that I can help you with this:

$(function() {

  $('.accordion .accordion-title').on('click', toggleAccordion);

  function toggleAccordion(event) {
    var target = $(event.target)
    var content = target.next('.accordion-content');

    content.parent('.accordion').find('.accordion-content').not(content).removeClass('is-open');
    target.toggleClass('is-open');
    content.toggleClass('is-open');
  }
  
});
.accordion .accordion-title {
  position: relative;
  padding: 15px;
  cursor: pointer;
}

.accordion .accordion-title:not(:first-child) {
  border-top: 1px solid #000;
}

.accordion .accordion-content {
  display: none;
  padding: 0 15px 15px;
}

.accordion .accordion-content.is-open {
  display: block;
}

.accordion .arrow {
  position: absolute;
  display: inline-block;
  padding: 5px;
  top: 13px;
  right: 15px;
  background-color: inherit;
  border: solid #000;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
}

.accordion .accordion-title.is-open .arrow {
  top: 20px;
  transform: rotate(-135deg);
  -webkit-transform: rotate(-135deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="accordion">
  <div class="accordion-title">
    TITLE 1
    <span class="arrow"></span>
  </div>
  <div class="accordion-content">
    CONTENT 1
  </div>
  <div class="accordion-title">
    TITLE 2
    <span class="arrow"></span>
  </div>
  <div class="accordion-content">
    CONTENT 2
  </div>
  <div class="accordion-title">
    TITLE 3
    <span class="arrow"></span>
  </div>
  <div class="accordion-content">
    CONTENT 3
  </div>
</div>


来源:https://stackoverflow.com/questions/61786991/open-clicked-tab-and-close-the-rest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!