滚动到页面上的特定元素

时间:2022-11-05 19:50:46

I want to have 4 buttons/links on the beginning of the page, and under them the content.

我想在页面的开头有4个按钮/链接,在它们下面有内容。

On the buttons I put this code:

在按钮上我把这个代码:

<a href="#idElement1">Scroll to element 1</a>
<a href="#idElement2">Scroll to element 2</a>
<a href="#idElement3">Scroll to element 3</a>
<a href="#idElement4">Scroll to element 4</a>

And under links there will be content:

在链接下将有内容:

<h2 id="idElement1">Element1</h2>
content....
<h2 id="idElement2">Element2</h2>
content....
<h2 id="idElement3">Element3</h2>
content....
<h2 id="idElement4">Element4</h2>
content....

It is working now, but cannot make it look more smooth.

它现在正在工作,但不能让它看起来更顺畅。

I used this code, but cannot get it to work.

我使用了这段代码,却无法使用它。

$('html, body').animate({
    scrollTop: $("#elementID").offset().top
}, 2000);

Any suggestions? Thank you.

有什么建议么?谢谢。

Edit: and the fiddle: http://jsfiddle.net/WxJLx/2/

编辑:和小提琴:http://jsfiddle.net/WxJLx/2/

8 个解决方案

#1


20  

Just made this javascript only solution below.

刚刚在下面制作了这个javascript解决方案。

Simple usage:

简单用法:

EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);

Engine object (you can fiddle with filter, fps values):

引擎对象(你可以使用filter,fps值):

/**
 *
 * Created by Borbás Geri on 12/17/13
 * Copyright (c) 2013 eppz! development, LLC.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */


var EPPZScrollTo =
{
    /**
     * Helpers.
     */
    documentVerticalScrollPosition: function()
    {
        if (self.pageYOffset) return self.pageYOffset; // Firefox, Chrome, Opera, Safari.
        if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop; // Internet Explorer 6 (standards mode).
        if (document.body.scrollTop) return document.body.scrollTop; // Internet Explorer 6, 7 and 8.
        return 0; // None of the above.
    },

    viewportHeight: function()
    { return (document.compatMode === "CSS1Compat") ? document.documentElement.clientHeight : document.body.clientHeight; },

    documentHeight: function()
    { return (document.height !== undefined) ? document.height : document.body.offsetHeight; },

    documentMaximumScrollPosition: function()
    { return this.documentHeight() - this.viewportHeight(); },

    elementVerticalClientPositionById: function(id)
    {
        var element = document.getElementById(id);
        var rectangle = element.getBoundingClientRect();
        return rectangle.top;
    },

    /**
     * Animation tick.
     */
    scrollVerticalTickToPosition: function(currentPosition, targetPosition)
    {
        var filter = 0.2;
        var fps = 60;
        var difference = parseFloat(targetPosition) - parseFloat(currentPosition);

        // Snap, then stop if arrived.
        var arrived = (Math.abs(difference) <= 0.5);
        if (arrived)
        {
            // Apply target.
            scrollTo(0.0, targetPosition);
            return;
        }

        // Filtered position.
        currentPosition = (parseFloat(currentPosition) * (1.0 - filter)) + (parseFloat(targetPosition) * filter);

        // Apply target.
        scrollTo(0.0, Math.round(currentPosition));

        // Schedule next tick.
        setTimeout("EPPZScrollTo.scrollVerticalTickToPosition("+currentPosition+", "+targetPosition+")", (1000 / fps));
    },

    /**
     * For public use.
     *
     * @param id The id of the element to scroll to.
     * @param padding Top padding to apply above element.
     */
    scrollVerticalToElementById: function(id, padding)
    {
        var element = document.getElementById(id);
        if (element == null)
        {
            console.warn('Cannot find element with id \''+id+'\'.');
            return;
        }

        var targetPosition = this.documentVerticalScrollPosition() + this.elementVerticalClientPositionById(id) - padding;
        var currentPosition = this.documentVerticalScrollPosition();

        // Clamp.
        var maximumScrollPosition = this.documentMaximumScrollPosition();
        if (targetPosition > maximumScrollPosition) targetPosition = maximumScrollPosition;

        // Start animation.
        this.scrollVerticalTickToPosition(currentPosition, targetPosition);
    }
};

#2


41  

