ก่อนหน้านี้การชี้ให้เห็นสิ่งต่างๆ บนเว็บเป็นเรื่องง่าย คุณใช้เมาส์เลื่อนไปรอบๆ บางครั้งก็ผลักปุ่ม แค่นั้นเอง ทุกอย่างที่ไม่ใช่หนูจะเลียนแบบเป็นรูปเดียว และนักพัฒนาซอฟต์แวร์ก็รู้ดีว่าต้องใช้อะไร
แต่ความเรียบง่ายไม่ได้หมายความว่าดีเสมอไป เมื่อเวลาผ่านไป สิ่งที่สำคัญขึ้นเรื่อยๆ คือไม่ใช่ว่าทุกอย่างเป็น (หรือแสร้งทำเป็น) เมาส์เลย คุณอาจใช้ปากกาไวต่อแรงกดและปากกาที่รับรู้ได้เอียงได้ เพื่ออิสระในการสร้างสรรค์อันน่าตื่นตาตื่นใจ คุณสามารถใช้นิ้ว ทั้งหมดที่แค่มีอุปกรณ์และมือของคุณเอง เอาล่ะ ทำไมไม่ใช้มากกว่า 1 นิ้วล่ะ
เรามีเหตุการณ์การแตะมาสักพักหนึ่งแล้วเพื่อช่วยคุณในเรื่องนี้ แต่เหตุการณ์เหล่านั้นเป็น API ที่แยกต่างหากโดยสิ้นเชิงสำหรับการสัมผัส ซึ่งบังคับให้คุณเขียนโค้ดรูปแบบเหตุการณ์ 2 รูปแบบแยกกันหากต้องการรองรับทั้งเมาส์และการแตะ Chrome 55 มาพร้อมกับมาตรฐานที่ใหม่กว่า ที่รวมทั้ง 2 รุ่นเข้าด้วยกัน คือ กิจกรรมตัวชี้
รูปแบบเหตุการณ์เดียว
เหตุการณ์ตัวชี้จะรวมโมเดลอินพุตตัวชี้สำหรับเบราว์เซอร์ เพื่อนำการแตะ ปากกา และเมาส์มารวมกันเป็นเหตุการณ์ชุดเดียว เช่น
document.addEventListener('pointermove',
ev => console.log('The pointer moved.'));
foo.addEventListener('pointerover',
ev => console.log('The pointer is now over foo.'));
นี่คือรายการเหตุการณ์ทั้งหมดที่มี ซึ่งคุณน่าจะคุ้นเคยกับเหตุการณ์จากเมาส์
pointerover
|
ตัวชี้เข้าสู่กรอบล้อมรอบขององค์ประกอบ
การดำเนินการนี้จะเกิดขึ้นทันทีสำหรับอุปกรณ์ที่รองรับการวางเมาส์เหนือรายการ หรือก่อนเหตุการณ์ pointerdown สำหรับอุปกรณ์ที่ไม่รองรับ
|
pointerenter
|
คล้ายกับ pointerover แต่ไม่ได้แสดงเป็นบับเบิลและจัดการองค์ประกอบสืบทอดแตกต่างกัน
รายละเอียดเกี่ยวกับข้อกำหนด
|
pointerdown
|
ตัวชี้เข้าสู่สถานะของปุ่มที่ใช้งานอยู่ โดยมีการกดปุ่มหรือการสร้างรายชื่อติดต่อ ทั้งนี้ขึ้นอยู่กับความหมายของอุปกรณ์อินพุต |
pointermove
|
เคอร์เซอร์เปลี่ยนตำแหน่ง |
pointerup
|
ตัวชี้ออกจากสถานะปุ่มที่ใช้งานอยู่แล้ว |
pointercancel
|
มีบางอย่างเกิดขึ้น ซึ่งหมายความว่าเคอร์เซอร์ไม่น่าจะปล่อยเหตุการณ์ใดๆ อีก ซึ่งหมายความว่าคุณควรยกเลิกการดำเนินการที่กำลังดำเนินการอยู่และกลับสู่สถานะการป้อนข้อมูลที่เป็นกลาง |
pointerout
|
เคอร์เซอร์ออกจากกรอบล้อมรอบขององค์ประกอบหรือหน้าจอ และหลังจาก pointerup แล้ว หากอุปกรณ์ไม่รองรับการวางเมาส์เหนือ
|
pointerleave
|
คล้ายกับ pointerout แต่ไม่ได้แสดงเป็นบับเบิลและจัดการองค์ประกอบสืบทอดแตกต่างกัน
รายละเอียดเกี่ยวกับข้อกำหนด
|
gotpointercapture
|
องค์ประกอบได้รับการจับภาพตัวชี้ |
lostpointercapture
|
ปล่อยตัวชี้ที่กำลังจับภาพอยู่ |
ประเภทการป้อนข้อมูลต่างๆ
โดยทั่วไป เหตุการณ์ตัวชี้ช่วยให้คุณเขียนโค้ดได้โดยไม่ต้องป้อนข้อมูลเอง โดยไม่ต้องลงทะเบียนเครื่องจัดการเหตุการณ์แยกต่างหากสำหรับอุปกรณ์อินพุตต่างๆ
แน่นอนว่าคุณยังต้องคำนึงถึงความแตกต่างระหว่างอินพุตแต่ละประเภทด้วย เช่น มีการใช้แนวคิดของการวางเมาส์เหนือ หากต้องการแยกอุปกรณ์อินพุตที่แตกต่างกันหรืออาจระบุโค้ด/ฟังก์ชันการทำงานแยกต่างหากสำหรับอินพุตที่ต่างกัน แต่ก็ทำได้จากในเครื่องจัดการเหตุการณ์เดียวกันโดยใช้พร็อพเพอร์ตี้ pointerType
ของอินเทอร์เฟซ PointerEvent
เช่น หากเขียนโค้ดลิ้นชักการนำทางด้านข้าง คุณจะมีตรรกะต่อไปนี้ในเหตุการณ์ pointermove
switch(ev.pointerType) {
case 'mouse':
// Do nothing.
break;
case 'touch':
// Allow drag gesture.
break;
case 'pen':
// Also allow drag gesture.
break;
default:
// Getting an empty string means the browser doesn't know
// what device type it is. Let's assume mouse and do nothing.
break;
}
การดำเนินการเริ่มต้น
ในเบราว์เซอร์ที่เปิดใช้ระบบสัมผัส ท่าทางสัมผัสบางอย่างจะใช้เพื่อทำให้หน้าเว็บเลื่อน ซูม หรือรีเฟรช
ในกรณีของเหตุการณ์การแตะ คุณจะยังได้รับเหตุการณ์ในขณะที่มีการดำเนินการเริ่มต้นเหล่านี้อยู่ เช่น touchmove
จะยังคงเริ่มทำงานขณะที่ผู้ใช้กำลังเลื่อน
เมื่อใช้เหตุการณ์ตัวชี้ เมื่อใดก็ตามที่มีการเรียกการดำเนินการเริ่มต้น เช่นการเลื่อนหรือซูม คุณจะได้รับเหตุการณ์ pointercancel
เพื่อแจ้งให้ทราบว่าเบราว์เซอร์ได้ควบคุมเคอร์เซอร์แล้ว เช่น
document.addEventListener('pointercancel',
ev => console.log('Go home, the browser is in charge now.'));
ความเร็วในตัว: โมเดลนี้ให้ประสิทธิภาพที่ดีขึ้นโดยค่าเริ่มต้นเมื่อเทียบกับเหตุการณ์การสัมผัส ซึ่งคุณจะต้องใช้ Listener เหตุการณ์แบบแพสซีฟเพื่อให้ได้การตอบสนองในระดับเดียวกัน
คุณหยุดไม่ให้เบราว์เซอร์ควบคุมได้ด้วยพร็อพเพอร์ตี้ CSS ของ touch-action
การตั้งค่าเป็น none
ในองค์ประกอบหนึ่งจะปิดการทำงานทั้งหมดที่เบราว์เซอร์กำหนดซึ่งเริ่มต้นเหนือองค์ประกอบนั้น แต่มีค่าอื่นๆ อีกจำนวนหนึ่งสำหรับการควบคุมที่ละเอียดยิ่งขึ้น เช่น pan-x
ที่ช่วยให้เบราว์เซอร์ตอบสนองต่อการเคลื่อนไหวในแกน x แต่ไม่ใช่แกน y Chrome 55 รองรับค่าต่อไปนี้
auto
|
ค่าเริ่มต้น เบราว์เซอร์จะดำเนินการต่างๆ ตามค่าเริ่มต้นได้ |
none
|
เบราว์เซอร์ไม่ได้รับอนุญาตให้ดำเนินการใดๆ ที่เป็นค่าเริ่มต้น |
pan-x
|
เบราว์เซอร์ได้รับอนุญาตให้ดำเนินการเลื่อนเริ่มต้นในแนวนอนเท่านั้น |
pan-y
|
เบราว์เซอร์ได้รับอนุญาตให้ดำเนินการเลื่อนตามค่าเริ่มต้นในแนวตั้งเท่านั้น |
pan-left
|
เบราว์เซอร์ได้รับอนุญาตให้ดำเนินการเลื่อนเริ่มต้นในแนวนอนเท่านั้น และเพียงแค่เลื่อนหน้าเว็บไปทางซ้ายเท่านั้น |
pan-right
|
เบราว์เซอร์ได้รับอนุญาตให้ดำเนินการเลื่อนเริ่มต้นในแนวนอนเท่านั้น และเพียงแค่เลื่อนหน้าเว็บไปทางขวา |
pan-up
|
เบราว์เซอร์ได้รับอนุญาตให้ดำเนินการเลื่อนเริ่มต้นในแนวตั้งเท่านั้น และเลื่อนหน้าขึ้นเท่านั้น |
pan-down
|
เบราว์เซอร์ได้รับอนุญาตให้ดำเนินการการเลื่อนตามค่าเริ่มต้นในแนวตั้งเท่านั้น โดยจะเลื่อนหน้าเว็บลงเท่านั้น |
manipulation
|
เบราว์เซอร์ได้รับอนุญาตให้ดำเนินการการเลื่อนและซูมเท่านั้น |
การจับภาพตัวชี้
คุณเคยเสียเวลาไปกับการแก้ไขข้อบกพร่องของเหตุการณ์ mouseup
ที่เสียหายจนนึกขึ้นได้ว่านั่นเป็นเพราะผู้ใช้ปล่อยปุ่มนอกเป้าหมายการคลิก หากไม่ โอเค งั้นก็มีแค่ฉันคนเดียว
อย่างไรก็ตาม ก่อนหน้านี้ยังไม่มีวิธีรับมือกับปัญหานี้ได้เป็นอย่างดี ได้เลย คุณตั้งค่าเครื่องจัดการ mouseup
ในเอกสาร และบันทึกสถานะบางอย่างในแอปพลิเคชันเพื่อติดตามข้อมูลได้ นั่นไม่ใช่ทางออกที่สะอาดที่สุด อย่างไรก็ตาม คุณกำลังสร้างคอมโพเนนต์เว็บและพยายามทำให้ทุกอย่างเรียบร้อยดีและอยู่โดดเดี่ยว
กิจกรรมตัวชี้มอบวิธีแก้ปัญหาที่ดีกว่ามาก กล่าวคือ คุณสามารถจับภาพตัวชี้ได้เพื่อให้แน่ใจว่าคุณจะได้รับเหตุการณ์ pointerup
นั้น (หรือเพื่อนที่เข้าใจยากรายการอื่นๆ)
const foo = document.querySelector('#foo');
foo.addEventListener('pointerdown', ev => {
console.log('Button down, capturing!');
// Every pointer has an ID, which you can read from the event.
foo.setPointerCapture(ev.pointerId);
});
foo.addEventListener('pointerup',
ev => console.log('Button up. Every time!'));
การสนับสนุนเบราว์เซอร์
ขณะที่เขียน Pointer Event ใช้ได้ใน Internet Explorer 11, Microsoft Edge, Chrome และ Opera และ Firefox รองรับบางส่วน ดูรายการล่าสุดได้ที่ caniuse.com
คุณใช้ polyfill เหตุการณ์ของ Pointer เพื่อเติมเต็มช่องว่างได้ หรือการตรวจสอบการรองรับเบราว์เซอร์ขณะรันไทม์นั้นตรงไปตรงมา
if (window.PointerEvent) {
// Yay, we can use pointer events!
} else {
// Back to mouse and touch events, I guess.
}
เหตุการณ์ตัวชี้เป็นตัวเลือกที่ยอดเยี่ยมสำหรับการเพิ่มประสิทธิภาพแบบต่อเนื่อง เพียงแก้ไขวิธีการเริ่มต้นเพื่อทำการตรวจสอบข้างต้น เพิ่มเครื่องจัดการเหตุการณ์ของตัวชี้ในบล็อก if
และย้ายเครื่องจัดการเมาส์/เหตุการณ์การแตะไปยังบล็อก else
ดังนั้น ไปดูกันเลย และบอกให้เราทราบว่าคุณคิดอย่างไร