การเลื่อนที่ราบรื่นเมื่อคลิกที่ลิงค์ยึด


487

ฉันมีการเชื่อมโยงหลายมิติบนหน้าของฉัน คำถามที่พบบ่อยที่ผู้ใช้จะอ่านเมื่อเข้าสู่ส่วนช่วยเหลือของฉัน

ใช้ลิงค์ Anchor ฉันสามารถเลื่อนหน้าไปทางจุดยึดและแนะนำผู้ใช้ที่นั่น

มีวิธีทำให้การเลื่อนนั้นราบรื่นหรือไม่?

แต่โปรดสังเกตว่าเขาใช้ไลบรารี JavaScript ที่กำหนดเอง บางที jQuery มีข้อเสนอบางอย่างเช่นนี้อบใน?


คุณช่วยทบทวนคำตอบที่ดีที่สุดได้ไหม? โซลูชัน css แบบบรรทัดเดียวหายากในบรรดาคำแนะนำ jquery ที่ยิ่งใหญ่ทั้งหมด: stackoverflow.com/a/51588820/1422553
АлександрКиричек

คำตอบ:


1159

อัปเดตเมษายน 2018:ตอนนี้มีวิธีการทำเช่นนี้แล้ว :

document.querySelectorAll('a[href^="#"]').forEach(anchor => {
    anchor.addEventListener('click', function (e) {
        e.preventDefault();

        document.querySelector(this.getAttribute('href')).scrollIntoView({
            behavior: 'smooth'
        });
    });
});

ปัจจุบันนี้รองรับเฉพาะเบราว์เซอร์ Edge ที่มีเลือดออกมากที่สุด


สำหรับการรองรับเบราว์เซอร์รุ่นเก่าคุณสามารถใช้เทคนิค jQuery นี้:

$(document).on('click', 'a[href^="#"]', function (event) {
    event.preventDefault();

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top
    }, 500);
});

และนี่คือซอ: http://jsfiddle.net/9SDLw/


หากองค์ประกอบเป้าหมายของคุณไม่มี ID และคุณกำลังเชื่อมโยงไปยังองค์ประกอบนั้นnameให้ใช้สิ่งนี้:

$('a[href^="#"]').click(function () {
    $('html, body').animate({
        scrollTop: $('[name="' + $.attr(this, 'href').substr(1) + '"]').offset().top
    }, 500);

    return false;
});

เพื่อประสิทธิภาพที่เพิ่มขึ้นคุณควรแคช$('html, body')ตัวเลือกนั้นเพื่อไม่ให้ทำงานทุกครั้งที่มีการคลิกจุดยึด:

var $root = $('html, body');

$('a[href^="#"]').click(function () {
    $root.animate({
        scrollTop: $( $.attr(this, 'href') ).offset().top
    }, 500);

    return false;
});

หากคุณต้องการให้ URL อัปเดตให้ทำภายในการanimateเรียกกลับ:

var $root = $('html, body');

$('a[href^="#"]').click(function() {
    var href = $.attr(this, 'href');

    $root.animate({
        scrollTop: $(href).offset().top
    }, 500, function () {
        window.location.hash = href;
    });

    return false;
});

10
ดูเหมือนว่าจะลบ #extension ออกจาก URL โดยทำลายฟังก์ชัน back มีวิธีแก้ไขไหม?
Fletch

2
@JosephSilber ไม่ควรที่จะscrollTop: $(this.hash).offset().topแทนscrollTop: $(this.href).offset().top?
Gregory Pakosz

4
@CreateSean -scrollTop: $(href).offset().top - 72
Joseph Silber

5
ฉันขอยืนยันว่าการแคชhtml, bodyวัตถุที่นี่ไม่จำเป็นการเรียกใช้ตัวเลือกหนึ่งครั้งต่อคลิกนั้นไม่มากนัก

