javascript 滚动位置上 div 的动画位置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24290472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Animate position of div on scroll position
提问by John the Painter
What's the best way to animate the position of a div on scroll position? Essentially, when you reach a certain point on the page... a fixed element will animate up.
在滚动位置上为 div 的位置设置动画的最佳方法是什么?从本质上讲,当您到达页面上的某个点时……一个固定元素将动画化。
I have included below what I currently have... but it's a little slow and seems to slide up... slowly... half way... then complete. Any thoughts?
我在下面列出了我目前拥有的……但它有点慢,似乎向上滑动……慢慢……中途……然后完成。有什么想法吗?
var shareHeight = $('.related-share-container').height();
$('.related-share-container').css('bottom',-shareHeight);
$(window).scroll(function() {
if ($(window).scrollTop() + $(window).height() > $(document).height() - 150) {
$('.related-share-container').stop().animate({ bottom: 0 }, 500);
} else {
$('.related-share-container').stop().animate({ bottom: -shareHeight }, 500);
}
});
UPDATE FOR REWARD
奖励更新
This is the dev site I am working on: http://goo.gl/KcFdE6and as you can see, if you scroll to the bottom and stop, it slides up fairly well, BUT, if you keep scrolling... it's interacting with the animation and you can a really jumpy/slow transition. Any ideas?
这是我正在开发的开发站点:http: //goo.gl/KcFdE6,正如你所看到的,如果你滚动到底部并停止,它会很好地向上滑动,但是,如果你继续滚动......它是与动画交互,您可以进行非常跳跃/缓慢的过渡。有任何想法吗?
回答by demonofthemist
It is happening cause for each scroll movement previous animation get stopped and new begins, which is slower than previous one cause it has less distance to animate. Thus you need some flag in your code to prevent same animation triggering again and again.
这是因为每次滚动移动前一个动画停止并开始新的动画,这比前一个动画慢,因为它的动画距离更短。因此,您需要在代码中使用一些标志来防止相同的动画一次又一次地触发。
Modified JS:
修改后的JS:
Here I am using done
class as a flag.
在这里,我使用done
类作为标志。
var shareHeight = $('.related-share-container').height();
$('.related-share-container').css('bottom',-shareHeight);
$(window).scroll(function() {
if ($(window).scrollTop() + $(window).height() > $(document).height() - 150) {
if(!$('.related-share-container').hasClass('done'))
$('.related-share-container').addClass('done').stop().animate({ bottom: 0 }, 500);
} else {
if($('.related-share-container').hasClass('done'))
$('.related-share-container').removeClass('done').stop().animate({ bottom: -shareHeight }, 500);
}
});
回答by gulty
If I understood you correctly you want an element which is somewhere on the page to scroll once it's on a specific position of the viewport.
如果我理解正确,您希望页面上某处的元素在位于视口的特定位置时滚动。
Check this fiddle: http://jsfiddle.net/6bZab/11/JS:
检查这个小提琴:http: //jsfiddle.net/6bZab/11/JS:
var oldElemBottom;
function isScrolledIntoView(elem) {
var win = $(window),
marginBot = 20,
docViewTop = $(window).scrollTop(),
docViewBottom = docViewTop + $(window).height(),
elemTop = $(elem).offset().top,
elemBottom = elemTop + $(elem).height();
if (typeof oldElemBottom !== 'undefined'){
elemBottom = oldElemBottom;
}
if ((win.scrollTop() + win.height() - marginBot) >= elemBottom){
oldElemBottom = elemBottom;
return true
} else {
return false
};
}
CSS:
CSS:
#container {
width: 100%;
height: 1000px;
}
#elem {
width:80px;
height:50px;
background:#333;
color:#FFF;
text-align:center;
right: 0;
}
.first{
background-color: green;
height: 1000px;
}
.absolute_pos{
position: absolute;
top: 600px;
}
Element is scrolling as soon as the bottom of the viewport + marginBot passes the element. It's fixed afterwards until it's goin top again.
只要视口底部 + marginBot 通过元素,元素就会滚动。之后它会被修复,直到它再次回到顶部。
回答by Justin
Going off the fact that you mention the iffy animation rather than actual div placement, the problem is that your js code executes every time you scroll, even if you are already animating. This causes you to stop the animation and restart it. This is the cause of the slow and laggy animation effect you are seeing.
考虑到您提到的是 iffy 动画而不是实际的 div 位置,问题是每次滚动时都会执行 js 代码,即使您已经在制作动画。这会导致您停止动画并重新启动它。这就是您所看到的缓慢而滞后的动画效果的原因。
What you need to do is keep track of if you are animating and react based on that so the animation has a chance to complete.
您需要做的是跟踪您是否正在制作动画并基于此做出反应,以便动画有机会完成。
//...
var isAnimating = false;
$(this).bind('scroll', function() {
//jQuery does have a :animated selector as well that can handle this
if(!isAnimating){
isAnimating = true;
var y = $(this).outerHeight() + api.getContentPositionY() + 600 >= api.getContentHeight();
if (y) {
$('.related-share-container').animate({ 'margin-bottom': 0 }, { queue: false, duration: 300 }, 'slow', function(){ isAnimating = false; });
} else {
$('.related-share-container').animate({ 'margin-bottom': -shareHeight - 30 }, { queue: false, duration: 300 }, 'slow', function(){ isAnimating = false; });
}
}
});
Warning! Code not tested but is an approximation of needed codeYou will need to take into account that if they are scrolling up, it is okay to stop the animation and reverse direction.
警告!代码未经测试,但是是所需代码的近似值您需要考虑到,如果它们向上滚动,则可以停止动画并反转方向。
回答by Nayem Majhar
First check thisdemo
首先检查这个演示
CSS
CSS
.related-share-container{
position: fixed;
left: 0;
bottom: 0;
width: 100%;
z-index: 9999;
padding: 15px 0;
font-size: 16px;
display:none;
}
download animate.cssfile and link to your file
下载animate.css文件并链接到您的文件
JS
JS
$(window).scroll(function(e) {
if ($(window).scrollTop() + $(window).height() > $(document).height() - 150) {
$('.related-share-container').removeClass('rotateOutUpLeft').addClass('animated rotateInUpLeft').show();
} else {
$('.related-share-container').removeClass('rotateInUpLeft').addClass('rotateOutUpLeft');
}
});
Its working perfect. don't forget to download animate.css file and add to your site. you can choose animation effect.
它的工作完美。不要忘记下载 animate.css 文件并添加到您的站点。您可以选择动画效果。
回答by Etai
You have 2 options, both of which are good, but the latter is better:
您有 2 个选择,两者都不错,但后者更好:
A. Use a debounced function - in other words, you want to throttle the scroll listener so that it only happens once out of every X milliseconds, so if someone is mid-scroll, it won't happen.
A. 使用 debounced 函数 - 换句话说,您希望限制滚动侦听器,使其每 X 毫秒仅发生一次,因此如果有人在滚动中,则不会发生。
Libraries such as lodash provide this as _.debounce(fn, time);
诸如 lodash 之类的库将其提供为 _.debounce(fn, time);
If you don't use a library, this can be achieved like this (I'm using the code from your current site):
如果您不使用库,则可以这样实现(我使用的是您当前站点的代码):
var shareHeight = $('.related-share-container').height();
$('.related-share-container').css('height',shareHeight);
$('.project-content-container').css('margin-bottom',shareHeight);
$('.related-share-container').css('margin-bottom',-shareHeight - 30);
var timeout,
elem = $(this);
elem.bind('scroll', function() {
clearTimeout(timeout);
timeout = setTimeout(function(){
var y = elem.outerHeight() + api.getContentPositionY() + 600 >= api.getContentHeight();
if (y) {
$('.related-share-container').stop(true).animate({ 'margin-bottom': 0 }, { queue: false, duration: 300 });
} else {
$('.related-share-container').stop(true).animate({ 'margin-bottom': -shareHeight - 30 }, { queue: false, duration: 300 });
}
}, 50); //50ms debounce time
});
B. Animate in steps - in other words, each time your animate function will be called, it will not animate the full size of the container, but will only animate the amount that was scrolled (or a set step size). This is actually a much better solution, since currently, if someone scrolls down and the huge footer pops up, it's almost impossible to scroll back up. Libraries such as tween.js make this easy.
B. 分步动画 - 换句话说,每次你的动画函数被调用时,它不会动画容器的整个大小,而只会动画滚动的数量(或设置的步长)。这实际上是一个更好的解决方案,因为目前,如果有人向下滚动并弹出巨大的页脚,则几乎不可能向上滚动。诸如 tween.js 之类的库使这变得容易。
回答by T J
I'd use css transitions instead of jquery animate
as follows, so that you don't have to worry about the animation queue.
我会使用 css transitions 而不是 jqueryanimate
如下,这样你就不必担心动画队列。
(Using css, You could even make use of hardware acceleration)
(使用css,你甚至可以利用硬件加速)
css
css
.element-to-animate {
/*your style rules*/
transform: translate3d(0, 0, 0);
transition:height .5s linear;
}
.hide {
height:0 !important;
}
script:
脚本:
var sliderTop = $(window).height() - 150;
$(window).scroll(function () {
var scrollTop = $(window).scrollTop();
if (scrollTop > sliderTop) {
if ($('.overlay').hasClass('hide'))
$('.overlay').removeClass('hide');
} else {
if (!$('.overlay').hasClass('hide'))
$('.overlay').addClass('hide');
}
});