Super smoothly with requestAnimationFrame

For smoothly rendered scrolling animation one could use window.requestAnimationFrame() which performs better with rendering than regular setTimeout() solutions.

对于平滑渲染的滚动动画,可以使用window.requestAnimationFrame(),与常规的setTimeout()解决方案相比,渲染效果更好。

A basic example looks like this. Function step is called for browser's every animation frame and allows for better time management of repaints, and thus increasing performance.

一个基本的例子是这样的。为浏览器的每个动画帧调用函数步骤,并允许更好的时间管理重绘,从而提高性能。

function doScrolling(elementY, duration) { 
  var startingY = window.pageYOffset;
  var diff = elementY - startingY;
  var start;

  // Bootstrap our animation - it will get called right before next frame shall be rendered.
  window.requestAnimationFrame(function step(timestamp) {
    if (!start) start = timestamp;
    // Elapsed milliseconds since start of scrolling.
    var time = timestamp - start;
    // Get percent of completion in range [0, 1].
    var percent = Math.min(time / duration, 1);

    window.scrollTo(0, startingY + diff * percent);

    // Proceed with animation as long as we wanted it to.
    if (time < duration) {
      window.requestAnimationFrame(step);
    }
  })
}

For element's Y position use functions in other answers or the one in my below-mentioned fiddle.

对于元素的Y位置,使用其他答案中的函数或下面提到的小提琴中的函数。

I set up a bit more sophisticated function with easing support and proper scrolling to bottom-most elements: https://jsfiddle.net/s61x7c4e/

我设置了一个更复杂的功能,支持更轻松,并适当滚动到最底层的元素:https://jsfiddle.net/s61x7c4e/

#3


14  

Smooth scrolling - look ma no jQuery

Based on an article on itnewb.com i made a demo plunk to smoothly scroll without external libraries.

根据itnewb.com上的一篇文章,我做了一个演示插件,可以在没有外部库的情况下顺利滚动。

The javascript is quite simple. First a helper function to improve cross browser support to determine the current position.

javascript非常简单。首先是帮助函数,以改善跨浏览器支持以确定当前位置。

function currentYPosition() {
    // Firefox, Chrome, Opera, Safari
    if (self.pageYOffset) return self.pageYOffset;
    // Internet Explorer 6 - standards mode
    if (document.documentElement && document.documentElement.scrollTop)
        return document.documentElement.scrollTop;
    // Internet Explorer 6, 7 and 8
    if (document.body.scrollTop) return document.body.scrollTop;
    return 0;
}

Then a function to determine the position of the destination element - the one where we would like to scroll to.

然后是一个函数来确定目标元素的位置 - 我们想要滚动到的位置。

function elmYPosition(eID) {
    var elm = document.getElementById(eID);
    var y = elm.offsetTop;
    var node = elm;
    while (node.offsetParent && node.offsetParent != document.body) {
        node = node.offsetParent;
        y += node.offsetTop;
    } return y;
}

And the core function to do the scrolling

而滚动的核心功能

function smoothScroll(eID) {
    var startY = currentYPosition();
    var stopY = elmYPosition(eID);
    var distance = stopY > startY ? stopY - startY : startY - stopY;
    if (distance < 100) {
        scrollTo(0, stopY); return;
    }
    var speed = Math.round(distance / 100);
    if (speed >= 20) speed = 20;
    var step = Math.round(distance / 25);
    var leapY = stopY > startY ? startY + step : startY - step;
    var timer = 0;
    if (stopY > startY) {
        for ( var i=startY; i<stopY; i+=step ) {
            setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
            leapY += step; if (leapY > stopY) leapY = stopY; timer++;
        } return;
    }
    for ( var i=startY; i>stopY; i-=step ) {
        setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
        leapY -= step; if (leapY < stopY) leapY = stopY; timer++;
    }
    return false;
}

To call it you just do the following. You create a link which points to another element by using the id as a reference for a destination anchor.

要调用它,您只需执行以下操作即可。您可以使用id作为目标锚点的引用来创建指向另一个元素的链接。

<a href="#anchor-2" 
   onclick="smoothScroll('anchor-2');">smooth scroll to the headline with id anchor-2<a/>
...
...  some content
...
<h2 id="anchor-2">Anchor 2</h2>

Copyright