2
วิธีแก้ปัญหาแรกนั้นดีที่สุดและทันสมัยที่สุดคุณสามารถใช้ polyfill นี้เพื่อสนับสนุนพฤติกรรมนี้บนเบราว์เซอร์เก่าด้วยโปลิฟิล
Efe

166

ไวยากรณ์ที่ถูกต้องคือ:

//Smooth scrolling with links
$('a[href*=\\#]').on('click', function(event){     
    event.preventDefault();
    $('html,body').animate({scrollTop:$(this.hash).offset().top}, 500);
});

// Smooth scrolling when the document is loaded and ready
$(document).ready(function(){
  $('html,body').animate({scrollTop:$(location.hash).offset().‌​top}, 500);
});

ลดความซับซ้อน : DRY

function smoothScrollingTo(target){
  $('html,body').animate({scrollTop:$(target).offset().​top}, 500);
}
$('a[href*=\\#]').on('click', function(event){     
    event.preventDefault();
    smoothScrollingTo(this.hash);
});
$(document).ready(function(){
  smoothScrollingTo(location.hash);
});

คำอธิบายของhref*=\\#:

  • *หมายความว่าตรงกับสิ่งที่มี#ถ่าน ดังนั้นเพียงตรงกับเบรก สำหรับข้อมูลเพิ่มเติมเกี่ยวกับความหมายของสิ่งนี้ดูที่นี่
  • \\เป็นเพราะตัว#ละครพิเศษใน css selector ดังนั้นเราต้องหนีมันออกไป

8
ฉันต้องเปลี่ยน$('a')เป็นการ$('a[href*=#]')รับใช้สมอเท่านั้น
okliv

2
@okliv <a href="javascript:$('#test').css('background-color', '#000')">Test</a>นี้จะทำหน้าที่มากเกินไปเช่นการเชื่อมโยงเช่นจาวาสคริปต์ คุณควรใช้$('a[href^=#]')เพื่อจับคู่ URL ทั้งหมดที่ขึ้นต้นด้วยอักขระแฮช
Martin Braun

