Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

เหตุการณ์โหลดหน้า (Load Events) ใน JavaScript

Load Events ควบคุมจุดเวลาต่างๆ ของการโหลดหน้าเว็บ มี 4 เหตุการณ์หลัก ที่เกิดขึ้นตามลำดับ

ลำดับเหตุการณ์โหลดหน้า

  1. DOMContentLoaded - DOM Tree สร้างเสร็จ (HTML Parse เสร็จ) แต่ External Resources (CSS, Images, Fonts) ยังโหลดไม่เสร็จ
  2. load - ทุกอย่างโหลดเสร็จแล้ว (HTML, CSS, JS, Images, Fonts, Iframes)
  3. beforeunload - ก่อนหน้าจะ Unload (ปิดแท็บ, Refresh, Navigate ไปหน้าอื่น) - สามารถยกเลิกได้
  4. unload - หน้า Unload เสร็จแล้ว - ไม่สามารถยกเลิกได้

ตัวอย่าง: ตรวจจับ DOMContentLoaded

<!DOCTYPE html>
<html lang="th">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Load Events</title>
    <style>
        body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; padding: 20px; }
        .result { font-size: 18px; font-weight: 500; color: blueviolet; }
        .event-log { background: #f8f9fa; padding: 10px; margin: 5px 0; border-left: 3px solid #667eea; font-family: monospace; }
    </style>
</head>
<body>
    <h1>Load Events ใน JavaScript</h1>
    <div class="result" id="log"></div>

    <script>
        const log = document.getElementById("log");
        
        function addLog(eventName, details = "") {
            const time = new Date().toLocaleTimeString("th-TH", { hour12: false });
            log.innerHTML += `
[${time}] ${eventName} ${details}
`; } // 1. DOMContentLoaded - เร็วที่สุด document.addEventListener("DOMContentLoaded", () => { addLog("DOMContentLoaded", "- DOM พร้อม จัดการ Element ได้แล้ว"); initApp(); // เริ่มต้นแอปได้ที่นี่ }); // 2. Load - ช้าที่สุด (รอทุกอย่าง) window.addEventListener("load", () => { addLog("load", "- ทุก Resource โหลดเสร็จ (Images, CSS, Fonts)"); }); // 3. Beforeunload - ก่อนปิดหน้า window.addEventListener("beforeunload", (e) => { // ถ้ามีข้อมูลไม่ได้บันทึก ให้เตือน if (hasUnsavedChanges()) { e.preventDefault(); e.returnValue = ""; // Chrome ต้องการค่านี้ return ""; // Legacy browsers } }); // 4. Unload - ปิดหน้าแล้ว (ไม่สามารถยกเลิกได้) window.addEventListener("unload", () => { // ทำ Cleanup เร็วๆ เช่น send analytics beacon navigator.sendBeacon("/analytics/leave", JSON.stringify({ page: location.pathname })); // ไม่ควรทำ Async operations ที่นี่ (อาจไม่สำเร็จ) }); function initApp() { addLog("App Init", "- เริ่มต้นแอปพลิเคชัน"); } function hasUnsavedChanges() { // ตัวอย่าง: ตรวจสอบ Form Dirty return document.querySelector("form")?.classList.contains("dirty") || false; } </script> </body> </html>

ผลลัพธ์ (ลำดับใน Console)

[10:30:15] DOMContentLoaded - DOM พร้อม จัดการ Element ได้แล้ว
[10:30:15] App Init - เริ่มต้นแอปพลิเคชัน
[10:30:16] load - ทุก Resource โหลดเสร็จ (Images, CSS, Fonts)
... (เวลาผ่านไป ผู้ใช้ปิดแท็บ)
[10:35:22] beforeunload - กำลังจะปิดหน้า
[10:35:22] unload - หน้าถูก Unload แล้ว

ความแตกต่างสำคัญ: DOMContentLoaded vs Load

เหตุการณ์เวลาเหมาะสำหรับ
DOMContentLoadedเร็ว (~100-300ms)เริ่มต้น App, Query DOM, Bind Events
loadช้า (~1-5s+)วัดขนาดรูปภาพ, Layout ที่ต้องรอ CSS/Fonts

Best Practices

  • ✅ ใช้ DOMContentLoaded สำหรับ Initialization หลัก (เร็วกว่า)
  • ✅ ใช้ load เฉพาะต้องการขนาดรูปภาพหรือ Layout ที่พึ่งพา External Resources
  • ✅ ใช้ beforeunload เฉพาะต้องเตือน Unsaved Changes (อย่าลงทะเบียนถ้าไม่จำเป็น - ทำให้ช้า)
  • ✅ ใช้ navigator.sendBeacon() ใน unload สำหรับ Analytics (น่าเชื่อถือกว่า XHR/Fetch)
  • ❌ อย่าทำ Heavy Work ใน Load Events (Blocking)

Script Loading และ Load Events

<!-- Normal: Blocking HTML Parsing -->
<script src="app.js"></script>

<!-- Defer: รอ DOMContentLoaded (แนะนำสำหรับ Module/App) -->
<script src="app.js" defer></script>

<!-- Async: โหลดขนานกัน Execute ทันทีโหลดเสร็จ (ไม่รับประกันลำดับ) -->
<script src="analytics.js" async></script>

<!-- Module: Defer โดยอัตโนมัติ -->
<script type="module" src="app.js"></script>