เลื่อนไปยังองค์ประกอบเฉพาะบนหน้าได้อย่างราบรื่น

ฉันอยากมีปุ่ม/ลิงก์ 4 ปุ่มที่จุดเริ่มต้นของหน้า และใต้เนื้อหา

บนปุ่มฉันใส่รหัสนี้:

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

และใต้ลิงค์จะมีเนื้อหา:

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

ขณะนี้ใช้งานได้แล้ว แต่ไม่สามารถทำให้ดูราบรื่นยิ่งขึ้นได้

ฉันใช้รหัสนี้ แต่ไม่สามารถใช้งานได้

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

มีข้อเสนอแนะอะไรบ้าง? ขอบคุณ

แก้ไข: และซอ: http://jsfiddle.net/WxJLx/2/


person M P    schedule 18.07.2013    source แหล่งที่มา
comment
เป็นไปได้ที่ซ้ำกันของ Smooth JavaScript/jQuery เลื่อนไปที่องค์ประกอบ   -  person MDEV    schedule 18.07.2013
comment
ฉันต้องถาม คุณใช้โค้ดภาพเคลื่อนไหวภายในเหตุการณ์การคลิกหรือไม่   -  person Or Duan    schedule 18.07.2013
comment
ฉันกลัวว่าฉันไม่รู้ว่าคุณกำลังถามอะไรฉัน   -  person M P    schedule 18.07.2013
comment
$('#idElement1').onclick=function(){/*นี่คือโค้ด smothscroll ของคุณ*/}   -  person dbanet    schedule 18.07.2013
comment
นอกจากนี้อย่าลืมคืนค่าเท็จเพื่อปิดการใช้งานการเลื่อนแบบเนทิฟ   -  person dbanet    schedule 18.07.2013
comment
คุณช่วยแสดงซอนั้นให้ฉันดูได้ไหม: jsfiddle.net/WxJLx/2   -  person M P    schedule 18.07.2013
comment
ฉันไม่ชัดเจนสำหรับฉันหากคุณต้องการค้นหาวิธีแก้ปัญหาสำหรับการเลื่อนอย่างราบรื่นหรือหากคุณต้องการทราบและเข้าใจว่าทำไมโค้ดของคุณถึงใช้งานไม่ได้   -  person surfmuggle    schedule 20.07.2013


คำตอบ (12)


เพิ่งสร้างจาวาสคริปต์นี้วิธีแก้ปัญหาด้านล่างเท่านั้น

การใช้งานที่เรียบง่าย:

EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);

วัตถุเครื่องยนต์ (คุณสามารถเล่นซอกับตัวกรองค่า 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);
    }
};
person Geri Borbás    schedule 18.12.2013

ราบรื่นสุดๆ ด้วย requestAnimationFrame

สำหรับภาพเคลื่อนไหวการเลื่อนที่แสดงผลได้อย่างราบรื่น เราสามารถใช้ window.requestAnimationFrame() ซึ่ง ทำงานได้ดีกว่าในการเรนเดอร์มากกว่าโซลูชัน setTimeout() ปกติ

ตัวอย่างพื้นฐานมีลักษณะเช่นนี้ ฟังก์ชัน step ถูกเรียกใช้สำหรับทุกเฟรมภาพเคลื่อนไหวของเบราว์เซอร์ และช่วยให้สามารถจัดการเวลาในการทาสีใหม่ได้ดีขึ้น และเพิ่มประสิทธิภาพการทำงานด้วย

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);
    }
  })
}

สำหรับฟังก์ชันการใช้ตำแหน่ง Y ขององค์ประกอบในคำตอบอื่นหรืออันที่อยู่ในซอที่กล่าวถึงด้านล่าง

ฉันตั้งค่าฟังก์ชันที่ซับซ้อนขึ้นอีกเล็กน้อยด้วยการรองรับการค่อยๆ เปลี่ยนและการเลื่อนไปยังองค์ประกอบที่อยู่ด้านล่างสุดอย่างเหมาะสม: https://jsfiddle.net/s61x7c4e/

person Daniel Sawka    schedule 14.09.2016
comment
แค่สร้างห้องสมุดเล็กๆ ตามแหล่งที่มาของคุณ โดยลิงก์ที่นี่ในเครดิต ขอบคุณ! - person Dev_NIX; 14.12.2016
comment
@Dev_NIX ดีใจที่สามารถช่วยได้! เมื่อฉันใช้ไลบรารี sweet-scroll แต่อย่างใดก็เล่นได้ไม่ดีกับ React คุณสามารถใช้ API หรือโค้ดบางส่วนจากสิ่งนั้นซ้ำได้ - person Daniel Sawka; 15.12.2016
comment
นี่มันป่วยชัดๆ ขอบคุณ! - person BrandonReid; 25.01.2017
comment
ขอบคุณ คุณเก่งที่สุด! :) - person Naskalin; 03.05.2021