3
ด้วย '#' เป็นตัวละครพิเศษและจะต้องมีการหลบหนีเช่นนี้:a[href^=\\#]
QuinnFreedman

3
สิ่งนี้ทำให้ลิงก์ไปยังแองเคอร์ในหน้าอื่น ๆ หยุดทำงาน แก้ไขได้โดยการเพิ่มเงื่อนไขถ้า ($ ($ (this.hash) .selector). ยาว) {... การเลื่อนแบบราบรื่น }
Liren

1
ฉันจะสร้างภาพเคลื่อนไหวนี้ได้อย่างไรเมื่อเดินทางไปที่หน้าใหม่เป็นครั้งแรก ตัวอย่างเช่นโดยการคลิก: เว็บไซต์.com/newpage/#section2 ฉันต้องการให้โหลดหน้าเว็บแล้วเลื่อนลง เป็นไปได้ไหม
Samyer

72

ใหม่ล่าสุดใน CSS3 นี่เป็นวิธีที่ง่ายกว่าทุกวิธีที่แสดงไว้ในหน้านี้และไม่ต้องใช้ Javascript เพียงแค่ใส่โค้ดด้านล่างลงใน css ของคุณและลิงค์ที่ฉับพลันทั้งหมดชี้ไปยังสถานที่ในหน้าของคุณจะมีภาพเคลื่อนไหวที่เลื่อนได้อย่างราบรื่น

html{scroll-behavior:smooth}

หลังจากนั้นลิงก์ใด ๆ ที่ชี้ไปยัง div จะราบรื่นไปยังส่วนเหล่านั้น

<a href="#section">Section1</a>

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

<div classname="section">content</div>

ในเรื่องนี้ลิงก์จะสามารถคลิกได้และจะไปยัง #section ส่วนใดในกรณีนี้คือ div ของเราที่เราเรียกว่าส่วน

BTW ฉันใช้เวลาหลายชั่วโมงเพื่อให้มันทำงาน พบวิธีแก้ปัญหาในส่วนความคิดเห็นที่คลุมเครือ มันเป็นรถและจะไม่ทำงานในบางแท็ก ไม่ได้ทำงานในร่างกาย ในที่สุดก็ใช้งานได้เมื่อฉันวางไว้ใน html {} ในไฟล์ CSS


4
ฉันสามารถเป็นประโยชน์ได้มาก แต่ก็เป็นข้อเสีย
บูซูต

3
ดี แต่ต้องระวังเพราะในขณะนี้ Safari ยังไม่รองรับและเห็นได้ชัดจาก Explorer (03/2019)
Marco Romano

2
วิธีแก้ปัญหาที่ดีมีเพียง 74,8% ที่ จำกัด เท่านั้น อาจจะในอนาคต
iepur1lla

1
น่าทึ่งมาก ขอบคุณมาก.
Mikkel Fennefoss

1
นี่จะเป็นคำตอบที่เกี่ยวข้องมากที่สุดในปีต่อ ๆ ไป
Nurul Huda

22
$('a[href*=#]').click(function(event){
    $('html, body').animate({
        scrollTop: $( $.attr(this, 'href') ).offset().top
    }, 500);
    event.preventDefault();
});

มันทำงานได้สมบูรณ์แบบสำหรับฉัน


1
"event.preventDefault ();" สามารถแทนที่ "return false;"
Andres แยกกัน

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

18

ฉันประหลาดใจที่ไม่มีใครโพสต์โซลูชันดั้งเดิมที่ดูแลการอัปเดตแฮชตำแหน่งเบราว์เซอร์ให้ตรงกัน นี่มันคือ:

let anchorlinks = document.querySelectorAll('a[href^="#"]')
 
for (let item of anchorlinks) { // relitere 
    item.addEventListener('click', (e)=> {
        let hashval = item.getAttribute('href')
        let target = document.querySelector(hashval)
        target.scrollIntoView({
            behavior: 'smooth',
            block: 'start'
        })
        history.pushState(null, null, hashval)
        e.preventDefault()
    })
}

ดูบทช่วยสอน: http://www.javascriptkit.com/javatutors/scrolling-html-bookmark-javascript.shtml

สำหรับไซต์ที่มีส่วนหัวที่เหนียวscroll-padding-topสามารถใช้ CSS เพื่อจัดทำออฟเซ็ต


1
ฉันชอบคำตอบนี้มากที่สุด อย่างไรก็ตามคนไทยไม่มีทางชดเชยได้ ตามที่ต้องการในกรณีที่เป็นหัวข้อคงที่
bskool

ไม่ได้รับการสนับสนุนที่ไม่ดีเช่นเดียวกับคุณสมบัติเลื่อนพฤติกรรม CSS: developer.mozilla.org/en-US/docs/Web/CSS/…
Dmitry Nevzorov

15

CSS เท่านั้น

html {
    scroll-behavior: smooth !important;
}

สิ่งที่คุณต้องเพิ่มเท่านั้น ตอนนี้พฤติกรรมการเลื่อนลิงก์ภายในของคุณจะราบรื่นเหมือนการสตรีม

หมายเหตุ : เบราว์เซอร์ล่าสุด ( Opera, ChromeและFirefoxอื่น ๆ ) รองรับคุณสมบัตินี้

เพื่อความเข้าใจอย่างละเอียดอ่านบทความนี้


1
ดี! ทำไมนี่ไม่ใช่คำตอบที่ยอมรับ? เราไม่ต้องการจาวาสคริปต์ทั้งหมด!
Trevor de Koekkoek

1
มันใช้งานได้ดีนี่ควรเป็นคำตอบที่ได้รับการยอมรับ
หลุมฝังศพ

ตรวจสอบการสนับสนุนเบราว์เซอร์ที่นี่
Ryan Zhou

1
มันทำงานเหมือนจับใจ ไม่ต้องการ js
Navbro

นี่เป็นทางออกที่ดีที่สุดสำหรับการเลื่อนที่ราบรื่น! ขอบคุณ!
yehanny

10

ฉันแนะนำให้คุณสร้างรหัสทั่วไปนี้:

$('a[href^="#"]').click(function(){

var the_id = $(this).attr("href");

    $('html, body').animate({
        scrollTop:$(the_id).offset().top
    }, 'slow');

return false;});

คุณสามารถดูบทความที่ดีมากที่นี่: jquery-effet-smooth-scroll-defilement-fluide


9
นี่ไม่ใช่เรื่องทั่วไปนี่คือ jQuery
AnrDaemon

6
$(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top
        }, 1000);
        return false;
      }
    }
  });
});

