เหตุการณ์การสแนปการเลื่อน

Adam Argyle
Adam Argyle

จาก Chrome 129 คุณจะใช้เหตุการณ์ scrollSnapChange และ scrollSnapChanging จาก JavaScript ได้ เมื่อใช้เหตุการณ์สแนปในตัว สถานะสแนปที่มองไม่เห็นก่อนหน้านี้จะดําเนินการได้ในเวลาที่เหมาะสมและถูกต้องเสมอ นี่ไม่ใช่ความสะดวกสบายของคุณหากไม่มีกิจกรรมเหล่านี้

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

อย่างไรก็ตาม ก่อนวันที่ scrollSnapChanging การรู้ว่าเป้าหมายสแนปกำลังเปลี่ยนแปลงหรือสิ่งที่เปลี่ยนเป็น (เช่น เมื่อมีการเลื่อน) เป็นไปไม่ได้

แถบเลื่อนแนวนอนจะแสดงโดยมีกล่องหมายเลขด้านในเป็นเป้าหมายการสแนป ทางด้านซ้ายคือบันทึกแบบเรียลไทม์ของเหตุการณ์ ScrollSnapChange ที่ไฮไลต์ snapTargetinline ด้วยสีน้ำเงิน ทางด้านขวาคือบันทึกแบบเรียลไทม์ของเหตุการณ์ ScrollSnapSwitch ซึ่งไฮไลต์ snapTargetinline ด้วยสีเทา

ลองเลย
https://codepen.io/web-dot-dev/pen/jOjaaEP

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

scrollSnapChange

เหตุการณ์นี้จะเริ่มทำงานเฉพาะเมื่อท่าทางสัมผัสการเลื่อนส่งผลให้เกิดการพักเป้าหมายการสแนปใหม่ และเป็นไปตามลำดับต่อไปนี้

  1. หลังจากที่การเลื่อนหยุดลงแล้ว
  2. ก่อนวันที่ scrollend

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

scroller.addEventListener('scrollsnapchange', event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
})

scroller.onscrollsnapchange = event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
}

เหตุการณ์จะแสดงรายการที่สแนปในออบเจ็กต์เหตุการณ์เป็น snapTargetBlock และ snapTargetInline หากแถบเลื่อนอยู่ในแนวนอนเท่านั้น พร็อพเพอร์ตี้ snapTargetBlock จะเป็น null ค่าของพร็อพเพอร์ตี้จะเป็นโหนดองค์ประกอบ

รายละเอียดที่ไม่ซ้ำกันสำหรับ ScrollSnapChange

ไม่เริ่มทำงานจนกว่าผู้ใช้จะปล่อยท่าทางสัมผัส

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

ไม่เริ่มทำงานหากเป้าหมายการสแนปไม่เปลี่ยนแปลง

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

scrollSnapChanging

เหตุการณ์นี้จะเริ่มทำงานทันทีที่เบราว์เซอร์ตัดสินใจว่าท่าทางสัมผัสการเลื่อนมีหรือจะส่งผลให้มีเป้าหมายการสแนปใหม่ โดยจะเริ่มทำงานอย่างใจจดใจจ่อและในระหว่างการเลื่อน

scroller.addEventListener('scrollsnapchanging', event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
})

scroller.onscrollsnapchanging = event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
}

เหตุการณ์จะแสดงรายการที่สแนปในออบเจ็กต์เหตุการณ์เป็น snapTargetBlock และ snapTargetInline หากแถบเลื่อนอยู่ในแนวตั้งเท่านั้น พร็อพเพอร์ตี้ snapTargetInline จะเป็น null ค่าของพร็อพเพอร์ตี้จะเป็นโหนดองค์ประกอบ

รายละเอียดที่ไม่ซ้ำกันสำหรับ ScrollSnapReplace

เริ่มทำงานล่วงหน้าและบ่อยครั้งระหว่างท่าทางสัมผัสการเลื่อน

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

ไม่เริ่มการทำงานของเป้าหมายสแนปทั้งหมดระหว่างทางไปยังเป้าหมายการสแนปใหม่

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

กรณีการใช้งานและตัวอย่าง

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

รูปแบบต่อไปนี้แสดงกรณีการใช้งานบางอย่างเพื่อช่วยให้คุณทำงานได้อย่างมีประสิทธิภาพทันที

ไฮไลต์คำนิยม

ตัวอย่างนี้ส่งเสริมหรือเน้นภาพคำนิยมที่แนบไว้

scroller.onscrollsnapchange = event => {
  scroller.querySelector(':scope .snapped')?.classList.remove('snapped')
  event.snapTargetInline.classList.add('snapped')
}
https://codepen.io/web-dot-dev/pen/dyBZZPe