คำถามถูกถามเมื่อ 5 ปีที่แล้ว และฉันกำลังติดต่อกับ smooth scroll และรู้สึกว่าการให้วิธีแก้ปัญหาง่ายๆ นั้นคุ้มค่าสำหรับผู้ที่กำลังมองหา คำตอบทั้งหมดนั้นดี แต่นี่คือคำตอบง่ายๆ

function smoothScroll(){
    document.querySelector('.your_class or #id here').scrollIntoView({
        behavior: 'smooth'
    });
}

เพียงเรียกใช้ฟังก์ชัน smoothScroll ในเหตุการณ์ onClick บนแหล่งที่มาของคุณ element

เอกสาร: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

หมายเหตุ: โปรดตรวจสอบความเข้ากันได้ที่นี่

การแก้ไขโดยบุคคลที่สาม

การสนับสนุนสำหรับ Element.scrollIntoView() ในปี 2020 คือ:

Region            full   + partial = sum full+partial Support
Asia              73.24% + 22.75%  = 95.98%
North America     56.15% + 42.09%  = 98.25%
India             71.01% + 20.13%  = 91.14%
Europe            68.58% + 27.76%  = 96.35%

รองรับ scrollintoview 2020-02-28

person Sanjay Shr    schedule 13.08.2018
comment
scrollIntoView ด้วย 'ราบรื่น' ไม่รองรับ IE, EDGE และ Safari (28/09/2018) - person Karedia Noorsil; 28.09.2018
comment
@KarediaNoorsil ขอบคุณสำหรับการรายงาน อัปเดตคำตอบของฉัน - person Sanjay Shr; 29.09.2018
comment
คำตอบที่ดีที่สุดในปี 2020 - person n8jadams; 20.02.2020
comment
เพื่อน ฉันจะขอบคุณยังไงล่ะ? - person Beki; 10.06.2021

การเลื่อนอย่างราบรื่น - ดูสิไม่ใช่ jQuery

จาก บทความใน itnewb.com ฉันได้จัดทำ สาธิตเสียงพลังค์เพื่อให้เลื่อนได้อย่างราบรื่นโดยไม่ต้องใช้ไลบรารีภายนอก

จาวาสคริปต์ค่อนข้างง่าย ขั้นแรกเป็นฟังก์ชันตัวช่วยเพื่อปรับปรุงการรองรับข้ามเบราว์เซอร์เพื่อกำหนดตำแหน่งปัจจุบัน

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;
}

จากนั้นเป็นฟังก์ชันเพื่อกำหนดตำแหน่งขององค์ประกอบปลายทางซึ่งเป็นตำแหน่งที่เราต้องการเลื่อนไป

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;
}

และฟังก์ชั่นหลักในการทำการเลื่อน

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;
}

หากต้องการเรียกมันคุณเพียงแค่ทำดังต่อไปนี้ คุณสร้างลิงก์ที่ชี้ไปยังองค์ประกอบอื่นโดยใช้รหัสเป็นข้อมูลอ้างอิงสำหรับ จุดยึดปลายทาง

<a href="/th#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>

ลิขสิทธิ์

ในส่วนท้ายของ itnewb.com มีข้อความต่อไปนี้: The techniques, effects and code demonstrated in ITNewb articles may be used for any purpose without attribution (although we recommend it) (2014-01-12)

person surfmuggle    schedule 18.07.2013
comment
ขอบคุณ ฉันช่วยฉันได้สักพัก :) ฉันยังเพิ่มใน smoothScroll({eID, padding = 0}) และ stopY += padding; หลัง let stopY = elmYPosition(eID); เพื่อให้มีช่องว่างรอบองค์ประกอบและไม่ต้องเลื่อนไปยังองค์ประกอบที่แน่นอน - person Lukas Liesis; 14.04.2016
comment
กำลังดำเนินการสตริงเป็นฟังก์ชัน.... :( ทำไมไม่เพียงแค่: setTimeout(window.scrollTo.bind(null, 0, leapY), timer * speed); - person monners; 01.09.2016

คุณสามารถตรวจสอบบล็อกที่ยอดเยี่ยมนี้ได้ - ด้วยวิธีง่ายๆ บางอย่างในการบรรลุเป้าหมายนี้ :)

https://css-tricks.com/snippets/jquery/smooth-scrolling/

ชอบ (จากบล็อก)

// Scroll to specific values
// scrollTo is the same
window.scroll({
  top: 2500, 
  left: 0, 
  behavior: 'smooth'
});

// Scroll certain amounts from current position 
window.scrollBy({ 
  top: 100, // could be negative value
  left: 0, 
  behavior: 'smooth' 
});