เป็นทางการ: http://css-tricks.com/snippets/jquery/smooth-scrolling/


1
ดูเหมือนว่าจะใช้งานได้เฉพาะกับลิงก์จุดยึดหน้าภายใน แต่ลิงก์ยึดจากหน้าอื่น ๆ ใช้งานไม่ได้ตัวอย่างเช่นเว็บไซต์
com/about

5

มีคำตอบที่ดีอยู่แล้วจำนวนมากที่นี่ - อย่างไรก็ตามพวกเขาทั้งหมดขาดความจริงที่ว่าจะต้องไม่รวมแองเคอร์ มิฉะนั้นสคริปต์เหล่านั้นจะสร้างข้อผิดพลาด JavaScript ทันทีที่สมอที่ว่างเปล่าถูกคลิก

ในความคิดของฉันคำตอบที่ถูกต้องเป็นเช่นนี้

$('a[href*=\\#]:not([href$=\\#])').click(function() {
    event.preventDefault();

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top
    }, 500);
});

4

ใช้ JQuery:

$('a[href*=#]').click(function(){
  $('html, body').animate({
    scrollTop: $( $.attr(this, 'href') ).offset().top
  }, 500);
  return false;
});


3

คำตอบที่ให้มาทำงาน แต่ปิดการใช้งานลิงค์ขาออก ด้านล่างเวอร์ชันที่มีโบนัสเพิ่มง่าย ๆ (แกว่ง) และเคารพลิงก์ขาออก

$(document).ready(function () {
    $('a[href^="#"]').on('click', function (e) {
        e.preventDefault();

        var target = this.hash;
        var $target = $(target);

        $('html, body').stop().animate({
            'scrollTop': $target.offset().top
        }, 900, 'swing', function () {
            window.location.hash = target;
        });
    });
});

+1 สำหรับการstop()ที่ URL ย่อยไม่ทำงานตามที่คาดไว้: ปุ่มย้อนกลับไม่นำกลับมาเป็นเพราะเมื่อตั้งค่า crumb ใน URL หลังจากที่ภาพเคลื่อนไหวเสร็จสมบูรณ์ มันจะดีกว่าถ้าไม่มีเศษเล็กเศษน้อยใน url เช่นนั้นเป็นวิธีที่ airbnb ทำ
Eric

3

HTML

<a href="#target" class="smooth-scroll">
    Link
</a>
<div id="target"></div>

หรือด้วย URL แบบเต็มแน่นอน

<a href="https://somewebsite.com/#target" class="smooth-scroll">
    Link
</a>
<div id="target"></div>

jQuery

$j(function() {
    $j('a.smooth-scroll').click(function() {
        if (
                window.location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '')
            &&  window.location.hostname == this.hostname
        ) {
            var target = $j(this.hash);
            target = target.length ? target : $j('[name=' + this.hash.slice(1) + ']');
            if (target.length) {
                $j('html,body').animate({
                    scrollTop: target.offset().top - 70
                }, 1000);
                return false;
            }
        }
    });
});

3

