ลบฟังก์ชันระยะหมดเวลาและกำจัดข้อบกพร่องของระบบ สิ่งที่คุณต้องมีคือ 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
Polyfill จะเพิ่มประสิทธิภาพขึ้นเรื่อยๆ เพื่อใช้เบราว์เซอร์ scrollend
ในตัว
กิจกรรม หากมี หากไม่มี สคริปต์จะดูเหตุการณ์ตัวชี้และ
เพื่อเลื่อนหาเวลาคาดการณ์
เวลาสิ้นสุดเหตุการณ์ได้ดีที่สุด
กรณีการใช้งาน
คุณควรหลีกเลี่ยงการทำงานที่ต้องคำนวณมากขณะที่เลื่อนอยู่ แนวทางปฏิบัตินี้ช่วยให้การเลื่อนใช้หน่วยความจำและการประมวลผลได้อย่างเต็มที่เพื่อให้ประสบการณ์การใช้งานราบรื่น การใช้เหตุการณ์ scrollend
เป็นโอกาสเหมาะสําหรับการเรียกใช้และทํางานหนัก เนื่องจากผู้ใช้ไม่ได้เลื่อนดูอีกต่อไป
คุณใช้เหตุการณ์ scrollend
เพื่อทริกเกอร์การดําเนินการต่างๆ ได้ Use Case ทั่วไป
จะซิงค์องค์ประกอบ UI ที่เกี่ยวข้องกับตำแหน่งที่การเลื่อน
หยุดแล้ว เช่น
- การซิงค์ตำแหน่งการเลื่อนของภาพสไลด์กับตัวบ่งชี้จุด
- การซิงค์รายการแกลเลอรีกับข้อมูลเมตา
- การดึงข้อมูลหลังจากที่ผู้ใช้เลื่อนไปที่แท็บใหม่
ลองนึกถึงสถานการณ์ เช่น ผู้ใช้ปัดอีเมลออก หลังจากดำเนินการเสร็จสิ้น คุณจะสามารถทำงานตามตำแหน่งที่ผู้ใช้เลื่อนหน้าจอไป
คุณยังใช้เหตุการณ์นี้เพื่อซิงค์ข้อมูลหลังจากแบบเป็นโปรแกรมหรือผู้ใช้ หรือการดำเนินการต่างๆ เช่น การบันทึก Analytics
ต่อไปนี้เป็นตัวอย่างที่ดีที่องค์ประกอบหลายรายการ เช่น ลูกศร จุด และโฟกัส จำเป็นต้องอัปเดตตามตำแหน่งการเลื่อน ดูวิธีที่ฉันสร้างภาพหมุนนี้ใน YouTube นอกจากนี้ โปรดลองใช้เดโมเวอร์ชันที่ใช้จริง
ขอขอบคุณ Mehdi Kazemi สำหรับงานด้านวิศวกรรมเกี่ยวกับเรื่องนี้ และ Robert Flack สำหรับคำแนะนำเกี่ยวกับ API และการใช้งาน