// Scroll to a certain element
document.querySelector('.hello').scrollIntoView({ 
  behavior: 'smooth' 
});

และคุณยังสามารถรับตำแหน่งองค์ประกอบ "บนสุด" ได้เช่นด้านล่าง (หรือวิธีอื่น)

var e = document.getElementById(element);
var top = 0;

do {   
    top += e.offsetTop;
} while (e = e.offsetParent);

return top;
person aniltilanthe    schedule 16.05.2019

ฉันใช้สิ่งนี้มาเป็นเวลานาน:

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)
    }
}

การใช้งาน: scrollToItem(element) โดยที่ element คือ document.getElementById('elementid') เป็นต้น

person Community    schedule 05.07.2016
comment
สิ่งนี้ใช้ได้ผลดีสำหรับฉัน ฉันแค่คิดว่ามันจะดีกว่าถ้ามีอัฒภาค! - person Vahid Amiri; 23.09.2016
comment
แค่ต้องการเพิ่ม - เป้าหมายของฉันคือไม่ใช้ไลบรารีภายนอกใด ๆ มันไม่มีประโยชน์ที่จะโหลด jquery ขนาดใหญ่สำหรับการเลื่อนหน้า ;-) - person ; 04.01.2017
comment
เฮ้ขอบคุณสำหรับการแก้ปัญหา :) คุณช่วยบอกฉันหน่อยได้ไหมว่าตัวแปร window._TO ใช้ทำอะไร ฉันไม่สามารถเข้าใจได้ว่ามันทำอะไรและทำไมเราถึงใช้ clearTimeout ฉันได้ลบ clearTimeout แล้วและมันทำงานได้ดีสำหรับฉันอย่างสมบูรณ์ - person Subham Tripathi; 10.02.2017
comment
@Subham Tripathi ถ้าคุณเรียกใช้ฟังก์ชันอีกครั้งก่อนที่มันจะเสร็จสิ้น มันจะทำงานได้ไม่ดีนัก - เพราะมันจะเคลื่อนที่ไปยังจุดแรกต่อไป และหากการโทรครั้งที่สองต้องการย้ายไปยังจุดอื่น มันจะอยู่ตรงนั้นและย้อนกลับ - ตลอดไป - person ; 10.02.2017

รูปแบบของคำตอบ @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)
    }
}
person Andrzej Sala    schedule 06.11.2016

ทำไมไม่ใช้คุณสมบัติ scroll-behavior ของ CSS

html {
  scroll-behavior: smooth;
}

การรองรับเบราว์เซอร์ก็ดีเช่นกัน https://caniuse.com/#feat=css-scroll-behavior

person esnezz    schedule 09.05.2020
comment
ใช้งานไม่ได้บน Safari :-( - person randomcontrol; 11.04.2021

คุณสามารถใช้ปลั๊กอินนี้ได้ ทำสิ่งที่คุณต้องการอย่างแน่นอน

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

person Feedthe    schedule 18.07.2013
comment
ดังนั้นฉันจะต้องเขียนโค้ดเช่นนี้: $('#id1').localScroll({ target:'#content1' }); - person M P; 18.07.2013
comment
และจะต้องนำเข้า jQuery lib ทั้งหมดเพื่อเลื่อน ทำได้ดีกว่ากับ vanila js เหมือนคำตอบอื่น ๆ - person Lukas Liesis; 14.04.2016

คุณสามารถใช้ for loop กับ window.scrollTo และ setTimeout เพื่อเลื่อนได้อย่างราบรื่นด้วย Javascript ธรรมดา หากต้องการเลื่อนไปยังองค์ประกอบด้วยฟังก์ชัน scrollToSmoothly ของฉัน: scrollToSmoothly(elem.offsetTop) (สมมติว่า elem เป็นองค์ประกอบ DOM)

function scrollToSmoothly(pos, time){
/*Time is only applicable for scrolling upwards*/
/*Code written by hev1*/
/*pos is the y-position to scroll to (in pixels)*/
     if(isNaN(pos)){
      throw "Position must be a number";
     }
     if(pos<0){
     throw "Position can not be negative";
     }
    var currentPos = window.scrollY||window.screenTop;
    if(currentPos<pos){
    var t = 10;
       for(let i = currentPos; i <= pos; i+=10){
       t+=10;
        setTimeout(function(){
        window.scrollTo(0, i);
        }, t/2);
      }
    } else {
    time = time || 2;
       var i = currentPos;
       var x;
      x = setInterval(function(){
         window.scrollTo(0, i);
         i -= 10;
         if(i<=pos){
          clearInterval(x);
         }
     }, time);
      }
}

หากคุณต้องการเลื่อนไปที่องค์ประกอบด้วย id คุณสามารถเพิ่มฟังก์ชันนี้ (พร้อมกับฟังก์ชันด้านบน):

function scrollSmoothlyToElementById(id){
   var elem = document.getElementById(id);
   scrollToSmoothly(elem.offsetTop);
}

การสาธิต:

<button onClick="scrollToDiv()">Scroll To Element</button>
<div style="margin: 1000px 0px; text-align: center;">Div element<p/>
<button onClick="scrollToSmoothly(Number(0))">Scroll back to top</button>
</div>
<script>
function scrollToSmoothly(pos, time){
/*Time is only applicable for scrolling upwards*/
/*Code written by hev1*/
/*pos is the y-position to scroll to (in pixels)*/
     if(isNaN(pos)){
      throw "Position must be a number";
     }
     if(pos<0){
     throw "Position can not be negative";
     }
    var currentPos = window.scrollY||window.screenTop;
    if(currentPos<pos){
    var t = 10;
       for(let i = currentPos; i <= pos; i+=10){
       t+=10;
        setTimeout(function(){
      	window.scrollTo(0, i);
        }, t/2);
      }
    } else {
    time = time || 2;
       var i = currentPos;
       var x;
      x = setInterval(function(){
         window.scrollTo(0, i);
         i -= 10;
         if(i<=pos){
          clearInterval(x);
         }
     }, time);
      }
}
function scrollToDiv(){
  var elem = document.querySelector("div");
  scrollToSmoothly(elem.offsetTop);
}
</script>

person Unmitigated    schedule 04.08.2018

หากจำเป็นต้องเลื่อนไปที่องค์ประกอบภายใน 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);
        }
    })
}
person Kuba Szostak    schedule 25.06.2018