เบราว์เซอร์สมัยใหม่จะเร็วขึ้นเล็กน้อยในวันนี้ setInterval อาจทำงานได้ ฟังก์ชั่นนี้ใช้งานได้ดีใน Chrome และ Firefox ทุกวันนี้ (ซาฟารีค่อนข้างช้าไม่รำคาญกับ IE)

function smoothScroll(event) {
    if (event.target.hash !== '') { //Check if tag is an anchor
        event.preventDefault()
        const hash = event.target.hash.replace("#", "")
        const link = document.getElementsByName(hash) 
        //Find the where you want to scroll
        const position = link[0].getBoundingClientRect().y 
        let top = 0

        let smooth = setInterval(() => {
            let leftover = position - top
            if (top === position) {
                clearInterval(smooth)
            }

            else if(position > top && leftover < 10) {
                top += leftover
                window.scrollTo(0, top)
            }

            else if(position > (top - 10)) {
                top += 10
                window.scrollTo(0, top)
            }

        }, 6)//6 milliseconds is the faster chrome runs setInterval
    }
}

3

มีวิธี CSS ในการทำเช่นนี้โดยใช้เลื่อนพฤติกรรม เพิ่มคุณสมบัติต่อไปนี้

    scroll-behavior: smooth;

และนั่นคือมัน ไม่จำเป็นต้องใช้ JS

a {
  display: inline-block;
  width: 50px;
  text-decoration: none;
}
nav, scroll-container {
  display: block;
  margin: 0 auto;
  text-align: center;
}
nav {
  width: 339px;
  padding: 5px;
  border: 1px solid black;
}
scroll-container {
  display: block;
  width: 350px;
  height: 200px;
  overflow-y: scroll;
  scroll-behavior: smooth;
}
scroll-page {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 5em;
}
<nav>
  <a href="#page-1">1</a>
  <a href="#page-2">2</a>
  <a href="#page-3">3</a>
</nav>
<scroll-container>
  <scroll-page id="page-1">1</scroll-page>
  <scroll-page id="page-2">2</scroll-page>
  <scroll-page id="page-3">3</scroll-page>
</scroll-container>

PS: โปรดตรวจสอบความเข้ากันได้ของเบราว์เซอร์


คอนเทนเนอร์ใดที่ฉันควรใช้ scroll-behavior: smooth;
CraZyDroiD

ในกรณีที่มีข้อสงสัยให้เพิ่มไปยังแท็ก body @CraZyDroiD
Santosh

2

เพิ่มสิ่งนี้:

function () {
    window.location.hash = href;
}

เป็นการทำให้ออฟเซ็ตในแนวตั้งเป็นโมฆะ

top - 72

ใน Firefox และ IE โปรดอย่าใช้ Chrome โดยทั่วไปหน้าจะเลื่อนไปยังจุดที่มันควรจะหยุดอย่างราบรื่นโดยขึ้นอยู่กับการชดเชย แต่จากนั้นก็กระโดดลงไปที่หน้าจะไปโดยไม่ต้องชดเชย

มันเพิ่มแฮชที่ส่วนท้ายของ url แต่การกดกลับไม่ได้นำคุณกลับไปที่ด้านบนมันแค่เอาแฮชออกจาก url และออกจากหน้าต่างการดู

นี่คือ js แบบเต็มที่ฉันใช้อยู่:

var $root = $('html, body');
$('a').click(function() {
    var href = $.attr(this, 'href');
    $root.animate({
        scrollTop: $(href).offset().top - 120
    }, 500, function () {
        window.location.hash = href;
    });
    return false;
});

2

โซลูชันนี้จะทำงานกับ URL ต่อไปนี้โดยไม่ทำลายจุดยึดลิงก์ไปยังหน้าต่างๆ

http://www.example.com/dir/index.html
http://www.example.com/dir/index.html#anchor

./index.html
./index.html#anchor

เป็นต้น