In the footer of itnewb.com the following is written: The techniques, effects and code demonstrated in ITNewb articles may be used for any purpose without attribution (although we recommend it) (2014-01-12)

在itnewb.com的页脚中写道如下:ITNewb文章中演示的技术,效果和代码可用于任何目的而不归因(尽管我们推荐)(2014-01-12)

#4


4  

I've been using this for a long time:

我已经使用了很长时间了:

function scrollToItem(item) {
    var diff=(item.offsetTop-window.scrollY)/8
    if (Math.abs(diff)>1) {
        window.scrollTo(0, (window.scrollY+diff))
        clearTimeout(window._TO)
        window._TO=setTimeout(scrollToItem, 30, item)
    } else {
        window.scrollTo(0, item.offsetTop)
    }
}

usage: scrollToItem(element) where element is document.getElementById('elementid') for example.

用法:scrollToItem(element),其中element是document.getElementById('elementid')。

#5


4  

Variation of @tominko answer. A little smoother animation and resolved problem with infinite invoked setTimeout(), when some elements can't allign to top of viewport.

@tominko答案的变化。当一些元素无法与视口顶部对齐时,使用无限调用的setTimeout()可以获得更平滑的动画和解决的问题。

function scrollToItem(item) {
    var diff=(item.offsetTop-window.scrollY)/20;
    if(!window._lastDiff){
        window._lastDiff = 0;
    }

    console.log('test')

    if (Math.abs(diff)>2) {
        window.scrollTo(0, (window.scrollY+diff))
        clearTimeout(window._TO)

        if(diff !== window._lastDiff){
            window._lastDiff = diff;
            window._TO=setTimeout(scrollToItem, 15, item);
        }
    } else {
        console.timeEnd('test');
        window.scrollTo(0, item.offsetTop)
    }
}

#6


2  

you can use this plugin. Does exactly what you want.

你可以使用这个插件。完全符合你的要求。

http://flesler.blogspot.com/2007/10/jqueryscrollto.html

http://flesler.blogspot.com/2007/10/jqueryscrollto.html

#7


0  

If one need to scroll to an element inside a div there is my solution based on Andrzej Sala's answer:

如果需要滚动到div中的元素,我的解决方案基于Andrzej Sala的答案:

function scroolTo(element, duration) {
    if (!duration) {
        duration = 700;
    }
    if (!element.offsetParent) {
        element.scrollTo();
    }
    var startingTop = element.offsetParent.scrollTop;
    var elementTop = element.offsetTop;
    var dist = elementTop - startingTop;
    var start;

    window.requestAnimationFrame(function step(timestamp) {
        if (!start)
            start = timestamp;
        var time = timestamp - start;
        var percent = Math.min(time / duration, 1);
        element.offsetParent.scrollTo(0, startingTop + dist * percent);

        // Proceed with animation as long as we wanted it to.
        if (time < duration) {
            window.requestAnimationFrame(step);
        }
    })
}

#8


-2  

Smooth scrolling with jQuery.ScrollTo

To use the jQuery ScrollTo plugin you have to do the following

要使用jQuery ScrollTo插件,您必须执行以下操作

  1. Create links where href points to another elements.id
  2. 创建href指向另一个elements.id的链接
  3. create the elements you want to scroll to
  4. 创建要滚动到的元素
  5. reference jQuery and the scrollTo Plugin
  6. 引用jQuery和scrollTo插件
  7. Make sure to add a click event handler for each link that should do smooth scrolling
  8. 确保为应该进行平滑滚动的每个链接添加一个单击事件处理程序

Creating the links

创建链接

<h1>Smooth Scrolling with the jQuery Plugin .scrollTo</h1>
<div id="nav-list">
  <a href="#idElement1">Scroll to element 1</a>
  <a href="#idElement2">Scroll to element 2</a>
  <a href="#idElement3">Scroll to element 3</a>
  <a href="#idElement4">Scroll to element 4</a>
</div>

Creating the target elements here only the first two are displayed the other headings are set up the same way. To see another example i added a link back to the navigation a.toNav

这里只创建前两个目标元素,其他标题的设置方式相同。为了看到另一个例子,我添加了一个回到导航a.toNav的链接

<h2 id="idElement1">Element1</h2>    
....
<h2 id="idElement1">Element1</h2>
... 
<a class="toNav" href="#nav-list">Scroll to Nav-List</a>

