หัวข้อ 5 · 10 นาที
ใส่ JavaScript ใน HTML
นึกภาพก่อน
HTML คือโครงของบ้าน CSS คือสีและการตกแต่ง JavaScript คือระบบไฟฟ้า: สิ่งที่ทำให้กดสวิตช์แล้วมีอะไรเกิดขึ้น คำถามของบทนี้คือ: จะเดินสายไฟ (JavaScript) เข้าไปในบ้าน (HTML) ที่จุดไหน และเมื่อใดจึงจะจ่ายไฟ
วิธีที่ 1: ใน attribute ของ element
เขียน JavaScript ลงใน attribute onclick ของ element โค้ดจะทำงาน เมื่อผู้ใช้คลิก
<button onclick="alert('Hello')">
Please Click
</button>
<button onclick="console.log('Hi')">
Please Click
</button>
<button onclick="document.getElementById('demo').innerText=Date()">
Please Click
</button>
| โค้ด | ผล |
|---|---|
alert('Hello') | เปิดกล่องข้อความบนหน้าจอ |
console.log('Hi') | พิมพ์ลง console ของ browser (เปิดด้วย DevTools ผู้ใช้ทั่วไปไม่เห็น) |
document.getElementById('demo').innerText=Date() | หา element ที่มี id="demo" แล้วเปลี่ยนข้อความเป็นวันเวลาปัจจุบัน |
สังเกตเครื่องหมายคำพูด: ค่าของ attribute ใช้ "…" ข้อความใน JavaScript ข้างในจึงใช้ '…' เพื่อไม่ให้ชนกัน
วิธีที่ 2: ใน tag script
<script>
alert("Hello");
</script>
โค้ดทำงานทันทีเมื่อ browser อ่านมาถึง tag นี้
วิธีที่ 3: ไฟล์ .js ภายนอก
<script src="script.js"></script>
attribute src ชี้ไปที่ไฟล์ได้สามแบบ:
| รูปแบบ | ความหมาย |
|---|---|
src="script.js" | ไฟล์ในโฟลเดอร์เดียวกับหน้า HTML |
src="js/script.js" | ไฟล์ในโฟลเดอร์ย่อย js |
src="https://example.com" | ไฟล์จากเว็บอื่น (URL เต็ม) |
ข้อดีของไฟล์ภายนอก: ใช้ซ้ำได้หลายหน้า, HTML กับ JavaScript แยกกันอ่านง่าย และ browser cache ไฟล์ไว้ได้
ควรวาง script ที่ใด
browser อ่าน HTML จากบนลงล่าง เมื่อเจอ <script> ธรรมดา จะ หยุดอ่าน HTML ไปโหลดและรัน script ก่อน
ถ้า script อยู่บนสุดและทำงานนาน ผู้ใช้จะเห็นหน้าขาว และ script จะยังมองไม่เห็น element ที่อยู่ถัดลงไป
แบบที่ 1: ใน head พร้อม defer
<head>
<meta charset="UTF-8">
<title>My Web Page</title>
<!-- Link your JS file here -->
<script src="script.js" defer></script>
</head>
attribute
deferป้องกันไม่ให้ script ขวางการโหลดหน้า และรับประกันว่า script จะทำงาน หลังจาก HTML ทั้งหมดถูกโหลดเสร็จแล้ว
แบบที่ 2: ก่อนปิด body
<body>
<h1>Hello World</h1>
<script src="script.js"></script>
</body>
เมื่อ browser อ่านมาถึง script element ทั้งหมดข้างบนถูกสร้างเสร็จแล้ว
| ใน head ไม่มี defer | ใน head + defer | ก่อน </body> | |
|---|---|---|---|
| ขวางการแสดงหน้า | ขวาง | ไม่ขวาง | ไม่ขวาง (อยู่ท้ายแล้ว) |
| script เห็น element ในหน้า | ไม่เห็น | เห็น | เห็น |
ตัวอย่างไล่ทีละขั้น
โจทย์: หน้านี้ทำงานผิด เพราะอะไร และแก้อย่างไร
<html>
<head>
<script>
document.getElementById('demo').innerText = 'Hello';
</script>
</head>
<body>
<p id="demo">...</p>
</body>
</html>
- browser อ่านจากบนลงล่าง เจอ
<script>ใน head → รันทันที - ตอนนั้น browser ยังอ่านไม่ถึง
<p id="demo">element นี้จึงยังไม่มี document.getElementById('demo')คืนnullnull.innerText = …→ error และข้อความไม่เปลี่ยน
วิธีแก้ (เลือกอย่างใดอย่างหนึ่ง):
- ย้าย
<script>ไปไว้ ก่อน</body> - ย้ายโค้ดไปไฟล์
script.jsแล้วใช้<script src="script.js" defer></script>ใน head
จุดที่มักพลาด
1. ใช้เครื่องหมายคำพูดชนิดเดียวกันซ้อนกัน
onclick="alert("Hello")" ผิด ต้องสลับ: onclick="alert('Hello')"
2. คิดว่า console.log แสดงบนหน้าเว็บ
แสดงใน console ของ DevTools
3. คิดว่า defer ทำให้ script ไม่ถูกรัน
รัน แต่ หลัง HTML โหลดเสร็จ
4. วาง script ธรรมดาใน head แล้วเรียก element
element ยังไม่ถูกสร้าง
5. ใส่โค้ดระหว่าง tag ของ script ที่มี src
<script src="a.js">โค้ด</script> โค้ดข้างในถูกละเลย
ที่มา: HTML JavaScript.pdf หน้า 1–10