Scrollend เหตุการณ์ JavaScript ใหม่

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

อดัม อาร์ไกล์
อดัม อาร์ไกล์

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

ก่อน
document.onscroll = event => {
  clearTimeout(window.scrollEndTimer)
  window.scrollEndTimer = setTimeout(callback, 100)
}

วิธีที่ดีที่สุดที่กลยุทธ์ setTimeout() นี้ทำได้คือรู้ว่าการเลื่อนหยุดลงเป็นเวลา 100ms แล้วหรือไม่ ซึ่งทำให้ดูเหมือนการเลื่อนมีเหตุการณ์หยุดชั่วคราว ไม่ใช่การเลื่อนได้สิ้นสุดเหตุการณ์

หลังเหตุการณ์ scrollend เบราว์เซอร์จะทำการประเมินที่ยากๆ นี้ให้คุณ

หลัง
document.onscrollend = event => {…}

นั่นเป็นสิ่งที่ดี มีเวลาที่เหมาะสมและเต็มไปด้วยสภาวะที่มีความหมาย ก่อนที่จะปล่อยออกมา

การสนับสนุนเบราว์เซอร์

  • 114
  • 114
  • 109
  • x

แหล่งที่มา

ลองใช้งาน

รายละเอียดเหตุการณ์

เหตุการณ์ scrollend จะเริ่มทำงานในกรณีต่อไปนี้ - เบราว์เซอร์ไม่เคลื่อนไหวหรือแปลการเลื่อนอีกต่อไป - ปล่อยการสัมผัสของผู้ใช้แล้ว - ตัวชี้ของผู้ใช้ปล่อยนิ้วโป้งเลื่อน - ปล่อยการกดแป้นของผู้ใช้แล้ว - เลื่อนไปยังส่วนย่อยเสร็จสมบูรณ์แล้ว - การสแนปการเลื่อนเสร็จสมบูรณ์แล้ว - scrollTo() เสร็จสมบูรณ์แล้ว - ผู้ใช้เลื่อนวิวพอร์ตภาพ

เหตุการณ์ scrollend ไม่เริ่มทำงานในกรณีต่อไปนี้ - ท่าทางสัมผัสของผู้ใช้ไม่ส่งผลให้เกิดการเปลี่ยนแปลงตำแหน่งการเลื่อนใดๆ (ไม่มีการแปล) - scrollTo() ไม่พบคำแปลใดๆ

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

การใช้กิจกรรม

คุณลงทะเบียน Listener ได้ 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 ในตัวของเบราว์เซอร์ (หากมี) หากไม่มี สคริปต์จะดูเหตุการณ์ตัวชี้และเลื่อนเพื่อประเมินเหตุการณ์สิ้นสุดอย่างดีที่สุดเท่าที่ทำได้

Use Case

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

คุณใช้เหตุการณ์ scrollend เพื่อทริกเกอร์การดำเนินการต่างๆ ได้ กรณีการใช้งานที่พบบ่อยคือการซิงค์องค์ประกอบ UI ที่เกี่ยวข้องเข้ากับตำแหน่งที่การเลื่อนหยุดลง ตัวอย่างเช่น - การซิงค์ตำแหน่งการเลื่อนภาพหมุนที่มีเครื่องหมายจุด - การซิงค์รายการในแกลเลอรีกับข้อมูลเมตา - การดึงข้อมูลหลังจากที่ผู้ใช้เลื่อนไปยังแท็บใหม่

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

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

นี่คือตัวอย่างที่ดีที่ต้องอัปเดตองค์ประกอบหลายรายการ เช่น ลูกศร จุด และโฟกัสตามตำแหน่งการเลื่อน ดูวิธีที่ฉันสร้างภาพสไลด์นี้บน YouTube และลองการสาธิตการใช้งานจริง

ขอขอบคุณ Mehdi Kazemi สำหรับงานด้านวิศวกรรมในเรื่องนี้ และ Robert Flack สำหรับ API และคำแนะนำในการใช้งาน