Setting the references to the scripts. Your path to the files may be different.

设置脚本的引用。您的文件路径可能不同。

<script src="./jquery-1.8.3.min.js"></script>
<script src="./jquery.scrollTo-1.4.3.1-min.js"></script>

Wiring it all up

The code below is borrowed from jQuery easing plugin

下面的代码是从jQuery缓动插件中借来的

jQuery(function ($) {
    $.easing.elasout = function (x, t, b, c, d) {
        var s = 1.70158;  var p = 0; var a = c;
        if (t == 0) return b;
        if ((t /= d) == 1) return b + c;
        if (!p) p = d * .3;
        if (a < Math.abs(c)) {
            a = c;   var s = p / 4;
        } else var s = p / (2 * Math.PI) * Math.asin(c / a);
        // line breaks added to avoid scroll bar
        return a * Math.pow(2, -10 * t)  * Math.sin((t * d - s) 
                 * (2 * Math.PI) / p) + c + b;
    };            

    // important reset all scrollable panes to (0,0)       
    $('div.pane').scrollTo(0); 
    $.scrollTo(0);    // Reset the screen to (0,0)
    // adding a click handler for each link 
    // within the div with the id nav-list
    $('#nav-list a').click(function () {             
        $.scrollTo(this.hash, 1500, {
            easing: 'elasout'
        });
        return false;
    });   
    // adding a click handler for the link at the bottom
    $('a.toNav').click(function () { 
        var scrollTargetId = this.hash;
        $.scrollTo(scrollTargetId, 1500, {
            easing: 'elasout'
        });
        return false;
    });    
});

Fully working demo on plnkr.co

You may take a look at the soucre code for the demo.

您可以查看演示的soucre代码。

Update May 2014

Based on another question i came across another solution from kadaj. Here jQuery animate is used to scroll to an element inside a <div style=overflow-y: scroll>

基于另一个问题,我遇到了kadaj的另一个解决方案。这里jQuery animate用于滚动到

中的元素

 $(document).ready(function () {
    $('.navSection').on('click', function (e) {
        debugger;
        var elemId = "";    //eg: #nav2
        switch (e.target.id) {
        case "nav1":
            elemId = "#s1";
            break;
        case "nav2":
            elemId = "#s2";
            break;
        case "nav3":
            elemId = "#s3";
            break;
        case "nav4":
            elemId = "#s4";
            break;
        }
        $('.content').animate({
            scrollTop: $(elemId).parent().scrollTop() 
                    + $(elemId).offset().top 
                    - $(elemId).parent().offset().top
        }, {
            duration: 1000,
            specialEasing: { width: 'linear'
                    , height: 'easeOutBounce' },
            complete: function (e) {
                //console.log("animation completed");
            }
        });
        e.preventDefault();
    });
  });

#1


20  

Just made this javascript only solution below.

刚刚在下面制作了这个javascript解决方案。

Simple usage:

简单用法:

EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);

Engine object (you can fiddle with filter, fps values):

引擎对象(你可以使用filter,fps值):

/**
 *
 * Created by Borbás Geri on 12/17/13
 * Copyright (c) 2013 eppz! development, LLC.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */


