Javascript 回调未按正确顺序触发
Javascript callbacks not firing in correct order
我正在使用 jQuery、skrollr 和 skrollr-menu 创建特定的导航动画。我想要的动画如下:
- 用户点击 link
- 黑色div 淡出页面
- 页面滚动到下面的位置
- 黑色div淡出页面
您可以在 http://www.gramercyparkhotel.com/ 看到该动画的示例。这看起来很简单;然而,随着 <div>
淡入,滚动在动画结束之前被触发,导致在屏幕变黑之前滚动内容闪烁。这不应该发生,因为一切都是使用回调定时的,所以如果动画还没有完成,为什么要调用滚动的后续函数?
编辑
我在下面添加了一个代码片段。看起来好像在动画完成之前正在调用 animateTo
调用。 animateTo
滚动到顶部,然后滚动到正确的位置。如果回调确实按其应有的方式运行,我不关心这种行为。
$(document).ready( function() {
// Initialize skrollr
var s = skrollr.init({
keyframe: function(element, name, direction) {
$(element).trigger(name, [direction]);
}
});
function hideFader($fader, callback) {
var callback = callback || function() { return false; };
$fader.animate({
'opacity': 0
}, 500, function() {
$fader.css('top', '-100%');
callback();
});
}
function showFader($fader, callback) {
var callback = callback || function() { return false; };
$fader.css('top', '0%');
$fader.animate({
'opacity': 1
}, 500, callback);
}
var $fader = $('#fader');
hideFader($fader);
skrollr.menu.init(s, {
animate: false,
handleLink: function(link) {
showFader($fader, function() {
var $location = $($(link).attr('href')),
menuTop;
if($(link).attr('href') === '#home') {
menuTop = 0;
} else {
menuTop = Math.round(parseInt($location.attr('data-dtcp')) / 100 * $('#home').height());
}
s.animateTo(menuTop, {
duration: 0,
done: function() {
hideFader($fader);
}
});
});
},
complexLinks: false,
updateUrl: false
});
});
.navigation-centered {
position: fixed;
bottom: 0;
width: 100%;
background-color: #171511;
background-color: rgba(23, 21, 17, 0.9);
z-index: 1000;
}
.navigation-centered .navigation-centered-wrapper {
position: relative;
border: 10px solid transparent;
padding: 15px 0;
min-width: 100%;
}
.navigation-centered ul.navigation-centered-menu {
clear: both;
display: none;
margin: 0 auto;
overflow: visible;
padding: 0;
width: 100%;
display: block;
text-align: center;
}
.navigation-centered ul.navigation-centered-menu.show {
display: block;
}
.navigation-centered ul li.nav-link {
display: block;
text-align: right;
width: 100%;
display: inline;
}
.navigation-centered ul li.nav-link a {
display: inline-block;
color: #b5b4b2;
text-decoration: none;
outline: none;
}
.navigation-centered ul li.nav-link a:hover, .navigation-centered ul li.nav-link a:active, .navigation-centered ul li.nav-link a:visited, .navigation-centered ul li.nav-link a:focus {
color: #b5b4b2;
text-decoration: none;
outline: none;
}
.navigation-centered ul li.nav-link:after {
content: '[=12=]B7';
padding-right: 1em;
display: inline-block;
color: #b5b4b2;
}
.navigation-centered ul li.nav-link:last-child:after {
content: '';
display: none;
}
.navigation-centered ul li.nav-link a {
padding-right: 1em;
}
.fullscreen, #fader {
height: 100%;
width: 100%;
height: 100vh;
width: 100vw;
}
#home {
background-color: red;
}
#about {
background-color: blue;
}
#gallery {
background-color: green;
}
#contact {
background-color: yellow;
}
#blog {
background-color: purple;
}
#fader {
position: fixed;
z-index: 10000;
background: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://sid.artlyticalmedia.com/wp-content/themes/sanctuariesinteriordesign/bower_components/skrollr/dist/skrollr.min.js"></script>
<script src="http://sid.artlyticalmedia.com/wp-content/themes/sanctuariesinteriordesign/bower_components/skrollr-menu/dist/skrollr.menu.min.js"></script>
<div id="home" class="fullscreen"
data-dtcp="0"
data-0p="top: 0%;"
data-100p="top: -100%;">
<h1>home</h1>
</div>
<div id="gallery" class="fullscreen"
data-dtcp="100"
data-100p="top: 100%;"
data-200p="top: 0%;"
data-300p="top: -100%;">
<h1>gallery</h1>
</div>
<div id="about" class="fullscreen"
data-dtcp="200"
data-200p="top: 100%;"
data-300p="top: 0%;"
data-400p="top: -100%;">
<h1>about</h1>
</div>
<div id="blog" class="fullscreen"
data-dtcp="400"
data-300p="top: 100%;"
data-400p="top: 0%;"
data-500p="top: -100%;">
<h1>blog</h1>
</div>
<div id="contact" class="fullscreen"
data-dtcp="500"
data-400p="top: 100%;"
data-500p="top: 0%;"
data-600p="top: -100%;">
<h1>contact</h1>
</div>
<div id="fader"></div>
<footer id="footer">
<nav id="nav-main" class="nav-main" role="navigation">
<div class="navigation-centered" role="banner">
<div class="navigation-centered-wrapper">
<nav role="navigation">
<ul id="js-navigation-centered-menu" class="navigation-centered-menu show">
<li class="nav-link">
<a href="#home">home</a>
</li>
<li class="nav-link">
<a href="#gallery">gallery</a>
</li>
<li class="nav-link">
<a href="#about">about</a>
</li>
<li class="nav-link">
<a href="#blog">blog</a>
</li>
<li class="nav-link">
<a href="#contact">contact</a>
</li>
</ul>
</nav>
</div>
</div>
</nav><!-- #nav -->
</footer>
问题是如果 handleLink
函数不返回任何值,skrollr-menu
将默认滚动到 0。我通过在函数末尾添加 return null;
来修复它。
我正在使用 jQuery、skrollr 和 skrollr-menu 创建特定的导航动画。我想要的动画如下:
- 用户点击 link
- 黑色div 淡出页面
- 页面滚动到下面的位置
- 黑色div淡出页面
您可以在 http://www.gramercyparkhotel.com/ 看到该动画的示例。这看起来很简单;然而,随着 <div>
淡入,滚动在动画结束之前被触发,导致在屏幕变黑之前滚动内容闪烁。这不应该发生,因为一切都是使用回调定时的,所以如果动画还没有完成,为什么要调用滚动的后续函数?
编辑
我在下面添加了一个代码片段。看起来好像在动画完成之前正在调用 animateTo
调用。 animateTo
滚动到顶部,然后滚动到正确的位置。如果回调确实按其应有的方式运行,我不关心这种行为。
$(document).ready( function() {
// Initialize skrollr
var s = skrollr.init({
keyframe: function(element, name, direction) {
$(element).trigger(name, [direction]);
}
});
function hideFader($fader, callback) {
var callback = callback || function() { return false; };
$fader.animate({
'opacity': 0
}, 500, function() {
$fader.css('top', '-100%');
callback();
});
}
function showFader($fader, callback) {
var callback = callback || function() { return false; };
$fader.css('top', '0%');
$fader.animate({
'opacity': 1
}, 500, callback);
}
var $fader = $('#fader');
hideFader($fader);
skrollr.menu.init(s, {
animate: false,
handleLink: function(link) {
showFader($fader, function() {
var $location = $($(link).attr('href')),
menuTop;
if($(link).attr('href') === '#home') {
menuTop = 0;
} else {
menuTop = Math.round(parseInt($location.attr('data-dtcp')) / 100 * $('#home').height());
}
s.animateTo(menuTop, {
duration: 0,
done: function() {
hideFader($fader);
}
});
});
},
complexLinks: false,
updateUrl: false
});
});
.navigation-centered {
position: fixed;
bottom: 0;
width: 100%;
background-color: #171511;
background-color: rgba(23, 21, 17, 0.9);
z-index: 1000;
}
.navigation-centered .navigation-centered-wrapper {
position: relative;
border: 10px solid transparent;
padding: 15px 0;
min-width: 100%;
}
.navigation-centered ul.navigation-centered-menu {
clear: both;
display: none;
margin: 0 auto;
overflow: visible;
padding: 0;
width: 100%;
display: block;
text-align: center;
}
.navigation-centered ul.navigation-centered-menu.show {
display: block;
}
.navigation-centered ul li.nav-link {
display: block;
text-align: right;
width: 100%;
display: inline;
}
.navigation-centered ul li.nav-link a {
display: inline-block;
color: #b5b4b2;
text-decoration: none;
outline: none;
}
.navigation-centered ul li.nav-link a:hover, .navigation-centered ul li.nav-link a:active, .navigation-centered ul li.nav-link a:visited, .navigation-centered ul li.nav-link a:focus {
color: #b5b4b2;
text-decoration: none;
outline: none;
}
.navigation-centered ul li.nav-link:after {
content: '[=12=]B7';
padding-right: 1em;
display: inline-block;
color: #b5b4b2;
}
.navigation-centered ul li.nav-link:last-child:after {
content: '';
display: none;
}
.navigation-centered ul li.nav-link a {
padding-right: 1em;
}
.fullscreen, #fader {
height: 100%;
width: 100%;
height: 100vh;
width: 100vw;
}
#home {
background-color: red;
}
#about {
background-color: blue;
}
#gallery {
background-color: green;
}
#contact {
background-color: yellow;
}
#blog {
background-color: purple;
}
#fader {
position: fixed;
z-index: 10000;
background: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://sid.artlyticalmedia.com/wp-content/themes/sanctuariesinteriordesign/bower_components/skrollr/dist/skrollr.min.js"></script>
<script src="http://sid.artlyticalmedia.com/wp-content/themes/sanctuariesinteriordesign/bower_components/skrollr-menu/dist/skrollr.menu.min.js"></script>
<div id="home" class="fullscreen"
data-dtcp="0"
data-0p="top: 0%;"
data-100p="top: -100%;">
<h1>home</h1>
</div>
<div id="gallery" class="fullscreen"
data-dtcp="100"
data-100p="top: 100%;"
data-200p="top: 0%;"
data-300p="top: -100%;">
<h1>gallery</h1>
</div>
<div id="about" class="fullscreen"
data-dtcp="200"
data-200p="top: 100%;"
data-300p="top: 0%;"
data-400p="top: -100%;">
<h1>about</h1>
</div>
<div id="blog" class="fullscreen"
data-dtcp="400"
data-300p="top: 100%;"
data-400p="top: 0%;"
data-500p="top: -100%;">
<h1>blog</h1>
</div>
<div id="contact" class="fullscreen"
data-dtcp="500"
data-400p="top: 100%;"
data-500p="top: 0%;"
data-600p="top: -100%;">
<h1>contact</h1>
</div>
<div id="fader"></div>
<footer id="footer">
<nav id="nav-main" class="nav-main" role="navigation">
<div class="navigation-centered" role="banner">
<div class="navigation-centered-wrapper">
<nav role="navigation">
<ul id="js-navigation-centered-menu" class="navigation-centered-menu show">
<li class="nav-link">
<a href="#home">home</a>
</li>
<li class="nav-link">
<a href="#gallery">gallery</a>
</li>
<li class="nav-link">
<a href="#about">about</a>
</li>
<li class="nav-link">
<a href="#blog">blog</a>
</li>
<li class="nav-link">
<a href="#contact">contact</a>
</li>
</ul>
</nav>
</div>
</div>
</nav><!-- #nav -->
</footer>
问题是如果 handleLink
函数不返回任何值,skrollr-menu
将默认滚动到 0。我通过在函数末尾添加 return null;
来修复它。