แสดงคำบรรยายภาพสำหรับรายการที่สแนป

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

การเปลี่ยนสแนป
https://codepen.io/web-dot-dev/pen/wvLPPBL

สแนป เปลี่ยน
https://codepen.io/web-dot-dev/pen/QWXOObw

ภาพเคลื่อนไหวของสไลด์งานนำเสนอที่กะทันหันของเด็กๆ

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

document.addEventListener('scrollsnapchange', event => {
  event.snapTargetBlock.classList.add('seen')
})
https://codepen.io/web-dot-dev/pen/rNEYYVj

สแนปทั้ง x และ y ในแถบเลื่อน

สแนปการเลื่อนใช้ได้กับแถบเลื่อนที่อนุญาตการเลื่อนในแนวนอนและแนวตั้ง การสาธิตนี้แสดงทั้งเป้าหมาย scrollSnapChanging และ scrollSnapChange เมื่อคุณเลื่อนดูตารางกริด การสาธิตนี้จะแสดงให้เห็นว่าองค์ประกอบที่เบราว์เซอร์สแนปไปอาจไม่ใช่อย่างที่คุณคิดเสมอไป

ระบบจะแสดงตารางสี่เหลี่ยมจัตุรัสในตัวเลื่อนหน้าจอแนวนอนและแนวตั้ง ขอบเส้นประจะแสดงเป้าหมาย ScrollSnapSwitch และขอบที่เป็นเส้นทึบคือเป้าหมายscrollSnapChange สีแดงหมายถึง snapTargetinline และสีน้ำเงินแสดงถึง snapTargetBlock

https://codepen.io/web-dot-dev/pen/qBzVVdp

แถบเลื่อนที่ลิงก์ไว้ 2 รายการ

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

https://codepen.io/web-dot-dev/pen/YzoEEXj

ตัวเลือกสี OKLCH

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

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

https://codepen.io/web-dot-dev/pen/OJeOOVG

การสแนปฮับภาพเคลื่อนไหวที่ส่ายไปมา

การสาธิตนี้ปรับปรุงวิธีการสแนปการเลื่อนอย่างต่อเนื่องโดยใช้ scrollsnapchange เพื่อเปลี่ยนการสแนปที่เรียกใช้การสแนป

ตรวจสอบการรองรับเหตุการณ์ด้วย JavaScript ต่อไปนี้

if ('onscrollsnapchange' in window) {
  // ok to use snap change
}
https://codepen.io/web-dot-dev/pen/MWMOOae

ป้อนข้อมูลไม้บรรทัดแบบเลื่อนได้

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

https://codepen.io/web-dot-dev/pen/LYKOOpd

ขั้นตอนการปิด

วิดีโอสาธิตนี้สร้างขึ้นจากการสร้างภาพเคลื่อนไหวที่น่าทึ่งโดยใช้การเลื่อนหน้าจอของ Braus Van Damme จากการแสดงคัฟเวอร์เพลงของ macOS อันโด่งดัง (วิดีโอบทแนะนำด้วย) scrollSnapChanging จะใช้เพื่อซ่อนชื่ออัลบั้ม และ scrollSnapChange จะใช้เพื่อแสดงชื่ออัลบั้ม กิจกรรมช่วยสร้างความตื่นเต้นให้กับชื่อเดิมและการนำเสนอเกมใหม่อย่างขะมักเขม้น

https://codepen.io/web-dot-dev/pen/Bagmmog

ไอเดียเพิ่มเติมสำหรับจุดประกายความคิดสร้างสรรค์

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

  • ทริกเกอร์การโหลดแบบ Lazy Loading หรือที่เรียกว่า "Snapchange" ที่ทริกเกอร์การแสดงผลหรือการดึงข้อมูล
  • ภาพขนาดย่อของแถบฟิล์มที่ลิงก์กับรูปภาพขนาดใหญ่
  • สลับเล่น/หยุดชั่วคราวสำหรับตัวอย่างวิดีโอสำหรับภาพขนาดย่อของวิดีโอที่สแนป
  • การติดตาม Analytics
  • การเลื่อนผ่าน
  • UI/UX ของ Wheel of Fortune
  • เป้าหมายการสแนปจะได้รับเคล็ดลับเครื่องมือที่ปักหมุดไว้
  • แตะเพื่อสแนป
  • สแนปเพื่อแสดง
  • ส่งเสียงได้ในพริบตา
  • UI การปัด
  • แท็บหรือภาพสไลด์ที่ปัดได้

การศึกษาเพิ่มเติม

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

แหล่งข้อมูล