var EPPZScrollTo =
{
    /**
     * Helpers.
     */
    documentVerticalScrollPosition: function()
    {
        if (self.pageYOffset) return self.pageYOffset; // Firefox, Chrome, Opera, Safari.
        if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop; // Internet Explorer 6 (standards mode).
        if (document.body.scrollTop) return document.body.scrollTop; // Internet Explorer 6, 7 and 8.
        return 0; // None of the above.
    },

    viewportHeight: function()
    { return (document.compatMode === "CSS1Compat") ? document.documentElement.clientHeight : document.body.clientHeight; },

    documentHeight: function()
    { return (document.height !== undefined) ? document.height : document.body.offsetHeight; },

    documentMaximumScrollPosition: function()
    { return this.documentHeight() - this.viewportHeight(); },

    elementVerticalClientPositionById: function(id)
    {
        var element = document.getElementById(id);
        var rectangle = element.getBoundingClientRect();
        return rectangle.top;
    },

    /**
     * Animation tick.
     */
    scrollVerticalTickToPosition: function(currentPosition, targetPosition)
    {
        var filter = 0.2;
        var fps = 60;
        var difference = parseFloat(targetPosition) - parseFloat(currentPosition);

        // Snap, then stop if arrived.
        var arrived = (Math.abs(difference) <= 0.5);
        if (arrived)
        {
            // Apply target.
            scrollTo(0.0, targetPosition);
            return;
        }

        // Filtered position.
        currentPosition = (parseFloat(currentPosition) * (1.0 - filter)) + (parseFloat(targetPosition) * filter);

        // Apply target.
        scrollTo(0.0, Math.round(currentPosition));

        // Schedule next tick.
        setTimeout("EPPZScrollTo.scrollVerticalTickToPosition("+currentPosition+", "+targetPosition+")", (1000 / fps));
    },

    /**
     * For public use.
     *
     * @param id The id of the element to scroll to.
     * @param padding Top padding to apply above element.
     */
    scrollVerticalToElementById: function(id, padding)
    {
        var element = document.getElementById(id);
        if (element == null)
        {
            console.warn('Cannot find element with id \''+id+'\'.');
            return;
        }

        var targetPosition = this.documentVerticalScrollPosition() + this.elementVerticalClientPositionById(id) - padding;
        var currentPosition = this.documentVerticalScrollPosition();

        // Clamp.
        var maximumScrollPosition = this.documentMaximumScrollPosition();
        if (targetPosition > maximumScrollPosition) targetPosition = maximumScrollPosition;

        // Start animation.
        this.scrollVerticalTickToPosition(currentPosition, targetPosition);
    }
};

#2


41  

Super smoothly with requestAnimationFrame

For smoothly rendered scrolling animation one could use window.requestAnimationFrame() which performs better with rendering than regular setTimeout() solutions.

对于平滑渲染的滚动动画,可以使用window.requestAnimationFrame(),与常规的setTimeout()解决方案相比,渲染效果更好。

A basic example looks like this. Function step is called for browser's every animation frame and allows for better time management of repaints, and thus increasing performance.

一个基本的例子是这样的。为浏览器的每个动画帧调用函数步骤,并允许更好的时间管理重绘,从而提高性能。

function doScrolling(elementY, duration) { 
  var startingY = window.pageYOffset;
  var diff = elementY - startingY;
  var start;

  // Bootstrap our animation - it will get called right before next frame shall be rendered.
  window.requestAnimationFrame(function step(timestamp) {
    if (!start) start = timestamp;
    // Elapsed milliseconds since start of scrolling.
    var time = timestamp - start;
    // Get percent of completion in range [0, 1].
    var percent = Math.min(time / duration, 1);

    window.scrollTo(0, startingY + diff * percent);

    // Proceed with animation as long as we wanted it to.
    if (time < duration) {
      window.requestAnimationFrame(step);
    }
  })
}

For element's Y position use functions in other answers or the one in my below-mentioned fiddle.

对于元素的Y位置,使用其他答案中的函数或下面提到的小提琴中的函数。

I set up a bit more sophisticated function with easing support and proper scrolling to bottom-most elements: https://jsfiddle.net/s61x7c4e/

我设置了一个更复杂的功能,支持更轻松,并适当滚动到最底层的元素:https://jsfiddle.net/s61x7c4e/

#3


14  

Smooth scrolling - look ma no jQuery

Based on an article on itnewb.com i made a demo plunk to smoothly scroll without external libraries.

根据itnewb.com上的一篇文章,我做了一个演示插件,可以在没有外部库的情况下顺利滚动。

The javascript is quite simple. First a helper function to improve cross browser support to determine the current position.

javascript非常简单。首先是帮助函数,以改善跨浏览器支持以确定当前位置。

function currentYPosition() {
    // Firefox, Chrome, Opera, Safari
    if (self.pageYOffset) return self.pageYOffset;
    // Internet Explorer 6 - standards mode
    if (document.documentElement && document.documentElement.scrollTop)
        return document.documentElement.scrollTop;
    // Internet Explorer 6, 7 and 8
    if (document.body.scrollTop) return document.body.scrollTop;
    return 0;
}

Then a function to determine the position of the destination element - the one where we would like to scroll to.

然后是一个函数来确定目标元素的位置 - 我们想要滚动到的位置。

