检查div是否在视图中,如果是,则移动到窗口顶部

时间:2016-04-06 14:16:20

标签: javascript jquery html

我有一个全屏画笔,当用户点击最后一张幻灯片时,会自动向下滚动到内容。这部分就是这样做的:

heroSwiper.on('onReachEnd', function(){

    setTimeout(function(){
      $('html,body').animate({
        scrollTop: $(".section").offset().top
      });
      heroSwiper.lockSwipes();
      heroSwiper.disableMousewheelControl();
  }, 100);

});

heroMediaSwiper.on('onReachEnd', function(){

    setTimeout(function(){
      $('html,body').animate({
        scrollTop: $(".section").offset().top
      });       
      heroMediaSwiper.lockSwipes();
      heroMediaSwiper.disableMousewheelControl();
  }, 100);

});

如果用户然后从内容向上滚动并且部分swiper在视图中,那么我希望它滚动到窗口的最顶部。 所以从理论上讲,你要么看到全屏闪光灯,要么看到主要内容。

如果英雄横幅的一部分在视野中,这应该让用户到达窗口的顶部:

$(window).scroll(function(){
    setTimeout(function(){
    if ($('#hero').isOnScreen(0.3, 0.3) == true) {

        $('html,body').animate({
            scrollTop: $("#hero").offset().top
            heroSwiper.slideTo(0);      
            heroSwiper.enableMousewheelControl();
            heroSwiper.unlockSwipes();
            heroMediaSwiper.slideTo(0);
            heroMediaSwiper.enableMousewheelControl();
            heroMediaSwiper.unlockSwipes();
        });           
    };
    }, 100);    
});

此时它会向下滚动到主要内容,然后直接返回到页面顶部。

这是检查某些内容是否在视图中的脚本:

$.fn.isOnScreen = function(){

    var win = $(window);

    var viewport = {
        top : win.scrollTop(),
        left : win.scrollLeft()
    };
    viewport.right = viewport.left + win.width();
    viewport.bottom = viewport.top + win.height();

    var bounds = this.offset();
    bounds.right = bounds.left + this.outerWidth();
    bounds.bottom = bounds.top + this.outerHeight();

    return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));

};

或者如果有更好的方法可以做到这一点,请告诉我!!

2 个答案:

答案 0 :(得分:1)

您可能希望限制窗口滚动处理程序调用。当你的animate函数导致滚动本身时,你想完全绕过滚动处理程序。

使用滚动处理程序时,我建议使用_.throttle(或debounce),如果您使用underscore,则可以访问。您也可以从_.throttle复制_.now的来源定义(以及它依赖的underscore annotated source)。

$(function () {
  var THROTTLE_TIME = 10; // throttle the window scroll handler
  var timer = null; // clearTimeout(timer) if you want to cancel it
  var waiting = false;

  $(window).scroll(_.throttle(function(){
    // the animation takes time, so wait for it to complete
    if(waiting) return;

    if ($('#hero').isOnScreen(0.3, 0.3) == true) {
      waiting = true; // we're going to do the animation
      // could do clearTimeout(timer) here, but waiting takes care of that
      timer = setTimeout(function(){
        var done = false;
        $('html,body').animate({
            scrollTop: $("#hero").offset().top
          },
          function () {
            // executed twice (once for html and once for body)
            waiting = false; // animation is complete
            if(!done) {
              done = true; // only want to run this stuff once:
              heroSwiper.slideTo(0);      
              heroSwiper.enableMousewheelControl();
              heroSwiper.unlockSwipes();
              heroMediaSwiper.slideTo(0);
              heroMediaSwiper.enableMousewheelControl();
              heroMediaSwiper.unlockSwipes();
            }
          }
        );
      }, 100);
    }
  }, THROTTLE_TIME));
});

答案 1 :(得分:0)

目前,每当满足任何条件时,您就会触发超时。但是你不能取消任何先前的超时。因此,所有超时最终都会被触发,这可能不是您想要的。这是一个片段:

//Declare a timeout variable outside those functions that is visible to all of them
var myTimeout;

对于您调用的每个超时,请执行以下操作:

clearTimeout(myTimeout);
myTimeout = setTimeout(function(){
    /* your code goes here */
},/* your timer goes here */);