เลื่อนได้อย่างราบรื่นด้วย jQuery.ScrollTo

หากต้องการใช้ปลั๊กอิน jQuery ScrollTo คุณต้องทำดังต่อไปนี้

  1. สร้างลิงก์โดยที่ href ชี้ไปยัง element.id อื่น
  2. สร้างองค์ประกอบที่คุณต้องการเลื่อนไป
  3. อ้างอิง jQuery และปลั๊กอิน scrollTo
  4. ตรวจสอบให้แน่ใจว่าได้เพิ่มตัวจัดการเหตุการณ์การคลิกสำหรับแต่ละลิงก์ที่ควรเลื่อนได้อย่างราบรื่น

การสร้างลิงค์

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

การสร้างองค์ประกอบเป้าหมายที่นี่จะแสดงเฉพาะสองรายการแรก ส่วนหัวข้ออื่นๆ ได้รับการตั้งค่าในลักษณะเดียวกัน หากต้องการดูตัวอย่างอื่น ฉันได้เพิ่มลิงก์กลับไปยังการนำทาง a.toNav

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

การตั้งค่าการอ้างอิงไปยังสคริปต์ เส้นทางไปยังไฟล์ของคุณอาจแตกต่างกัน

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

เดินสายไฟทั้งหมด

โค้ดด้านล่างยืมมาจาก ปลั๊กอิน jQuery easing

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;
    });    
});

การสาธิตการทำงานโดยสมบูรณ์บน plnkr.co

คุณสามารถดูโค้ด soucre สำหรับการสาธิต

อัปเดตเดือนพฤษภาคม 2014

จากคำถามอื่น ฉันพบวิธีแก้ปัญหาอื่นจาก คาดาจ. ที่นี่ jQuery animate ใช้เพื่อเลื่อนไปยังองค์ประกอบภายใน <div style=overflow-y: scroll>

 $(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();
    });
  });
person surfmuggle    schedule 19.07.2013
comment
ในระหว่างนี้ ฉันทำซอนี้: jsfiddle.net/WxJLx/15.. มันใช้งานได้ อยู่ในซอ แต่ไม่ใช่บนเวิร์ดเพรส คุณสามารถตรวจสอบซอร์สโค้ดนี้ได้หรือไม่ หากคุณพบปัญหาใดๆ ขอขอบคุณ: view-source:anchovyluxury.com/yachts/services - person M P; 19.07.2013
comment
คุณพยายามค้นหาข้อผิดพลาดอะไร คุณคุ้นเคยกับเครื่องมือ Chrome dev ไหม เพราะทำให้ตรวจพบข้อผิดพลาดได้ง่ายมาก: $('a[href^="#"]').click(function(){ ในบรรทัด 360 ของ anchovyluxury com/yachts/services คุณมีคำถามเพิ่มเติมเกี่ยวกับวิธีการเลื่อนอย่างราบรื่นหรือไม่? - person surfmuggle; 19.07.2013
comment
ฉันพยายามใส่โค้ดนั้นซึ่งหน้าต่างป๊อปอัปที่ jquery ใช้งานได้ และรหัสของฉันกำลังเล่นซออยู่ เลยไม่รู้ว่าปัญหาอยู่ที่ไหน - person M P; 20.07.2013