在类似手风琴的选项卡上完成另一个运行功能

时间:2016-10-06 07:45:02

标签: javascript jquery accordion jquery-callback

我正在尝试做手风琴效果之类的事情。当您单击“选项卡”时,它应该关闭已经打开的那个,然后打开单击的那个。 但正在发生的事情是它首先打开一个点击的,然后关闭已经打开的那个。

你可以在这里看到它: https://boguz.github.io/SWCanonTimeline/

我正在使用以下jQuery:

// DOCUMENT READY FUNCTION
$(document).ready(function () {

// CLICK ON STRIPE
$(".stripe").on("click", function() {

    closeStripe();

    openStripe( $(this) );

});

}); // end of document.ready


// CLOSE OPEN STRIPE
function closeStripe() {

    $(".open").removeClass("open");

}

// OPEN CLICKED STRIPE
function openStripe(stripe) {

    stripe.addClass("open");

}

我尝试过使用$.when().done(),但没有设法让它发挥作用。我也尝试将其作为回调函数,但没有成功。

3 个答案:

答案 0 :(得分:2)

你的问题不在于JavaScript。您可以同时触发两个动画,因此它们应该同时发生(并且它们会发生)。但它们是CSS转换,它们适用于max-heightThis question实际上非常相似。

您将max-height1000px转换为100px会发生什么情况,但您的元素只有700px高,所以您不会看到任何内容对于第一个300px

您可以做的是等待closeStripe()动画完成setTimeout()

$(".stripe").on("click", function() {
    closeStripe();
    var duration = Number($(this).css('transition-duration').match(/\d+(\.\d+)?/)[0])*1000;
    setTimeout(function () {
        openStripe($(this));
    }, duration);
});

这从transition-duration属性获取持续时间并将其转换为字符串(未经过充分测试)。

答案 1 :(得分:1)

观察到的延迟是由max-height属性的转换引起的。开放式手风琴的最大高度设置为1000px,而闭合的手风琴设置为100px。这意味着浏览器将执行从100px到1000px的转换。当您的开放式手风琴的实际内容高度不是1000px时,转换将会延迟,因为浏览器只是将值从1000px向下补间,并且内容只会在补间值达到或小于值时折叠max-height

另一种解决方案是基于JS的解决方案,您可以使用.slideUp(500).slideDown(500)代替CSS转换。这些jQuery函数将考虑手风琴的实际高度,而不是补间max-height属性。



$(document).ready(function () {
  $(".stripe").on("click", function() {
    closeStripe();
    openStripe($(this));
  });
});

// CLOSE OPEN STRIPE
function closeStripe() {
  $(".stripe").removeClass("open").find("div.content").slideUp(500);
}
// OPEN CLICKED STRIPE
function openStripe(stripe) {
  stripe.addClass("open").find("div.content").slideDown(500);
}

* {
  margin: 0;
  padding: 0;
  font-family: "Ubuntu";
}
body, html { width: 100vw; }
section.head {
  width: 100vw;
  height: 80px;
  background-color: #f4f2f2;
}
.menu {
  height: 80px;
  width: 260px;
  float: left;
}
h1.title {
  width: calc( 100vw - 520px );
  height: 80px;
  float: left;
  text-align: center;
  line-height: 80px;
  text-transform: uppercase;
  font-weight: 300;
  color: #666;
}
.social {
  width: 260px;
  height: 80px;
  float: right;
}
.stripe {
  width: 100vw;
  text-align: center;
  border: 10px solid transparent;
  cursor: pointer;
  overflow: hidden;
}
.stripe[data-eventType="book"] { background-color: #F4D03F; }
.stripe[data-eventType="comic"] { background-color: #E67E22; }
.stripe[data-eventType="movie"] { background-color: #D64541; }
.stripe[data-eventType="tv"] { background-color: #C0392B; }
.stripe[data-eventType="game"] { background-color: #674172; }
.stripe:hover { border-color: #f4f2f2; }
.stripe.open:hover { border-color: transparent; }
.stripeTitle {
  font-size: 4em;
  color: white;
  line-height: 160px;
  text-transform: uppercase;
}
.content {
  width: calc( 100vw - 100px );
  background-color: #f4f2f2;
  margin: 0 auto;
  overflow: hidden;
  padding: 50px;
  display: none;
  box-sizing: border-box;
}
.content p {
  color: #666;
  font-weight: 300;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="head">
  <div class="menu"></div>
  <h1 class="title">Star Wars Canon Timeline</h1>
  <div class="social"></div>
</section>
<!-- end section.head -->
<section class="main">
  <div class="stripe" data-eventtype="movie">
    <h2 class="stripeTitle">32 bby</h2>
    <div class="content">
      <p>HERE WILL COME THE CONTENT</p>
    </div>
    <!-- end .content -->
  </div>
  <!-- end stripe -->
  <div class="stripe open" data-eventtype="comic">
    <h2 class="stripeTitle">29 bby</h2>
    <div class="content">
      <p>HERE WILL COME THE CONTENT</p>
    </div>
    <!-- end .content -->
  </div>
  <!-- end stripe -->
  <div class="stripe" data-eventtype="movie">
    <h2 class="stripeTitle">22 bby</h2>
    <div class="content">
      <p>HERE WILL COME THE CONTENT</p>
    </div>
    <!-- end .content -->
  </div>
  <!-- end stripe -->
  <div class="stripe" data-eventtype="movie">
    <h2 class="stripeTitle">22 bby</h2>
    <div class="content">
      <p>HERE WILL COME THE CONTENT</p>
    </div>
    <!-- end .content -->
  </div>
  <!-- end stripe -->
  <div class="stripe" data-eventtype="tv">
    <h2 class="stripeTitle">22 - 20 bby</h2>
    <div class="content">
      <p>HERE WILL COME THE CONTENT</p>
    </div>
    <!-- end .content -->
  </div>
  <!-- end stripe -->
  <div class="stripe" data-eventtype="comic">
    <h2 class="stripeTitle">20 bby</h2>
    <div class="content">
      <p>HERE WILL COME THE CONTENT</p>
    </div>
    <!-- end .content -->
  </div>
  <!-- end stripe -->
</section>
<!-- end section.main -->
&#13;
&#13;
&#13;

答案 2 :(得分:0)

我最终遵循了Terry的建议,并使用jQuery中的toggleSlide函数为选项卡设置动画。

以下是我现在使用的代码:

// DOCUMENT READY FUNCTION
$(document).ready(function () {

    // on tab click
    $(".stripe").on("click", function() {

        // close all open tabs
        $(this).siblings().children(".content").slideUp();

        // open just clicked tab
        $(this).children(".content").slideToggle();

    });

}); // end of document.ready