var $root = $('html, body');
$('a').on('click', function(event){
    var hash = this.hash;
    // Is the anchor on the same page?
    if (hash && this.href.slice(0, -hash.length-1) == location.href.slice(0, -location.hash.length-1)) {
        $root.animate({
            scrollTop: $(hash).offset().top
        }, 'normal', function() {
            location.hash = hash;
        });
        return false;
    }
});

ฉันยังไม่ได้ทดสอบในเบราว์เซอร์ทั้งหมด


2

สิ่งนี้จะทำให้ง่ายต่อการอนุญาตให้ jQuery แยกแยะแฮชเป้าหมายของคุณและทราบเวลาและสถานที่ที่จะหยุด

$('a[href*="#"]').click(function(e) {
    e.preventDefault();
    var target = this.hash;
    $target = $(target);

    $('html, body').stop().animate({
        'scrollTop': $target.offset().top
    }, 900, 'swing', function () {
        window.location.hash = target;
    });
});

2
$("a").on("click", function(event){
    //check the value of this.hash
    if(this.hash !== ""){
        event.preventDefault();

        $("html, body").animate({scrollTop:$(this.hash).offset().top}, 500);

        //add hash to the current scroll position
        window.location.hash = this.hash;

    }



});

2

รหัสผ่านการทดสอบและตรวจสอบแล้ว

<script>
jQuery(document).ready(function(){
// Add smooth scrolling to all links
jQuery("a").on('click', function(event) {

// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
  // Prevent default anchor click behavior
  event.preventDefault();

  // Store hash
  var hash = this.hash;

  // Using jQuery's animate() method to add smooth page scroll
  // The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
  jQuery('html, body').animate({
    scrollTop: jQuery(hash).offset().top
  }, 800, function(){

    // Add hash (#) to URL when done scrolling (default click behavior)
    window.location.hash = hash;
  });
} // End if
});
});
</script>

1

ฉันทำสิ่งนี้ทั้ง "/ xxxxx # asdf" และ "#asdf" href anchors

