3

我有一个正在构建的页面,我想让它在我滚动(向上或向下)时页面滚动到下一个 div(每个 div 是窗口高度的 100%)。并在那里“固定”,直到您再次滚动。我正在努力完成的一个例子可以在这里看到:

http://testdays.hondamoto.ch/

您会注意到,当您向下滚动时,它会自动将您移动到下一个“div”。

我试过的:

  • 使用 jQuery .scroll 事件并结合:

        function updatePosition() {
          if(canScroll) {
            var pageName;
            canScroll = false;
            var st = $(window).scrollTop();
            if (st > lastScrollTop){
               // downscroll code
               if(pageNumber < 7) {
                   pageNumber++;
               }
               pageName = '#' + getPageToScrollTo().id;
               $('body').animate({ scrollTop: $(pageName).offset().top }, 2000, function() {
                   canScroll = true;
               });
            } else {
              // upscroll code
              if(pageNumber > 0) {
                  pageNumber--;
              }
              pageName = '#' + getPageToScrollTo().id;
              $('body').animate({ scrollTop: $(pageName).offset().top }, 2000, function() {
                   canScroll = true;
                });
            }
            lastScrollTop = st;
          }
        }
    

但是当页面滚动(动画)和用户滚动时,滚动事件被调用。我只需要在用户滚动时调用它。

然后我补充说:

var throttled = _.throttle(updatePosition, 3000);

$(document).scroll(throttled);

来自 Underscore.js 库 - 但它仍然做了同样的事情。

最后,我在这里浏览了一下,发现:

仅在用户滚动时调用 Scroll,而不是在 animate()

但我无法实施该解决方案。有没有人知道任何库或方法可以使它工作?

编辑:基于基本答案的解决方案:

  function nextPage() {
        canScroll = false;
        if(pageNumber < 7) {
            pageNumber++;
        }
        pageName = getPageToScrollTo();
        $('html, body').stop().animate({ scrollTop: $(pageName).offset().top }, 1000, function() {
            canScroll = true;
        });
    }

    function prevPage() {
        canScroll = false;
        if(pageNumber > 0) {
        pageNumber--;
      }
      pageName = getPageToScrollTo();
      $('html, body').stop().animate({ scrollTop: $(pageName).offset().top }, 1000, function() {
         canScroll = true;
      });
    }

    //--Bind mouseWheel
    $(window).on(mousewheelevt, function(event) {
        event.preventDefault();
        if(canScroll){
          if(mousewheelevt == "mousewheel") {
              if (event.originalEvent.wheelDelta >= 0) {
                prevPage();
              } else {
                nextPage();
              }
          } else if(mousewheelevt == "DOMMouseScroll") {
              if (event.originalEvent.detail >= 0) {
                nextPage();
              } else {
                prevPage();
              }
          }
        }
    });
4

1 回答 1

3

行...

本田网站的相关代码可以在http://testdays.hondamoto.ch/js/script_2.js中找到。它似乎正在做一些计算来定位 div 的顶部然后滚动到它。有用于不同类型滚动的处理程序。

具体来说,运动由function navigation(target)

关键位在这里...

$('html,body').stop().animate({
        scrollTop: $(target).offset().top + newMargin
    }, 1000,'easeInOutExpo',function(){
        //Lots of "page"-specific stuff
    }
});

有滚动类型的处理程序......

$('body').bind('touchstart', function(event) {
    //if(currentNav!=3){
        // jQuery clones events, but only with a limited number of properties for perf reasons. Need the original event to get 'touches'
        var e = event.originalEvent;
        scrollStartPos = e.touches[0].pageY;
    //}
});

//--Bind mouseWheel
$('*').bind('mousewheel', function(event, delta) {
    event.preventDefault();
    //trace('class : '+$(this).attr('class') + '   id : '+$(this).attr('id'));
    if(!busy && !lockScrollModel && !lockScrollMap){
        if(delta<0){
            nextPage();
        }else{
            prevPage();
        }
    }
});

You'll note that the navigate() function sets a busy flag which is unset when scrolling completes - which is how it suppresses all new scroll events during a scroll. Try changing the direction of scroll while the page is already scrolling and you'll notice user input is being ignored too.

于 2012-10-11T22:30:16.670 回答