function elmYPosition(eID) {
    var elm = document.getElementById(eID);
    var y = elm.offsetTop;
    var node = elm;
    while (node.offsetParent && node.offsetParent != document.body) {
        node = node.offsetParent;
        y += node.offsetTop;
    } return y;
}

And the core function to do the scrolling

而滚动的核心功能

function smoothScroll(eID) {
    var startY = currentYPosition();
    var stopY = elmYPosition(eID);
    var distance = stopY > startY ? stopY - startY : startY - stopY;
    if (distance < 100) {
        scrollTo(0, stopY); return;
    }
    var speed = Math.round(distance / 100);
    if (speed >= 20) speed = 20;
    var step = Math.round(distance / 25);
    var leapY = stopY > startY ? startY + step : startY - step;
    var timer = 0;
    if (stopY > startY) {
        for ( var i=startY; i<stopY; i+=step ) {
            setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
            leapY += step; if (leapY > stopY) leapY = stopY; timer++;
        } return;
    }
    for ( var i=startY; i>stopY; i-=step ) {
        setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
        leapY -= step; if (leapY < stopY) leapY = stopY; timer++;
    }
    return false;
}

To call it you just do the following. You create a link which points to another element by using the id as a reference for a destination anchor.

要调用它,您只需执行以下操作即可。您可以使用id作为目标锚点的引用来创建指向另一个元素的链接。

<a href="#anchor-2" 
   onclick="smoothScroll('anchor-2');">smooth scroll to the headline with id anchor-2<a/>
...
...  some content
...
<h2 id="anchor-2">Anchor 2</h2>

Copyright

In the footer of itnewb.com the following is written: The techniques, effects and code demonstrated in ITNewb articles may be used for any purpose without attribution (although we recommend it) (2014-01-12)

在itnewb.com的页脚中写道如下:ITNewb文章中演示的技术,效果和代码可用于任何目的而不归因(尽管我们推荐)(2014-01-12)

#4


4  

I've been using this for a long time:

我已经使用了很长时间了:

function scrollToItem(item) {
    var diff=(item.offsetTop-window.scrollY)/8
    if (Math.abs(diff)>1) {
        window.scrollTo(0, (window.scrollY+diff))
        clearTimeout(window._TO)
        window._TO=setTimeout(scrollToItem, 30, item)
    } else {
        window.scrollTo(0, item.offsetTop)
    }
}

usage: scrollToItem(element) where element is document.getElementById('elementid') for example.

用法:scrollToItem(element),其中element是document.getElementById('elementid')。

#5


4  

Variation of @tominko answer. A little smoother animation and resolved problem with infinite invoked setTimeout(), when some elements can't allign to top of viewport.

@tominko答案的变化。当一些元素无法与视口顶部对齐时,使用无限调用的setTimeout()可以获得更平滑的动画和解决的问题。

function scrollToItem(item) {
    var diff=(item.offsetTop-window.scrollY)/20;
    if(!window._lastDiff){
        window._lastDiff = 0;
    }

    console.log('test')

    if (Math.abs(diff)>2) {
        window.scrollTo(0, (window.scrollY+diff))
        clearTimeout(window._TO)

        if(diff !== window._lastDiff){
            window._lastDiff = diff;
            window._TO=setTimeout(scrollToItem, 15, item);
        }
    } else {
        console.timeEnd('test');
        window.scrollTo(0, item.offsetTop)
    }
}

#6


2  

you can use this plugin. Does exactly what you want.

你可以使用这个插件。完全符合你的要求。

http://flesler.blogspot.com/2007/10/jqueryscrollto.html

http://flesler.blogspot.com/2007/10/jqueryscrollto.html

#7


0  

If one need to scroll to an element inside a div there is my solution based on Andrzej Sala's answer:

如果需要滚动到div中的元素,我的解决方案基于Andrzej Sala的答案:

function scroolTo(element, duration) {
    if (!duration) {
        duration = 700;
    }
    if (!element.offsetParent) {
        element.scrollTo();
    }
    var startingTop = element.offsetParent.scrollTop;
    var elementTop = element.offsetTop;
    var dist = elementTop - startingTop;
    var start;

    window.requestAnimationFrame(function step(timestamp) {
        if (!start)
            start = timestamp;
        var time = timestamp - start;
        var percent = Math.min(time / duration, 1);
        element.offsetParent.scrollTo(0, startingTop + dist * percent);

        // Proceed with animation as long as we wanted it to.
        if (time < duration) {
            window.requestAnimationFrame(step);
        }
    })
}