$("a[href*=#]").on('click', function(event){
    var href = $(this).attr("href");
    if ( /(#.*)/.test(href) ){
      var hash = href.match(/(#.*)/)[0];
      var path = href.match(/([^#]*)/)[0];

      if (window.location.pathname == path || path.length == 0){
        event.preventDefault();
        $('html,body').animate({scrollTop:$(this.hash).offset().top}, 1000);
        window.location.hash = hash;
      }
    }
});

1

นี่เป็นวิธีที่ฉันใช้สำหรับการเชื่อมโยงและจุดยึดหลายจุดเพื่อการเลื่อนที่ราบรื่น:

http://www.adriantomic.se/development/jquery-localscroll-tutorial/ หากคุณมีลิงค์นำทางของคุณติดตั้งใน div navigation และประกาศด้วยโครงสร้างนี้:

<a href = "#destinationA">

และปลายทางแท็กจุดยึดของคุณที่สอดคล้องกันดังนี้:

<a id = "destinationA">

จากนั้นโหลดลงในส่วนหัวของเอกสาร:

    <!-- Load jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>

<!-- Load ScrollTo -->
<script src="http://flesler-plugins.googlecode.com/files/jquery.scrollTo-1.4.2-min.js"></script>

<!-- Load LocalScroll -->
<script src="http://flesler-plugins.googlecode.com/files/jquery.localscroll-1.2.7-min.js"></script>

<script type = "text/javascript">
 $(document).ready(function()
    {
        // Scroll the whole document
        $('#menuBox').localScroll({
           target:'#content'
        });
    });
</script>

ขอบคุณ @Adriantomic


1

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

$(window).on('hashchange', function(event) {
    if (event.target.location.hash=="") {
        window.scrollTo(0,0);
    }
});

สิ่งนี้สามารถขยายออกไปเพื่อข้ามไปยังหน่วยงานต่างๆได้ด้วยการอ่านค่าแฮชและการเลื่อนเหมือนโจเซฟไซเบอร์ตอบ


1

อย่าลืมว่าฟังก์ชั่น offset () กำลังให้ตำแหน่งขององค์ประกอบกับเอกสาร ดังนั้นเมื่อคุณต้องการเลื่อนองค์ประกอบของคุณสัมพันธ์กับแม่ของมันคุณควรใช้สิ่งนี้;

    $('.a-parent-div').find('a').click(function(event){
        event.preventDefault();
        $('.scroll-div').animate({
     scrollTop: $( $.attr(this, 'href') ).position().top + $('.scroll-div').scrollTop()
     }, 500);       
  });

จุดสำคัญคือการรับ scrollTop ของ scroll-div และเพิ่มลงใน scrollTop หากคุณจะไม่ทำฟังก์ชั่น position () นั้นจะให้ค่าตำแหน่งที่แตกต่างกันเสมอ


1

คุณสามารถใช้window.scroll()กับbehavior: smoothและtopตั้งค่าเป็นส่วนบนออฟเซ็ตของแท็กสมอซึ่งทำให้มั่นใจได้ว่าแท็กจุดยึดจะอยู่ที่ด้านบนของวิวพอร์ต

document.querySelectorAll('a[href^="#"]').forEach(a => {
    a.addEventListener('click', function (e) {
        e.preventDefault();
        var href = this.getAttribute("href");
        var elem = document.querySelector(href)||document.querySelector("a[name="+href.substring(1, href.length)+"]");
        //gets Element with an id of the link's href 
        //or an anchor tag with a name attribute of the href of the link without the #
        window.scroll({
            top: elem.offsetTop, 
            left: 0, 
            behavior: 'smooth' 
        });
        //if you want to add the hash to window.location.hash
        //you will need to use setTimeout to prevent losing the smooth scrolling behavior
       //the following code will work for that purpose
       /*setTimeout(function(){
            window.location.hash = this.hash;
        }, 2000); */
    });
});

การสาธิต:

คุณสามารถตั้งค่าคุณสมบัติ CSS scroll-behaviorเป็นsmooth(ซึ่งเบราว์เซอร์ที่ทันสมัยที่สุดสนับสนุน) ซึ่ง obviates ต้องการ Javascript


0

ขอบคุณสำหรับการแบ่งปัน Joseph Silber นี่คือโซลูชัน 2018 ของคุณในฐานะ ES6 ที่มีการเปลี่ยนแปลงเล็กน้อยเพื่อให้มีพฤติกรรมมาตรฐาน (เลื่อนไปด้านบน):

document.querySelectorAll("a[href^=\"#\"]").forEach((anchor) => {
  anchor.addEventListener("click", function (ev) {
    ev.preventDefault();

    const targetElement = document.querySelector(this.getAttribute("href"));
    targetElement.scrollIntoView({
      block: "start",
      alignToTop: true,
      behavior: "smooth"
    });
  });
});

0

ต้องการ jquery และแอนิเมชั่นเพื่อยึดแท็กด้วยชื่อที่ระบุแทน id ในขณะที่เพิ่มแฮชไปยัง URL ของเบราว์เซอร์ แก้ไขข้อผิดพลาดในคำตอบส่วนใหญ่ด้วย jquery โดยที่ # sign จะไม่ขึ้นต้นด้วย backslash ที่หลบหนี ปุ่มย้อนกลับโชคไม่ดีที่ไม่สามารถนำทางกลับไปยังลิงค์แฮชก่อนหน้าได้อย่างถูกต้อง ...

$('a[href*=\\#]').click(function (event)
{
    let hashValue = $(this).attr('href');
    let name = hashValue.substring(1);
    let target = $('[name="' + name + '"]');
    $('html, body').animate({ scrollTop: target.offset().top }, 500);
    event.preventDefault();
    history.pushState(null, null, hashValue);
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.