javascript 滚动到下一部分

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29760049/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 11:01:35  来源:igfitidea点击:

Scroll to next section

javascriptjquerycssscroll

提问by Matheus Souza

My code looks like this:

我的代码如下所示:

<div id="arrow">
    <a class="next"></a>
    <a class="previous"></a>
</div>

<section id="first">
...
</section>

<section id="second">
...
</section>

<section id="third">
...
</section>

The element #arrowhas position: fixed, and I'm trying to make the window scroll to the next sectionwhen a.nextis clicked.

该元素#arrow具有position: fixed,并且我试图sectiona.next单击时使窗口滚动到下一个。

Ex: The first time a.nextis clicked, the window scrolls to section#first, the second time, the window scrolls to section#second, etc. The same thing happens to a.previous.

例如:第一次a.next点击,窗口滚动到section#first,第二次,窗口滚动到section#second,等等。同样的事情发生在a.previous

Does someone know how to solve this problem?

有人知道如何解决这个问题吗?

Thanks a lot!

非常感谢!



EDIT

编辑

My JS code:

我的JS代码:

$('#arrows a.previous').click(function() {
    $.scrollTo($(this).closest('section').prev(),800);
});

$('#arrows a.next').click(function() {
    $.scrollTo($(this).closest('section').next(),800);
});     

回答by Shlomi Hassid

You will need to handle to 3 events in this case:

在这种情况下,您需要处理 3 个事件:

  1. Current page position - updated each time.
  2. User scrolls manualy the page.
  3. User clicks the prev or next button.
  1. 当前页面位置 - 每次更新。
  2. 用户手动滚动页面。
  3. 用户单击上一个或下一个按钮。

2, 3 need to use the current page position and update him according to the direction that the page is scrolling.

2、3需要使用当前页面位置,根据页面滚动的方向更新他。

My quick demos : Vertical Version jsFiddle--- Horizontal Version jsFiddle

我的快速演示:垂直版本 jsFiddle--- 水平版本 jsFiddle

Vertical Version snippet :

垂直版本片段:

$(function(){
    
    var pagePositon = 0,
        sectionsSeclector = 'section',
        $scrollItems = $(sectionsSeclector),
        offsetTolorence = 30,
        pageMaxPosition = $scrollItems.length - 1;
    
    //Map the sections:
    $scrollItems.each(function(index,ele) { $(ele).attr("debog",index).data("pos",index); });

    // Bind to scroll
    $(window).bind('scroll',upPos);
    
    //Move on click:
    $('#arrow a').click(function(e){
        if ($(this).hasClass('next') && pagePositon+1 <= pageMaxPosition) {
            pagePositon++;
            $('html, body').stop().animate({ 
                  scrollTop: $scrollItems.eq(pagePositon).offset().top
            }, 300);
        }
        if ($(this).hasClass('previous') && pagePositon-1 >= 0) {
            pagePositon--;
            $('html, body').stop().animate({ 
                  scrollTop: $scrollItems.eq(pagePositon).offset().top
              }, 300);
            return false;
        }
    });
    
    //Update position func:
    function upPos(){
       var fromTop = $(this).scrollTop();
       var $cur = null;
        $scrollItems.each(function(index,ele){
            if ($(ele).offset().top < fromTop + offsetTolorence) $cur = $(ele);
        });
       if ($cur != null && pagePositon != $cur.data('pos')) {
           pagePositon = $cur.data('pos');
       }                   
    }
    
});
section { min-height:800px; }
#arrow {
    position:fixed; 
    right:0; 
    top:0;
    background-color:black;
    color:white;
}
#arrow a{
    display:inline-block;
    padding:10px 20px;
    cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="arrow">
    <a class="next">next</a>
    <a class="previous">prev</a>
</div>
<section style="background-color:green">...</section>
<section style="background-color:blue">...</section>
<section style="background-color:red">...</section>

回答by Roko C. Buljan

All you need, to allow the user to use both arrows and scrollbar:

您只需要允许用户同时使用箭头和滚动条:

var $sec = $("section");
$(".prev, .next").click(function(){
    var y = $sec.filter(function(i, el) {
        return el.getBoundingClientRect().bottom > 0;
    })[$(this).hasClass("next")?"next":"prev"]("section").offset().top;
    $("html, body").stop().animate({scrollTop: y});
});
*{margin:0;padding:0;}
#arrow{
  position:fixed;
  width:100%;
  text-align:center;
}
#arrow a{
  display:inline-block;
  background: tomato;
  padding:6px 15px;
  border-radius:3px;
  cursor:pointer;
}
section{
  height:1200px;
  border:3px solid #444;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="arrow"><a class="prev">&uarr;</a><a class="next">&darr;</a></div>
<section>1</section>
<section style="height:500px;">2</section>
<section>3</section>
<section style="height:600px;">4</section>
<section>5</section>



To explain the jQuery a bit:

稍微解释一下 jQuery:

// Cache your selectors
var $sec = $("section"); 

// On any of both arrows click
$(".prev, .next").click(function(){

    // We need to get current element
    // before defining the `.next()` or `.prev()` element to target
    // and get it's `offset().top` into an `y` variable we'll animate to.
    // A current element is always the one which bottom position
    // (relative to the browser top) is higher than 0.
    var y = $sec.filter(function(i, el) {
        return el.getBoundingClientRect().bottom > 0;
    })[$(this).hasClass("next")?"next":"prev"]("section").offset().top;
    // (Line above:) if the clicked button className was `"next"`,
    // target the the `.next("section")`, else target the `.prev("section")`
    // and retrieve it's `.offset().top`

    $("html, body").stop().animate({scrollTop: y});

});

回答by Anis Boukhris

i have tried to do with .closest("section") but it only works when the section is a parent of the element you clicked so this is the best way i got

我曾尝试使用 .closest("section") 但它仅在该部分是您单击的元素的父级时才有效,所以这是我得到的最好方法

sections=$("section");
s=0;

$(".next").click(function() {
if(s<sections.length-1){
s++;
$('html, body').animate({
   scrollTop: sections.eq(s).offset().top
}, 500);
}});

$(".previous").click(function() {
if(s>0){
s--;
$('html, body').animate({
   scrollTop: sections.eq(s).offset().top
}, 500);
}});
section{
    background-color:#bbb;
    width:100%;
    height:700px;
    border-bottom:2px solid #eee;
}
#arrow{
    position:fixed;

}

#first{
 background-color: red;
}
#second{
 background-color:green;
}
#third{
 background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="arrow">
    <a class="next">next</a>
    <a class="previous">prev</a>
</div>

<section id="first">
...
</section>

<section id="second">
...
</section>

<section id="third">
...
</section>