0Pricing
HTML Academy · บทเรียน

เหตุการณ์ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. แอตทริบิวต์ draggable และเหตุการณ์ dragstart
  2. เหตุการณ์ dragover และ drop
  3. ออบเจ็กต์ dataTransfer
  4. รายการลากเพื่อจัดลำดับใหม่ภาคปฏิบัติ
← กลับไปที่ HTML Academy