#8


-2  

Smooth scrolling with jQuery.ScrollTo

To use the jQuery ScrollTo plugin you have to do the following

要使用jQuery ScrollTo插件,您必须执行以下操作

  1. Create links where href points to another elements.id
  2. 创建href指向另一个elements.id的链接
  3. create the elements you want to scroll to
  4. 创建要滚动到的元素
  5. reference jQuery and the scrollTo Plugin
  6. 引用jQuery和scrollTo插件
  7. Make sure to add a click event handler for each link that should do smooth scrolling
  8. 确保为应该进行平滑滚动的每个链接添加一个单击事件处理程序

Creating the links

创建链接

<h1>Smooth Scrolling with the jQuery Plugin .scrollTo</h1>
<div id="nav-list">
  <a href="#idElement1">Scroll to element 1</a>
  <a href="#idElement2">Scroll to element 2</a>
  <a href="#idElement3">Scroll to element 3</a>
  <a href="#idElement4">Scroll to element 4</a>
</div>

Creating the target elements here only the first two are displayed the other headings are set up the same way. To see another example i added a link back to the navigation a.toNav

这里只创建前两个目标元素,其他标题的设置方式相同。为了看到另一个例子,我添加了一个回到导航a.toNav的链接

<h2 id="idElement1">Element1</h2>    
....
<h2 id="idElement1">Element1</h2>
... 
<a class="toNav" href="#nav-list">Scroll to Nav-List</a>

Setting the references to the scripts. Your path to the files may be different.

设置脚本的引用。您的文件路径可能不同。

<script src="./jquery-1.8.3.min.js"></script>
<script src="./jquery.scrollTo-1.4.3.1-min.js"></script>

Wiring it all up

The code below is borrowed from jQuery easing plugin

下面的代码是从jQuery缓动插件中借来的

jQuery(function ($) {
    $.easing.elasout = function (x, t, b, c, d) {
        var s = 1.70158;  var p = 0; var a = c;
        if (t == 0) return b;
        if ((t /= d) == 1) return b + c;
        if (!p) p = d * .3;
        if (a < Math.abs(c)) {
            a = c;   var s = p / 4;
        } else var s = p / (2 * Math.PI) * Math.asin(c / a);
        // line breaks added to avoid scroll bar
        return a * Math.pow(2, -10 * t)  * Math.sin((t * d - s) 
                 * (2 * Math.PI) / p) + c + b;
    };            

    // important reset all scrollable panes to (0,0)       
    $('div.pane').scrollTo(0); 
    $.scrollTo(0);    // Reset the screen to (0,0)
    // adding a click handler for each link 
    // within the div with the id nav-list
    $('#nav-list a').click(function () {             
        $.scrollTo(this.hash, 1500, {
            easing: 'elasout'
        });
        return false;
    });   
    // adding a click handler for the link at the bottom
    $('a.toNav').click(function () { 
        var scrollTargetId = this.hash;
        $.scrollTo(scrollTargetId, 1500, {
            easing: 'elasout'
        });
        return false;
    });    
});

Fully working demo on plnkr.co

You may take a look at the soucre code for the demo.

您可以查看演示的soucre代码。

Update May 2014

Based on another question i came across another solution from kadaj. Here jQuery animate is used to scroll to an element inside a <div style=overflow-y: scroll>

基于另一个问题,我遇到了kadaj的另一个解决方案。这里jQuery animate用于滚动到

中的元素

 $(document).ready(function () {
    $('.navSection').on('click', function (e) {
        debugger;
        var elemId = "";    //eg: #nav2
        switch (e.target.id) {
        case "nav1":
            elemId = "#s1";
            break;
        case "nav2":
            elemId = "#s2";
            break;
        case "nav3":
            elemId = "#s3";
            break;
        case "nav4":
            elemId = "#s4";
            break;
        }
        $('.content').animate({
            scrollTop: $(elemId).parent().scrollTop() 
                    + $(elemId).offset().top 
                    - $(elemId).parent().offset().top
        }, {
            duration: 1000,
            specialEasing: { width: 'linear'
                    , height: 'easeOutBounce' },
            complete: function (e) {
                //console.log("animation completed");
            }
        });
        e.preventDefault();
    });
  });