加载新页面后平滑滚动到锚点

30

我想在新页面上导航到锚点,但我希望页面在顶部加载后立即平滑滚动到相关的锚点。这可以做到吗?

我完全不懂Javascript。

这是我目前用于当前页面内平滑滚动的js代码。 我只需在链接上应用“scroll”类即可。

非常感谢!

<script>
$(function(){
  $('.scroll').on('click',function(e) {
    e.preventDefault();
    $('html, body').animate({ scrollTop: $($(this).attr('href')).offset().top + 'px' }, 1000, 'swing');
  });
});
</script>
2个回答

58

因为浏览器会自动检测hash并将你带到该位置...我想到了一个方法,你可以先把滚动位置重置为0,然后再进行平滑滚动。

就像这样...

// to top right away
if ( window.location.hash ) scroll(0,0);
// void some browsers issue
setTimeout( function() { scroll(0,0); }, 1);

$(function() {

    // your current click function
    $('.scroll').on('click', function(e) {
        e.preventDefault();
        $('html, body').animate({
            scrollTop: $($(this).attr('href')).offset().top + 'px'
        }, 1000, 'swing');
    });

    // *only* if we have anchor on the url
    if(window.location.hash) {

        // smooth scroll to the anchor id
        $('html, body').animate({
            scrollTop: $(window.location.hash).offset().top + 'px'
        }, 1000, 'swing');
    }

});

编辑:将scroll(0,0)移到$(function(){...});之外,以防止闪烁。
此外,添加了一个具有工作示例的片段。
在全屏模式下查看效果最佳

        html, body {
            margin: 0;
            padding: 0;
        }
        .hidden-code {
            display: none;
            visibility: hidden;
            opacity: 0;
        }
        .header {
            background-color: #ccc;
            padding: 5px;
        }
        .header li {
            padding: 5px;
            margin: 5px;
            display: inline-block;
        }
        .articles > div {
            border: 1px solid;
            margin: 10px;
            padding: 250px 50px;
            background-color: #ccc;
        }
        div:before {
            content: attr(id);
        }
        .footer {
            text-align: center;
        }
    <div class="header">
        <ul>
            <li>page header title/navbar</li>
            <li><a class="scroll" href="#text-1">#text-1</a></li>
            <li><a class="scroll" href="#text-2">#text-2</a></li>
            <li><a class="scroll" href="#text-3">#text-3</a></li>
            <li><a class="scroll" href="#text-4">#text-4</a></li>
            <li><a class="scroll" href="#text-5">#text-5</a></li>
            <li><a class="scroll" href="#text-6">#text-6</a></li>
            <li><a class="scroll" href="#text-7">#text-7</a></li>
            <li><a class="scroll" href="#text-8">#text-8</a></li>
        </ul>
    </div>

    <div class="container">

        <div class="content">

            <div class="articles">
                <div id="text-1"></div>
                <div id="text-2"></div>
                <div id="text-3"></div>
                <div id="text-4"></div>
                <div id="text-5"></div>
                <div id="text-6"></div>
                <div id="text-7"></div>
                <div id="text-8"></div>
            </div>

        </div>

        <div class="footer">company &copy; 2015</div>

    </div>

    <div class="hidden-code">

        <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
        <script type="text/javascript">

            // to top right away
            if ( window.location.hash ) scroll(0,0);
            // void some browsers issue
            setTimeout( function() { scroll(0,0); }, 1);

            // any position
            $(function() {
                // your current click function
                $('.scroll').on('click', function(e) {
                    e.preventDefault();
                    $('html, body').animate({
                        scrollTop: $($(this).attr('href')).offset().top + 'px'
                    }, 1000, 'swing');
                });
                // *only* if we have anchor on the url
                if(window.location.hash) {
                    // smooth scroll to the anchor id
                    $('html, body').animate({
                        scrollTop: $(window.location.hash).offset().top + 'px'
                    }, 1000, 'swing');
                }
            });
        </script>

    </div>


嘿!非常抱歉 - 我一直不在。这个完美地运作了。 之前的测试是在OSX Yosemite本地进行的,跨多个浏览器进行测试(Safari,Firefox,Opera和Chrome)。再次感谢! - Mr Toad
1
@gmo 你能否解释一下,当存在锚点时,为什么要执行两次scroll(0,0)?并且在检查哈希值时,为什么不考虑已超时的那个? - Cu7l4ss
1
@gmo 在我删除了你代码的前4行之后,它终于起作用了。谢谢! - Luzan Baral
非常好!当您删除前4行时,它是适用于具有大量隐藏内容的单页网站的好解决方案。 - herrfischer
1
@JaySmoke 当然,只需将您想要的任何像素总和添加到scrollTop函数中,例如150 -> ...offset().top + 150 + 'px' - gmo
显示剩余11条评论

0

这里有一种更现代的方法,看起来非常有效。这必须放在任何document.ready或window.onLoad处理程序之外。

// Handle page load
if ( window.location.hash ) {
    var target = window.location.hash.slice( 1 );
    if ( document.getElementById( target ) ) {
        $( function() {
            if ( window.location.hash ) {
                if ( $( '#' + target ).length ) {
                    window.scrollTo( 0, 0 );
                    $( 'html, body' ).animate( {
                        scrollTop: $( '#' + target ).offset().top - 50
                    }, 800 );
                }
            }
        } );
        if ( 'scrollRestoration' in history ) {
            history.scrollRestoration = 'manual';
        }
        window.scrollTo( 0, 0 );
    }
}

// Handle anchor links
$( function() {
    $( 'a[href^="#"]' ).on( 'click', function( e ) {
        e.preventDefault();
        $( 'html, body' ).animate( {
            scrollTop: $( $.attr( this, 'href' ) ).offset().top - 80
        }, 800 );
        return false;
    } );
} );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接