运行 一个接一个的功能在类似手风琴的选项卡上完成
Run function after another is finished on accordion-like tabs
我正在尝试做类似手风琴效果的事情。当您单击 "tab" 时,它应该关闭已经打开的那个,然后打开被单击的那个。
但是发生的事情是它首先打开点击的那个,然后关闭已经打开的那个。
你可以在这里看到:
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()
但没成功。我也试过让它成为一个回调函数,但没有成功。
观察到的延迟是由于 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 -->
您的问题不在于 JavaScript。您同时触发两个动画,因此它们应该同时发生(它们确实发生了)。但它们是 CSS 转换,它们是针对 max-height
。 This question 实际上很相似。
发生的情况是您将 max-height
从 1000px
向下过渡到 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
属性 获取持续时间并将其转换为字符串(未经过充分测试)。
我最终听从了 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
我正在尝试做类似手风琴效果的事情。当您单击 "tab" 时,它应该关闭已经打开的那个,然后打开被单击的那个。 但是发生的事情是它首先打开点击的那个,然后关闭已经打开的那个。
你可以在这里看到: 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()
但没成功。我也试过让它成为一个回调函数,但没有成功。
观察到的延迟是由于 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 -->
您的问题不在于 JavaScript。您同时触发两个动画,因此它们应该同时发生(它们确实发生了)。但它们是 CSS 转换,它们是针对 max-height
。 This question 实际上很相似。
发生的情况是您将 max-height
从 1000px
向下过渡到 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
属性 获取持续时间并将其转换为字符串(未经过充分测试)。
我最终听从了 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