简体   繁体   English

div位置在滚动位置上的动画位置

[英]Animate position of div on scroll position

What's the best way to animate the position of a div on scroll position? 在滚动位置上设置div位置动画的最佳方法是什么? Essentially, when you reach a certain point on the page... a fixed element will animate up. 本质上,当您到达页面上的某个点时,固定的元素将产生动画。

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/KcFdE6 and 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. 这是我正在开发的开发站点: http : //goo.gl/KcFdE6 ,如您所见,如果滚动到底部并停止,它会很好地向上滑动,但是,如果您继续滚动...它是与动画互动,您可以真正跳动/缓慢过渡。 Any ideas? 有任何想法吗?

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 class作为标志。

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);
     }
});

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. 视口+ marginBot的底部通过元素后,元素就会滚动。 It's fixed afterwards until it's goin top again. 之后将其修复,直到再次进入顶部。

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. 考虑到您提到的是iffy动画而不是实际的div放置,这个问题是,即使您已经设置了动画,您的js代码也会在每次滚动时执行。 This causes you to stop the animation and restart it. 这将导致您停止动画并重新启动它。 This is the cause of the slow and laggy animation effect you are seeing. 这是导致您看到缓慢而缓慢的动画效果的原因。

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 code You will need to take into account that if they are scrolling up, it is okay to stop the animation and reverse direction. 代码未经测试,但是是所需代码的近似值。您需要考虑到,如果它们向上滚动,则可以停止动画和反向操作。

First check this demo 首先检查这个 演示

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.css file 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. 不要忘记下载animate.css文件并将其添加到您的网站。 you can choose animation effect. 您可以选择动画效果。

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.使用一个防反跳功能-换句话说,您想限制滚动侦听器,使其每隔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). B.分步进行动画处理-换句话说,每次调用动画函数时,它不会对容器的整个大小进行动画处理,而只会对滚动量(或设置的步长)进行动画处理。 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. 诸如tween.js之类的库使此操作变得容易。

I'd use css transitions instead of jquery animate as follows, so that you don't have to worry about the animation queue. 我将使用css过渡而不是jquery animate ,如下所示,这样您就不必担心动画队列。

(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');
 }
});

Demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM