เหตุการณ์ dragover และ drop
กำหนดเป้าหมายการวางที่ถูกต้องและจัดการเหตุการณ์ drop
เหตุการณ์ dragover และ drop เป็นบทเรียน HTML Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน HTML Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส HTML Academy มีบทเรียนทั้งหมด 4 บทเรียน
เป้าหมายวางต้องมีตัวจัดการสองตัว
เป้าหมายวางต้องจัดการทั้ง dragover (เพื่ออนุญาตให้วาง) และ drop (เพื่อรับข้อมูล) หากไม่มีเหตุการณ์ลากเหนือเป้าหมาย เบราว์เซอร์จะปฏิเสธการส่งเหตุการณ์วาง เพราะพฤติกรรมเริ่มต้นคือ "ไม่มีองค์ประกอบใดเป็นเป้าหมายวาง"
ต้องเรียก preventDefault
ในตัวจัดการเหตุการณ์ลากเหนือเป้าหมาย คุณต้องเรียก e.preventDefault() เพื่อยกเลิกค่าเริ่มต้นของเบราว์เซอร์ที่ปฏิเสธการวาง หากไม่เรียก เคอร์เซอร์จะคงสถานะ "ไม่อนุญาต" และเหตุการณ์วางจะไม่ทำงาน ไม่ว่าผู้ใช้จะทำอะไร
zone.addEventListener("dragover", (e) => {
e.preventDefault();
});
zone.addEventListener("drop", (e) => {
e.preventDefault();
console.log(e.dataTransfer.getData("text/plain"));
});การเข้าสู่และออกจากพื้นที่ลาก
เหตุการณ์เข้าสู่พื้นที่ลากจะทำงานหนึ่งครั้งเมื่อเคอร์เซอร์เข้าสู่เป้าหมาย ส่วนเหตุการณ์ออกจากพื้นที่ลากจะทำงานหนึ่งครั้งเมื่อเคอร์เซอร์ออก ใช้เหตุการณ์เหล่านี้เพื่อเปิดหรือปิดการเน้น "ลากเหนือเป้าหมาย" โดยเพิ่มคลาสเมื่อเข้าสู่ และลบออกเมื่อออก เพื่อให้ผู้ใช้เห็นว่าพื้นที่ใดจะรับข้อมูลที่วาง
เหตุการณ์ออกจากพื้นที่ลากทำงานกับองค์ประกอบลูก
มีพฤติกรรมเล็ก ๆ ที่ควรระวัง: เมื่อเลื่อนเคอร์เซอร์ไปเหนือองค์ประกอบลูก จะทำให้เหตุการณ์ออกจากพื้นที่ลากทำงานที่องค์ประกอบแม่ ตามด้วยเหตุการณ์เข้าสู่พื้นที่ลากที่องค์ประกอบลูก ใช้ counter โดยเพิ่มค่าในเหตุการณ์เข้าสู่พื้นที่ลากและลดค่าในเหตุการณ์ออกจากพื้นที่ลาก แล้วลบการเน้นก็ต่อเมื่อ counter กลับเป็นศูนย์
let counter = 0;
zone.addEventListener("dragenter", () => {
counter++;
zone.classList.add("over");
});
zone.addEventListener("dragleave", () => {
counter--;
if (counter === 0) zone.classList.remove("over");
});การกำหนด dropEffect
ภายในเหตุการณ์ลากเหนือเป้าหมาย ให้กำหนด e.dataTransfer.dropEffect = "move" (หรือ "copy", "link", "none") เพื่อควบคุมเคอร์เซอร์และบอกแหล่งลากว่าจะเกิดอะไรขึ้น การดำเนินการต้องเข้ากันได้กับ effectAllowed ของแหล่งลาก มิฉะนั้นการวางจะถูกปฏิเสธ
การอ่านข้อมูลเมื่อวาง
ในตัวจัดการเหตุการณ์วาง ให้เรียก e.dataTransfer.getData(format) โดยใช้ชนิด MIME เดียวกับที่ใช้กับ setData (โดยทั่วไปคือ "text/plain") จากนั้นค้นหาองค์ประกอบด้วยตัวระบุ เพิ่มองค์ประกอบนั้นไปยังเป้าหมาย อัปเดตแบบจำลองข้อมูล หรือดำเนินการอื่นตามที่แอปพลิเคชันต้องการ
การป้องกันค่าเริ่มต้นเมื่อวาง
คุณต้องเรียก e.preventDefault() ในตัวจัดการเหตุการณ์วางด้วย หากไม่เรียก เบราว์เซอร์จะกลับไปใช้พฤติกรรมในตัว — สำหรับ URL ที่ถูกวาง นั่นหมายถึงการนำทางไปยังลิงก์ ซึ่งจะทำให้สถานะของหน้าเว็บหายไปทันที
การวางจากเดสก์ท็อป
เบราว์เซอร์จะแปลงไฟล์ที่ลากจาก OS เป็นเหตุการณ์วาง โดยเติมข้อมูลใน e.dataTransfer.files ให้ครบถ้วน วนซ้ำใน FileList และอ่านไฟล์แต่ละไฟล์ด้วย API ของไฟล์ เพื่อรองรับการอัปโหลดรูปภาพ โปรแกรมดูไฟล์ log หรือโปรแกรมนำเข้าเอกสาร
zone.addEventListener("drop", (e) => {
e.preventDefault();
for (const file of e.dataTransfer.files) {
console.log(file.name, file.size);
}
});หลายชนิดใน dataTransfer
setData สามารถจัดเก็บข้อมูลเดียวกันไว้ภายใต้ชนิด MIME หลายชนิดได้ เช่น "text/plain" สำหรับการสำรอง "text/uri-list" สำหรับ URL และ "application/json" สำหรับข้อมูลที่มีโครงสร้าง เป้าหมายวางจะเลือกชนิดที่มีรายละเอียดมากที่สุดจากที่ตนเองเข้าใจผ่าน getData
การประสานงานกับเหตุการณ์สัมผัส
เบราว์เซอร์บนอุปกรณ์เคลื่อนที่จะไม่สร้างเหตุการณ์ลากเหนือเป้าหมายหรือวางจากการสัมผัสขึ้นมาเอง สำหรับประสบการณ์ที่เป็นหนึ่งเดียว ให้ใช้เหตุการณ์ตัวชี้ร่วมกับการตรวจสอบจุดชนด้วยตนเอง หรือใช้ไลบรารีที่ซ่อนความแตกต่างเหล่านี้ การลากและวางมาตรฐานของเว็บในตัวควรถือว่าเหมาะสำหรับเดสก์ท็อปเท่านั้น
เคล็ดลับด้านประสิทธิภาพ
เหตุการณ์ลากเหนือเป้าหมายจะทำงานต่อเนื่องขณะที่เคอร์เซอร์เคลื่อนที่ — บ่อยครั้งหลายสิบครั้งต่อวินาที ทำให้ตัวจัดการทำงานเบา: หลีกเลี่ยงการค้นหา DOM หรือการอ่านเลย์เอาต์ที่มีค่าใช้จ่ายสูงภายในตัวจัดการ เก็บสี่เหลี่ยมขอบเขตไว้ในเหตุการณ์เข้าสู่พื้นที่ลาก แล้วนำกลับมาใช้ขณะที่เคอร์เซอร์ยังอยู่เหนือเป้าหมาย
ตรวจสอบความรู้
เหตุใดเหตุการณ์วางจึงไม่ทำงานที่เป้าหมาย จนกว่าคุณจะเรียก e.preventDefault() ในตัวจัดการเหตุการณ์ลากเหนือเป้าหมาย
สรุป
เป้าหมายวางที่ทำงานได้ต้องรับฟังเหตุการณ์ลากเหนือเป้าหมาย (เรียก preventDefault เสมอ และอาจกำหนด dropEffect) และเหตุการณ์วาง (เรียก preventDefault อีกครั้ง แล้วอ่าน dataTransfer.getData หรือ dataTransfer.files) ใช้เหตุการณ์เข้าสู่และออกจากพื้นที่ลากร่วมกับ counter เพื่อเน้นพื้นที่ และทำให้ตัวจัดการทำงานเบา เพราะเหตุการณ์ลากเหนือเป้าหมายทำงานบ่อยมาก
คำถามที่พบบ่อย
บทเรียน “เหตุการณ์ dragover และ drop” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “เหตุการณ์ dragover และ drop” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส HTML Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส HTML Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “เหตุการณ์ dragover และ drop”
กำหนดเป้าหมายการวางที่ถูกต้องและจัดการเหตุการณ์ drop คุณปฏิบัติ HTML Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน HTML Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน HTML Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “เหตุการณ์ dragover และ drop” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน HTML Academy นี้ได้ไหม
ได้ บทเรียน HTML Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- แอตทริบิวต์ draggable และเหตุการณ์ dragstart
- เหตุการณ์ dragover และ drop
- ออบเจ็กต์ dataTransfer
- รายการลากเพื่อจัดลำดับใหม่ภาคปฏิบัติ