ลบฟังก์ชันการหมดเวลาและกำจัดข้อบกพร่องของฟังก์ชันเหล่านั้น เหตุการณ์ที่คุณต้องการจริงๆ คือ scrollend
ก่อนเหตุการณ์ scrollend
ยังไม่มีวิธีที่เชื่อถือได้ในการระบุว่าการเลื่อนสิ้นสุดแล้ว ซึ่งหมายความว่าเหตุการณ์จะทริกเกอร์ช้าหรือขณะที่นิ้วของผู้ใช้ยังอยู่บนหน้าจอ ความไม่แน่นอนนี้ในการรู้เวลาที่การเลื่อนสิ้นสุด
จริงๆ นี้ ทำให้เกิดข้อบกพร่องและประสบการณ์ใช้งานที่ไม่ดีสำหรับผู้ใช้
document.onscroll = event => { clearTimeout(window.scrollEndTimer) window.scrollEndTimer = setTimeout(callback, 100) }
กลยุทธ์ setTimeout()
นี้ที่ดีที่สุดคือการทราบว่าการเลื่อนหยุดไปเป็นเวลา 100ms
หรือไม่ ซึ่งทำให้ดูเหมือนเหตุการณ์การเลื่อนหยุดชั่วคราวมากกว่าเหตุการณ์การเลื่อนสิ้นสุด
หลังเหตุการณ์ scrollend
เบราว์เซอร์จะทำการประเมินที่ยากนี้ทั้งหมดให้คุณ
document.onscrollend = event => {…}
เยี่ยมเลย กำหนดเวลาอย่างเหมาะเจาะและเต็มไปด้วยเงื่อนไขที่มีความหมาย ก่อนออกเดินทาง
ลองใช้งาน
รายละเอียดเหตุการณ์
เหตุการณ์ scrollend
จะเริ่มทำงานในกรณีต่อไปนี้
- เบราว์เซอร์ไม่เคลื่อนไหวหรือแปลการเลื่อนอีกต่อไป
- ผู้ใช้ปล่อยนิ้วออกจากหน้าจอแล้ว
- ผู้ใช้ปล่อยนิ้วออกจากปุ่มเลื่อน
- ปล่อยการกดแป้นของผู้ใช้แล้ว
- เลื่อนไปยังส่วนที่เลือกเสร็จสมบูรณ์
- เลื่อนเพื่อดูภาพเสร็จสมบูรณ์
- scrollTo()
เสร็จสมบูรณ์แล้ว
- ผู้ใช้เลื่อนวิวพอร์ตภาพ
เหตุการณ์ scrollend
จะไม่เริ่มทำงานในกรณีต่อไปนี้
- ท่าทางสัมผัสของผู้ใช้ไม่ส่งผลให้เกิดการเปลี่ยนแปลงตำแหน่งการเลื่อน (ไม่มีการแปลเกิดขึ้น)
- scrollTo()
ไม่มีการแปล
เหตุผลที่เหตุการณ์นี้ใช้เวลานานมากกว่าจะมาถึงแพลตฟอร์มเว็บก็เพราะรายละเอียดเล็กๆ น้อยๆ มากมายที่ต้องมีรายละเอียดข้อมูลจำเพาะ หนึ่งในส่วนที่ซับซ้อนที่สุดคือการอธิบายรายละเอียด scrollend
สำหรับวิดเจ็ตภาพเทียบกับเอกสาร ลองนึกถึงหน้าเว็บที่คุณซูมเข้า คุณสามารถเลื่อนไปรอบๆ เมื่ออยู่ในสถานะการซูมนี้ และไม่จำเป็นต้องเลื่อนเอกสาร โปรดมั่นใจได้ว่าแม้แต่การโต้ตอบแบบเลื่อนที่ขับเคลื่อนโดยภาพของผู้ใช้ในวิวพอร์ตนี้จะปล่อยเหตุการณ์ scrollend
เมื่อเสร็จสมบูรณ์
การใช้เหตุการณ์
คุณสามารถลงทะเบียน Listeners ได้ 2 วิธีเช่นเดียวกับเหตุการณ์การเลื่อนอื่นๆ
addEventListener("scrollend", (event) => {
// scroll ended
});
aScrollingElement.addEventListener("scrollend", (event) => {
// scroll ended
});
หรือใช้พร็อพเพอร์ตี้เหตุการณ์
document.onscrollend = (event) => {
// scroll ended
};
aScrollingElement.onscrollend = (event) => {
// scroll ended
};
โพลีฟิลล์และการเพิ่มประสิทธิภาพแบบต่อเนื่อง
หากคุณต้องการใช้เหตุการณ์ใหม่นี้ในตอนนี้ คำแนะนำที่ดีที่สุดของเรามีดังนี้ คุณใช้กลยุทธ์สิ้นสุดการเลื่อนปัจจุบันต่อไปได้ (หากมี) และตรวจสอบการรองรับในตอนต้นด้วยสิ่งต่อไปนี้
'onscrollend' in window
// true, if available
ซึ่งจะรายงานเป็นจริงหรือเท็จโดยขึ้นอยู่กับว่าเบราว์เซอร์เสนอเหตุการณ์หรือไม่ การตรวจสอบนี้ช่วยให้คุณแยกโค้ดได้ ดังนี้
if ('onscrollend' in window) {
document.onscrollend = callback
}
else {
document.onscroll = event => {
clearTimeout(window.scrollEndTimer)
window.scrollEndTimer = setTimeout(callback, 100)
}
}
นี่เป็นจุดเริ่มต้นที่ดีในการปรับปรุงกิจกรรม scrollend
อย่างต่อเนื่องเมื่อพร้อมใช้งาน นอกจากนี้ คุณยังลองใช้ polyfill (NPM) ที่เราสร้างขึ้นซึ่งทำงานได้ดีที่สุดเท่าที่เบราว์เซอร์จะทำได้ ดังนี้
import {scrollend} from "scrollyfills"
// then use scrollend as if it's existed this whole time
document.onscrollend = callback
โพลีฟีลจะปรับปรุงอย่างต่อเนื่องเพื่อใช้เหตุการณ์ scrollend
ที่มาพร้อมเบราว์เซอร์ (หากมี) หากไม่พร้อมใช้งาน สคริปต์จะดูเหตุการณ์ตัวชี้และเลื่อนเพื่อคาดคะเนการสิ้นสุดเหตุการณ์ที่ดีที่สุดเท่าที่ทำได้
กรณีการใช้งาน
คุณควรหลีกเลี่ยงการทำงานที่ต้องคำนวณมากขณะที่เลื่อนอยู่ แนวทางปฏิบัตินี้ช่วยให้การเลื่อนใช้หน่วยความจําและการประมวลผลได้อย่างเต็มที่เพื่อให้ประสบการณ์การใช้งานราบรื่น การใช้เหตุการณ์ scrollend
ช่วยให้คุณแสดงข้อความและดึงดูดความสนใจได้เหมาะเจาะที่สุด เนื่องจากผู้ใช้ไม่ได้เลื่อนดูอีกต่อไป
คุณใช้เหตุการณ์ scrollend
เพื่อทริกเกอร์การดําเนินการต่างๆ ได้ Use Case ที่พบบ่อยคือการซิงค์องค์ประกอบ UI ที่เชื่อมโยงกับตำแหน่งที่การเลื่อนหยุด เช่น
- การซิงค์ตำแหน่งการเลื่อนของภาพสไลด์กับตัวบ่งชี้จุด
- การซิงค์รายการแกลเลอรีกับข้อมูลเมตา
- การดึงข้อมูลหลังจากที่ผู้ใช้เลื่อนไปยังแท็บใหม่
ลองนึกถึงสถานการณ์ เช่น ผู้ใช้ปัดอีเมลออก หลังจากปัดเสร็จแล้ว คุณจะดำเนินการได้ตามตำแหน่งที่ผู้ใช้เลื่อนหน้าจอไป
คุณยังใช้เหตุการณ์นี้เพื่อซิงค์ข้อมูลหลังจากการเลื่อนแบบเป็นโปรแกรมหรือการเลื่อนโดยผู้ใช้ หรือการดำเนินการต่างๆ เช่น การบันทึกข้อมูลวิเคราะห์
ต่อไปนี้เป็นตัวอย่างที่ดีที่องค์ประกอบหลายอย่าง เช่น ลูกศร จุด และโฟกัส ต้องอัปเดตตามตำแหน่งการเลื่อน ดูวิธีที่ฉันสร้างภาพสไลด์นี้ใน YouTube นอกจากนี้ โปรดลองใช้เดโมเวอร์ชันที่ใช้จริง
ขอขอบคุณ Mehdi Kazemi สำหรับงานด้านวิศวกรรมเกี่ยวกับเรื่องนี้ และ Robert Flack สำหรับคำแนะนำเกี่ยวกับ API และการใช้งาน