UPD: ฉันได้สร้างแพ็คเกจ npmที่ทำงานได้ดีกว่าโซลูชันต่อไปนี้และใช้งานง่ายกว่า
ฟังก์ชัน smoothScroll ของฉัน
ฉันได้ใช้โซลูชันที่ยอดเยี่ยมของ Steve Banton และเขียนฟังก์ชันที่ทำให้ใช้งานได้สะดวกยิ่งขึ้น มันจะง่ายกว่าที่จะใช้window.scroll()
หรือแม้กระทั่งwindow.scrollBy()
อย่างที่ฉันเคยลองมาก่อน แต่ทั้งสองมีปัญหา:
- ทุกอย่างกลายเป็นขยะหลังจากใช้งานด้วยพฤติกรรมที่ราบรื่น
- คุณไม่สามารถป้องกันได้ แต่อย่างใดและต้องรอจนกว่าจะถึงและเลื่อน ดังนั้นฉันหวังว่าฟังก์ชันของฉันจะเป็นประโยชน์สำหรับคุณ นอกจากนี้ยังมีโพลีฟิลน้ำหนักเบาที่ทำให้ใช้งานได้ใน Safari และแม้แต่ IE
นี่คือรหัส
เพียงแค่คัดลอกและทำให้ยุ่งเหยิงตามที่คุณต้องการ
import smoothscroll from 'smoothscroll-polyfill';
smoothscroll.polyfill();
const prepareSmoothScroll = linkEl => {
const EXTRA_OFFSET = 0;
const destinationEl = document.getElementById(linkEl.dataset.smoothScrollTo);
const blockOption = linkEl.dataset.smoothScrollBlock || 'start';
if ((blockOption === 'start' || blockOption === 'end') && EXTRA_OFFSET) {
const anchorEl = document.createElement('div');
destinationEl.setAttribute('style', 'position: relative;');
anchorEl.setAttribute('style', `position: absolute; top: -${EXTRA_OFFSET}px; left: 0;`);
destinationEl.appendChild(anchorEl);
linkEl.addEventListener('click', () => {
anchorEl.scrollIntoView({
block: blockOption,
behavior: 'smooth',
});
});
}
if (blockOption === 'center' || !EXTRA_OFFSET) {
linkEl.addEventListener('click', () => {
destinationEl.scrollIntoView({
block: blockOption,
behavior: 'smooth',
});
});
}
};
export const activateSmoothScroll = () => {
const linkEls = [...document.querySelectorAll('[data-smooth-scroll-to]')];
linkEls.forEach(linkEl => prepareSmoothScroll(linkEl));
};
ในการสร้างองค์ประกอบลิงก์ให้เพิ่มแอตทริบิวต์ข้อมูลต่อไปนี้:
data-smooth-scroll-to="element-id"
นอกจากนี้คุณสามารถตั้งค่าแอตทริบิวต์อื่นเป็นส่วนเสริมได้
data-smooth-scroll-block="center"
แสดงถึงblock
ตัวเลือกของscrollIntoView()
ฟังก์ชัน start
โดยค่าเริ่มต้นมัน อ่านเพิ่มเติมเกี่ยวกับMDN MDN
สุดท้าย
ปรับฟังก์ชัน smoothScroll ตามความต้องการของคุณ
ตัวอย่างเช่นหากคุณมีส่วนหัวคงที่ (หรือฉันเรียกด้วยคำว่าmasthead
) คุณสามารถทำสิ่งนี้ได้:
const mastheadEl = document.querySelector(someMastheadSelector);
const EXTRA_OFFSET = mastheadEl.offsetHeight - 3;
หากคุณไม่มีกรณีดังกล่าวก็ลบทิ้งทำไมไม่ :-D.
scrollIntoView
เป็นเรื่องที่น่าหนักใจ