ปูพื้นฐานการเขียนเว็บด้วย HTML, CSS และ JavaScript
เรียนรู้การสร้างหน้าเว็บด้วย HTML และ CSS แล้วต่อยอดด้วยพื้นฐาน JavaScript ผ่านตัวอย่างบน React และ Next.js
บทความนี้จะพาคุณเริ่มต้นสร้างหน้าเว็บทีละขั้น จาก HTML สำหรับวางโครงสร้างและเนื้อหา ต่อด้วย CSS สำหรับตกแต่งและจัดวางองค์ประกอบ แล้วเรียนรู้พื้นฐาน JavaScript ผ่านตัวอย่างบน React/Next.js เพื่อแสดงข้อมูลและเลือกเนื้อหาตามเงื่อนไข
เนื้อหาแบ่งเป็น 3 ส่วน โดยแต่ละส่วนต่อยอดจากสิ่งที่ได้เรียนรู้ก่อนหน้า:
- ส่วนที่ 1 — HTML: สร้างโครงสร้างหน้าเว็บด้วยหัวข้อ ลิงก์ รูปภาพ รายการ ตาราง และแบบฟอร์ม
- ส่วนที่ 2 — CSS: เรียนรู้การใส่สไตล์ทั้ง 3 แบบ การใช้ class การสร้างแถบนำทาง และการจัดวางด้วย Flexbox
- ส่วนที่ 3 — JavaScript กับ Next.js: ทำความรู้จัก React component และใช้พื้นฐาน JavaScript เพื่อแสดงข้อมูลบนหน้าเว็บ
ส่วนที่ 1: พื้นฐาน HTML#
1.1 HTML คืออะไร?#
HTML (HyperText Markup Language) เป็นภาษามาร์กอัปที่ใช้กำหนดโครงสร้างและความหมายของเนื้อหาบนหน้าเว็บ โดยนำองค์ประกอบต่าง ๆ ที่เรียกว่า element เช่น หัวข้อ ย่อหน้า และรูปภาพ มาประกอบกันเป็นหน้าเว็บ
1.2 เตรียมเครื่องมือและตั้งค่าโปรเจกต์#
ข้อกำหนดเบื้องต้น: ติดตั้ง VS Code จาก code.visualstudio.com ↗
VS Code เป็นโปรแกรมแก้ไขโค้ดที่เราจะใช้สร้างและแก้ไขไฟล์ตลอดบทความ เริ่มจากสร้างโฟลเดอร์สำหรับเก็บงาน แล้วเปิดโฟลเดอร์นั้นใน VS Code ด้วยคำสั่งด้านล่าง
การตั้งค่าโปรเจกต์
# สร้างโฟลเดอร์สำหรับโปรเจกต์
mkdir web-basics
cd web-basics
# สร้างโฟลเดอร์สำหรับไฟล์ HTML
mkdir 01_html
cd 01_html
# เปิด VS Code ในโฟลเดอร์ปัจจุบัน
code .bash1.3 โครงสร้างพื้นฐานของ HTML#
ใน VS Code ให้สร้างไฟล์ชื่อ index.html พิมพ์ html:5 แล้วกด Enter/Tab เพื่อสร้างโครงสร้าง HTML เริ่มต้น:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Website</title>
</head>
<body>
</body>
</html>htmlโดยทั่วไป element ประกอบด้วยแท็กเปิด (opening tag) เนื้อหา (content) และแท็กปิด (closing tag) แต่บาง element เช่น <img> ไม่มีแท็กปิด ส่วนแอตทริบิวต์ (attribute) ใช้ระบุข้อมูลเพิ่มเติมในแท็กเปิด โดยมักเขียนเป็นคู่ของชื่อและค่า ดังภาพ:

องค์ประกอบพื้นฐานของ HTML
| Element | คำอธิบาย |
|---|---|
<!DOCTYPE html> | ประกาศว่าเอกสารนี้เป็น HTML5 |
<html> | รากของเอกสาร HTML |
<head> | บรรจุข้อมูลเมตาดาต้า (ไม่แสดงบนหน้าเว็บ) |
<title> | กำหนดชื่อหน้าเว็บ แสดงที่แถบชื่อเบราว์เซอร์ |
<body> | บรรจุเนื้อหาที่แสดงบนหน้าเว็บ |
<h1> - <h6> | หัวข้อ 6 ระดับ โดย <h1> เป็นหัวข้อระดับหลัก |
<p> | ย่อหน้าข้อความ |
<a href="URL"> | ลิงก์ไปยังหน้าเว็บอื่น |
<img src="..." alt="..."> | แทรกรูปภาพ |
1.4 แสดงตัวอย่างหน้าเว็บใน VS Code#
หากต้องการดูตัวอย่างหน้าเว็บโดยไม่ต้องเปิดเบราว์เซอร์แยก ให้คลิกขวาที่ไฟล์ index.html แล้วเลือก Open in Integrated Browser:

จากนั้นจะเห็นตัวอย่างหน้าเว็บภายใน VS Code ดังภาพ:

1.5 หัวข้อและย่อหน้า#
แท็ก <h1> ถึง <h6> ใช้กำหนดลำดับของหัวข้อ (heading) เริ่มจาก <h1> สำหรับหัวข้อหลัก ไปจนถึง <h6> สำหรับหัวข้อย่อยระดับลึก ในตัวอย่างนี้เราจะใช้ <h1> เป็นชื่อหลักของหน้า และใช้ <h2> แบ่งเนื้อหาออกเป็นหมวด ส่วนแท็ก <p> ใช้เขียนข้อความแต่ละย่อหน้า
เพิ่มหัวข้อและย่อหน้าต่อไปนี้ภายใน <body> ของไฟล์ index.html:
<body>
<h1>Karn Yongsiriwit</h1>
<p>Welcome to my website</p>
<h2>News</h2>
<p>Read the latest news from our website</p>
<h2>Events</h2>
<p>We have many upcoming events</p>
</body>html
1.6 ลิงก์ (Anchor Tag)#
เมื่อมีเนื้อหาบนหน้าเว็บแล้ว เราสามารถใช้แท็ก <a> (anchor) สร้างลิงก์ไปยังหน้าอื่น โดยระบุปลายทางในแอตทริบิวต์ href ตัวอย่างนี้มีทั้งลิงก์ภายใน (internal link) ที่ใช้พาธ about.html เพื่อเปิดไฟล์ในโฟลเดอร์เดียวกัน และลิงก์ภายนอก (external link) ที่ใช้ URL เต็ม เช่น https://melivecode.com เพื่อเปิดเว็บไซต์อื่น
สร้างไฟล์ชื่อ about.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About</title>
</head>
<body>
<h1>About Me</h1>
</body>
</html>htmlใน index.html เพิ่มลิงก์สำหรับหน้าเว็บภายในและภายนอก:
<!-- Internal link -->
<a href="about.html">About Us</a>
<!-- External link -->
<a href="https://melivecode.com">Visit MeLiveCode</a>html
1.7 รูปภาพ#
นอกจากข้อความและลิงก์แล้ว เรายังเพิ่มรูปภาพด้วยแท็ก <img> ได้ โดยระบุตำแหน่งรูปในแอตทริบิวต์ src ซึ่งอาจเป็นพาธของไฟล์ในโปรเจกต์ เช่น cat_meme.jpg หรือ URL ของรูปบนอินเทอร์เน็ต ส่วน alt ใช้เขียนข้อความอธิบายรูปสำหรับผู้ที่มองไม่เห็นภาพหรือเมื่อโหลดรูปไม่สำเร็จ และใช้ width กับ height กำหนดขนาดที่แสดง:
<!-- Local image -->
<img src="cat_meme.jpg" alt="A funny cat" width="100px" height="150px" />
<!-- Image from the internet -->
<img src="https://melivecode.com/img/logo.png" alt="A bear writing code" height="150px" />html
1.8 รายการ (Lists)#
เมื่อมีข้อมูลหลายรายการ ให้เลือกรูปแบบตามความหมายของข้อมูล หากลำดับไม่สำคัญ ใช้ <ul> เพื่อสร้างรายการแบบไม่มีลำดับ (unordered list) ซึ่งปกติแสดงเป็นจุดนำหน้า แต่หากเป็นขั้นตอนหรือข้อมูลที่ลำดับมีความหมาย ใช้ <ol> เพื่อสร้างรายการแบบมีลำดับ (ordered list) ซึ่งปกติแสดงเป็นตัวเลข ทั้งสองแบบใช้ <li> (list item) ครอบแต่ละรายการ:
<!-- Unordered list -->
<ul>
<li>A new teacher joined the team</li>
<li>Heavy rain in the city</li>
<li>Weekend market opens downtown</li>
</ul>
<!-- Ordered list -->
<ol>
<li>Welcome event</li>
<li>National holiday</li>
<li>Semester break</li>
</ol>html| แท็ก | คำอธิบาย |
|---|---|
<ul> | รายการไม่มีลำดับ (bullet points) |
<ol> | รายการมีลำดับ (ตัวเลข) |
<li> | รายการย่อย |

1.9 ตาราง (Tables)#
สำหรับข้อมูลที่ต้องอ่านเทียบกันเป็นแถวและคอลัมน์ ให้ใช้แท็ก <table> โดยสร้างแต่ละแถวด้วย <tr> (table row) ใช้ <th> (table header) สำหรับช่องหัวตาราง และใช้ <td> (table data) สำหรับช่องข้อมูล โดยปกติเบราว์เซอร์จะแสดงข้อความใน <th> เป็นตัวหนาและจัดกึ่งกลาง
สร้างไฟล์ชื่อ table.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Table</title>
</head>
<body>
<table>
<tr>
<th>Name</th>
<th>Age</th>
<th>City</th>
</tr>
<tr>
<td>Karn Yong</td>
<td>30</td>
<td>Bangkok</td>
</tr>
<tr>
<td>Parkpoom Beer</td>
<td>25</td>
<td>Chiang Mai</td>
</tr>
</table>
</body>
</html>html| แท็ก | คำอธิบาย |
|---|---|
<table> | กำหนดขอบเขตของตาราง |
<tr> | แถวของตาราง (table row) |
<th> | ช่องหัวตาราง (table header) |
<td> | ช่องข้อมูล (table data) |
คลิกขวาที่ไฟล์ table.html แล้วเลือก Open in Integrated Browser (ดูหัวข้อ 1.4) เพื่อดูผลลัพธ์:

1.10 แบบฟอร์ม (Forms)#
แท็ก <form> ใช้จัดกลุ่มช่องรับข้อมูลจากผู้ใช้ เช่น ชื่อผู้ใช้และรหัสผ่าน พร้อมกำหนดปลายทางสำหรับส่งข้อมูลไปประมวลผล ตัวอย่างต่อไปนี้เป็นโครงสร้างหน้าเข้าสู่ระบบ
สร้างไฟล์ชื่อ login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form action="login.php" method="POST">
<label for="username">Username:</label>
<input type="text" id="username" name="username" />
<br />
<label for="password">Password:</label>
<input type="password" id="password" name="password" />
<br />
<input type="checkbox" id="remember" name="remember" />
<label for="remember">Remember me</label>
<br/>
<input type="submit" value="Login" />
</form>
</body>
</html>html
องค์ประกอบของแบบฟอร์ม
| Element | วัตถุประสงค์ |
|---|---|
<form action=""> | ครอบองค์ประกอบของแบบฟอร์ม โดย action ระบุปลายทางที่รับข้อมูล |
<label for="id"> | ระบุข้อความกำกับช่องรับข้อมูล และเชื่อมกับช่องนั้นผ่านค่า id |
<input> | สร้างช่องรับข้อมูลหรือปุ่มตามชนิด เช่น text, password, checkbox และ submit |
id attribute | ระบุองค์ประกอบ เพื่อให้ for ของ label อ้างถึงได้ |
name attribute | กำหนดชื่อที่ใช้ส่งค่าของช่องรับข้อมูล |
หมายเหตุ: สำหรับ HTML elements และตัวอย่างเพิ่มเติม สามารถดูได้ที่ W3Schools HTML ↗
ส่วนที่ 2: พื้นฐาน CSS#
2.1 CSS คืออะไร?#
เมื่อ HTML กำหนดโครงสร้างและเนื้อหาแล้ว เราจะใช้ CSS (Cascading Style Sheets) จัดการรูปลักษณ์ของหน้าเว็บ เช่น สีพื้นหลัง แบบอักษร ระยะห่าง และตำแหน่งขององค์ประกอบ
2.2 การตั้งค่าโปรเจกต์#
# เข้าไปที่โฟลเดอร์โปรเจกต์
cd web-basics
# สร้างโฟลเดอร์สำหรับไฟล์ CSS
mkdir 02_css
cd 02_css
# เปิด VS Code ในโฟลเดอร์ปัจจุบัน
code .bashใน VS Code สร้างไฟล์ชื่อ index.html พิมพ์ html:5 แล้วกด Enter/Tab เพื่อสร้างโครงสร้าง HTML เริ่มต้น:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Practice</title>
</head>
<body>
</body>
</html>html2.3 วิธีใส่ CSS มี 3 แบบ#
เราสามารถเพิ่ม CSS ให้หน้าเว็บได้ 3 วิธี ได้แก่ inline สำหรับกำหนดสไตล์เฉพาะองค์ประกอบ, internal สำหรับเขียนสไตล์ไว้ในหน้าเดียวกัน และ external สำหรับแยกสไตล์เป็นอีกไฟล์

1. Inline CSS
กำหนดสไตล์ให้ element โดยตรงผ่านแอตทริบิวต์ style ดังตัวอย่างที่เปลี่ยนสีพื้นหลังและสีหัวข้อ:
<body style="background-color: beige;">
<h1 style="color: darkblue;">Hello World</h1>
</body>html2. Internal CSS (Style Element)
เขียนกฎ CSS ไว้ในแท็ก <style> ภายใน <head> เพื่อรวมสไตล์ของหน้านั้นไว้ในจุดเดียว:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Styled Page</title>
<style>
body {
background-color: beige;
}
h1 {
color: darkblue;
font-size: 32px;
}
</style>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>html3. External CSS (แนะนำ)
แยก CSS ไว้ในไฟล์ style.css แล้วเชื่อมกับ HTML ด้วยแท็ก <link> วิธีนี้ช่วยให้แก้ไขสไตล์ได้สะดวกและใช้ไฟล์เดียวร่วมกันได้หลายหน้า เราจะใช้วิธีนี้ในตัวอย่างถัดไป
ไฟล์: style.css
body {
background-color: beige;
margin: 0;
}
h1 {
color: darkblue;
}cssไฟล์: index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Styled Page</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>Hello World</h1>
</body>
</html>html
2.4 รูปแบบของ CSS Rule#
จากตัวอย่างก่อนหน้า กฎ CSS แต่ละชุดเริ่มด้วย selector เพื่อเลือกองค์ประกอบ แล้วกำหนดคู่ property: value ภายในวงเล็บปีกกา ดังนี้:
selector {
property: value;
property: value;
}css
| ส่วน | คำอธิบาย |
|---|---|
selector | เลือก HTML elements ที่จะใช้สไตล์ (element, class, หรือ id) |
property | คุณสมบัติที่ต้องการกำหนด (background-color, color, font-size, margin, padding) |
value | ค่าของคุณสมบัตินั้น (aqua, #FF0000, 16px) |
หมายเหตุ: สำหรับอ้างอิง CSS properties สามารถดูได้ที่ W3Schools CSS Reference ↗
2.5 CSS Classes และ Div Elements#
เมื่อหลายองค์ประกอบต้องใช้สไตล์เดียวกัน เราสามารถกำหนด class ให้กับองค์ประกอบเหล่านั้น แล้วใช้ CSS class selector เลือกตกแต่งพร้อมกันได้ ตัวอย่างนี้ใช้ class box กับ <div> สองกล่อง
ทำต่อในไฟล์เดิมจากหัวข้อก่อนหน้า โดย เพิ่ม โค้ดด้านล่างเข้าไป ส่วนคอมเมนต์ ...existing... ใช้แทนโค้ดเดิมที่ต้องเก็บไว้ ไม่ต้องคัดลอกคอมเมนต์นี้ไปแทนเนื้อหาเดิม
ไฟล์: style.css
/* ...existing styles... */
.box {
border: 2px solid brown;
width: 200px;
padding: 10px;
margin: 10px;
}cssไฟล์: index.html
<body>
<!-- ...existing content... -->
<div class="box">
<h1>Box 1</h1>
<p>This is the content of box 1</p>
</div>
<div class="box">
<h1>Box 2</h1>
<p>This is the content of box 2</p>
</div>
</body>html
| Concept | คำอธิบาย |
|---|---|
<div> | คอนเทนเนอร์ทั่วไปสำหรับรวม elements เข้าด้วยกัน |
.classname | CSS class selector (เริ่มต้นด้วยจุด) |
#idname | CSS ID selector (เริ่มต้นด้วยเครื่องหมาย #) |
2.6 แถบนำทาง (Navigation Bar)#
ต่อไปเราจะนำ <ul> และ <li> มาสร้างแถบนำทาง โดย เพิ่ม CSS ลงในไฟล์เดิม และวางรายการลิงก์ไว้ตอนต้นของ <body> ส่วนคอมเมนต์ ...existing... ใช้แทนโค้ดเดิมที่ต้องเก็บไว้
ไฟล์: style.css
/* ...existing styles... */
.navMenu {
list-style-type: none;
margin: 0;
padding: 0;
background-color: darkgreen;
overflow: hidden;
}
.navItem {
float: left;
}
.navItem a {
color: white;
text-decoration: none;
display: block;
padding: 14px 16px;
text-align: center;
}
.navItem a:hover {
background-color: #115511;
}cssไฟล์: index.html
<body>
<!-- Add the navigation bar at the top of the body -->
<ul class="navMenu">
<li class="navItem"><a href="index.html">Home</a></li>
<li class="navItem"><a href="about.html">About Us</a></li>
<li class="navItem"><a href="contact.html">Contact</a></li>
</ul>
<!-- ...existing content... -->
</body>html
คำอธิบายคุณสมบัติ CSS
| Property | Value | คำอธิบาย |
|---|---|---|
list-style-type | none | ลบ bullet points ออกจากรายการ |
margin | 0 | ลบระยะห่างภายนอก |
padding | 0 | ลบระยะห่างภายใน |
background-color | darkgreen | กำหนดสีพื้นหลัง |
overflow | hidden | ครอบ elements ที่ลอยอยู่ภายใน parent |
float | left | วางรายการแนวนอน |
text-decoration | none | ลบเส้นใต้ลิงก์ |
display | block | ทำให้ทั้งพื้นที่คลิกได้ |
2.7 Flexbox Layout#
หลังจากจัดแถบนำทางด้วย float แล้ว เราจะลองใช้ Flexbox เพื่อจัดเรียงการ์ด Flexbox เป็นระบบจัดวางของ CSS ที่เรียงองค์ประกอบเป็นแถวหรือคอลัมน์ได้ เมื่อกำหนด display: flex องค์ประกอบนั้นจะเป็น flex container และองค์ประกอบลูกโดยตรงจะเป็น flex items ซึ่งเราสามารถกำหนดการแบ่งพื้นที่ การจัดกึ่งกลาง และระยะห่างได้

Responsive คือการออกแบบให้หน้าเว็บปรับการแสดงผลตามขนาดหน้าจอ ในตัวอย่างนี้
flex-wrap: wrapช่วยให้การ์ดขึ้นบรรทัดใหม่เมื่อพื้นที่ในแถวไม่พอ
สร้างไฟล์ใหม่ สองไฟล์ในโฟลเดอร์เดิม ชื่อ flexbox.css และ flexbox.html สำหรับทดลองจัดวางการ์ดตามตัวอย่างด้านล่าง
ไฟล์: flexbox.css
body {
background-color: beige;
margin: 0;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
padding: 20px;
}
.card {
width: 200px; /* set an equal width for every card */
border: 1px solid #ccc;
border-radius: 8px;
padding: 10px;
text-align: center;
background-color: white;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
/* no margin needed — the container uses gap for spacing */
}
.card img {
width: 100%;
height: 140px; /* height is required for object-fit to work */
object-fit: cover;
border-radius: 4px;
}cssไฟล์: flexbox.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flexbox Cards</title>
<link rel="stylesheet" href="flexbox.css" />
</head>
<body>
<h1>Popular Attractions</h1>
<div class="container">
<div class="card">
<img src="https://www.melivecode.com/attractions/1.jpg" alt="Phi Phi Islands" />
<h2>Phi Phi Islands</h2>
</div>
<div class="card">
<img src="https://www.melivecode.com/attractions/2.jpg" alt="Eiffel Tower" />
<h2>Eiffel Tower</h2>
</div>
<div class="card">
<img src="https://www.melivecode.com/attractions/3.jpg" alt="Times Square" />
<h2>Times Square</h2>
</div>
<div class="card">
<img src="https://www.melivecode.com/attractions/4.jpg" alt="Mount Fuji" />
<h2>Mount Fuji</h2>
</div>
</div>
</body>
</html>htmlเปิดไฟล์ flexbox.html ในเบราว์เซอร์ แล้วลองย่อและขยายหน้าต่างเพื่อสังเกตว่าการ์ดจัดเรียงใหม่อย่างไรเมื่อพื้นที่เปลี่ยนไป

คุณสมบัติ Flexbox
| Property | คำอธิบาย |
|---|---|
display: flex | ทำให้ element เป็น flex container |
flex-wrap: wrap | อนุญาตให้ items ขึ้นบรรทัดใหม่ |
justify-content: center | จัด items กึ่งกลางตามแกนหลัก ซึ่งเป็นแนวนอนในตัวอย่างนี้ |
gap | เพิ่มระยะห่างระหว่าง flex items |
หมายเหตุ: สำหรับคำอธิบาย Flexbox อย่างละเอียด ดูได้ที่ CSS-Tricks Flexbox Guide ↗
ส่วนที่ 3: JavaScript กับ Next.js#
3.1 Next.js คืออะไร?#
- React.js เป็นไลบรารี JavaScript สำหรับสร้างส่วนติดต่อผู้ใช้ โดยแบ่งหน้าเว็บเป็นส่วนย่อยที่เรียกว่า component
- Next.js เป็นเฟรมเวิร์กที่ต่อยอดจาก React ช่วยจัดโครงสร้างเว็บแอปพลิเคชัน ในส่วนนี้เราจะใช้เป็นพื้นฐานสำหรับทดลองเขียน JavaScript และแสดงผลผ่าน React
- Node.js เป็นสภาพแวดล้อมสำหรับรัน JavaScript นอกเบราว์เซอร์ ซึ่งเราจะใช้รันเครื่องมือและเซิร์ฟเวอร์ระหว่างพัฒนาโปรเจกต์
3.2 การติดตั้ง Node.js#
ข้อกำหนดเบื้องต้น: ติดตั้ง Node.js (LTS) จาก nodejs.org ↗
บน Linux (Ubuntu) แนะนำให้ติดตั้งผ่าน nvm (Node Version Manager):
# ดาวน์โหลดและติดตั้ง nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.7/install.sh | bash
# โหลด nvm เข้า shell ปัจจุบัน (แทนการเปิด terminal ใหม่)
\. "$HOME/.nvm/nvm.sh"
# ดาวน์โหลดและติดตั้ง Node.js
nvm install 24
# ตรวจสอบเวอร์ชัน Node.js
node -v # ควรแสดง "v24.20.0"
# ตรวจสอบเวอร์ชัน npm
npm -v # ควรแสดง "11.19.0"bash3.3 สร้างโปรเจกต์ Next.js#
# เข้าไปที่โฟลเดอร์โปรเจกต์
cd web-basics
# สร้างโปรเจกต์ Next.js ใหม่ (--js บังคับใช้ JavaScript แทน TypeScript)
npx create-next-app@16 03_js_nextjs --js
# ครั้งแรกจะถามให้ติดตั้งแพ็กเกจ ให้พิมพ์ y แล้วกด Enter:
# Need to install the following packages:
# create-next-app@16.3.4
# Ok to proceed? (y) y
# หมายเหตุ: Next.js 16 จะไม่ถามตัวเลือกทีละข้อเหมือนเวอร์ชันก่อน
# แต่จะใช้ค่าเริ่มต้นให้เลย ได้แก่ ESLint, Tailwind CSS, App Router,
# ไม่มีโฟลเดอร์ src/ และ import alias "@/*"
# เข้าไปในโปรเจกต์
cd 03_js_nextjs
# เปิด VS Code ในโฟลเดอร์ปัจจุบัน
code .bashเมื่อเปิดโปรเจกต์ใน VS Code ด้วย code . แล้ว ให้เริ่มเซิร์ฟเวอร์สำหรับพัฒนา (development server) ตามขั้นตอนต่อไปนี้ เพื่อเปิดดูหน้าเว็บระหว่างเขียนโค้ด
1. เปิด Terminal ใน VS Code — จากเมนู Terminal → New Terminal (หรือกดคีย์ลัด Ctrl+Shift+`)

2. เลือก Command Prompt (สำหรับ Windows) — หาก Terminal เปิดขึ้นมาเป็น PowerShell ให้กดลูกศร ∨ ข้างปุ่ม + มุมขวาบนของ Terminal แล้วเลือก Command Prompt เพื่อให้คำสั่งทำงานตรงกับตัวอย่างในบทความ

3. รัน npm run dev — พิมพ์คำสั่งต่อไปนี้แล้วกด Enter
npm run devbashเมื่อ server พร้อมใช้งานจะแสดงลิงก์ Local: http://localhost:3000 กด Ctrl ค้างแล้วคลิกที่ลิงก์ VS Code จะเปิดเบราว์เซอร์ในตัว (Simple Browser) แสดงหน้าแอปขึ้นมาทันทีโดยไม่ต้องออกจาก VS Code

3.4 ส่วนเสริม VS Code ที่แนะนำ#
ติดตั้งส่วนเสริม ES7+ React/Redux/React-Native snippets เพื่อใช้คำย่อช่วยสร้างโค้ด React ใน VS Code และลดการพิมพ์โครงสร้างที่ใช้ซ้ำ
3.5 โครงสร้าง React Component#
ในโปรเจกต์ Next.js ที่ใช้ App Router เราจะเขียนหน้าเว็บเป็น React component ภายในโฟลเดอร์ app เริ่มจากแก้ไข app/page.js ซึ่งเป็นหน้าหลัก ให้แสดงข้อความต้อนรับตามตัวอย่าง
ไฟล์: app/page.js
เคล็ดลับ: ใช้คำย่อ
rfcจากส่วนเสริม ES7+ React snippets แล้วกด Enter เพื่อสร้างโครง React component จากนั้นปรับโค้ดให้ตรงกับตัวอย่างด้านล่าง

export default function Page() {
return (
<div>
<div className='box'>
<h1>Hello World, Next.js</h1>
<p>Welcome to React!</p>
</div>
</div>
)
}javascript
แนวคิดสำคัญ
| Concept | คำอธิบาย |
|---|---|
export default | ส่งออก component หลักของไฟล์เพื่อนำไปใช้งาน |
function Component() | ประกาศฟังก์ชันที่ทำหน้าที่เป็น React component |
return (...) | คืนค่า JSX ที่อธิบายส่วนติดต่อผู้ใช้ |
className | ระบุ CSS class ให้กับองค์ประกอบใน JSX |
| JSX | ส่วนขยายไวยากรณ์ของ JavaScript สำหรับเขียนมาร์กอัปที่มีหน้าตาคล้าย HTML |
หมายเหตุ: เมื่อเขียน JSX ให้ใช้
classNameแทนแอตทริบิวต์classที่คุ้นเคยจาก HTML เพื่อเชื่อมองค์ประกอบกับ CSS class
3.6 การเพิ่ม CSS#
ไฟล์: app/style.css
.box {
border: 2px solid brown;
width: 200px;
padding: 10px;
margin: 10px;
background-color: beige;
}cssไฟล์: app/layout.js
import './style.css'
export const metadata = {
title: 'Next.js Tutorial',
description: 'Learn JavaScript with Next.js',
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}javascript
พื้นฐาน JavaScript ใน React/Next.js — เมื่อสร้าง component และเพิ่ม CSS ได้แล้ว เราจะเริ่มนำข้อมูลมาแสดงบนหน้าเว็บ ตั้งแต่ตัวแปรไปจนถึงการกรองข้อมูล แต่ละหัวข้อให้สร้างไฟล์ page.js ในโฟลเดอร์ย่อยภายใต้ app/ แล้วเปิด URL ที่ระบุขณะเซิร์ฟเวอร์ยังทำงาน
3.7 ตัวแปร (Variables)#
สร้างไฟล์ app/01_var/page.js — เข้าถึงที่ http://localhost:3000/01_var ↗
export default function VarPage() {
const name = "Karn";
let age = 25;
const isStudent = true;
return (
<div>
<h1>Variables</h1>
<p>Name: {name}</p>
<p>Age: {age}</p>
<p>Student: {isStudent ? "Yes" : "No"}</p>
</div>
);
}javascript
| Keyword | การใช้งาน |
|---|---|
var | รูปแบบเดิมที่มีขอบเขตต่างจาก let และ const; ในตัวอย่างนี้ให้เลือกใช้สองแบบหลัง |
let | ใช้เมื่อต้องกำหนดค่าใหม่ให้ตัวแปรภายหลัง |
const | ใช้เมื่อไม่ต้องกำหนดค่าใหม่ให้ตัวแปร แต่ยังแก้ไขสมาชิกของอาร์เรย์หรือคุณสมบัติของออบเจกต์ได้ |
3.8 อาร์เรย์ (Arrays)#
สร้างไฟล์ app/02_array/page.js — เข้าถึงที่ http://localhost:3000/02_array ↗
อาร์เรย์ใช้เก็บข้อมูลหลายรายการไว้ด้วยกัน ในตัวอย่างนี้เราใช้เมธอด map() แปลงสมาชิกแต่ละตัวเป็น JSX element แล้วนำรายการที่ได้มาแสดงบนหน้าเว็บ:

export default function ArrayPage() {
const fruits = ["Orange", "Banana", "Mango", "Strawberry"];
return (
<div>
<h1>Arrays</h1>
<ul>
{fruits.map((fruit, index) => (
<li key={index}>{fruit}</li>
))}
</ul>
</div>
);
}javascript
หมายเหตุ: แต่ละรายการที่สร้างด้วย
map()ควรมี propkeyที่คงที่และไม่ซ้ำกันในกลุ่ม เพื่อให้ React ระบุรายการเดิมได้เมื่อข้อมูลเปลี่ยนลำดับ มีการเพิ่ม หรือลบรายการ
3.9 ออบเจกต์ (Objects)#
สร้างไฟล์ app/03_object/page.js — เข้าถึงที่ http://localhost:3000/03_object ↗
export default function ObjectPage() {
const user = {
name: "Karn Yongsiriwit",
role: "Developer",
country: "Thailand"
};
return (
<div>
<h1>Objects</h1>
<p>Name: {user.name}</p>
<p>Role: {user.role}</p>
<p>Country: {user.country}</p>
</div>
);
}javascript
ออบเจกต์ใช้เก็บข้อมูลที่เกี่ยวข้องกันเป็นคู่ชื่อและค่า (key-value) เช่น ชื่อ บทบาท และประเทศของผู้ใช้ เราอ่านค่าของแต่ละคุณสมบัติได้ด้วย dot notation เช่น user.name แล้วใส่ไว้ใน {} เพื่อแสดงใน JSX
3.10 อาร์เรย์ของออบเจกต์ (Array of Objects)#
สร้างไฟล์ app/04_array_objects/page.js — เข้าถึงที่ http://localhost:3000/04_array_objects ↗
export default function ArrayObjectsPage() {
const attractions = [
{ id: 1, name: "Phi Phi Islands", country: "Thailand" },
{ id: 2, name: "Eiffel Tower", country: "France" },
{ id: 3, name: "Times Square", country: "USA" },
{ id: 4, name: "Mount Fuji", country: "Japan" }
];
return (
<div>
<h1>Array of Objects</h1>
{attractions.map((attraction) => (
<div key={attraction.id} style={{ border: "1px solid #ccc", margin: "10px", padding: "10px" }}>
<h2>{attraction.name}</h2>
<p>Country: {attraction.country}</p>
</div>
))}
</div>
);
}javascript
เมื่อนำอาร์เรย์และออบเจกต์มาใช้ร่วมกัน เราจะเก็บข้อมูลหลายรายการที่แต่ละรายการมีหลายคุณสมบัติได้ ตัวอย่างนี้เก็บสถานที่ท่องเที่ยวเป็นอาร์เรย์ของออบเจกต์ แล้วใช้ map() สร้างกล่องแสดงชื่อและประเทศของแต่ละสถานที่ โดยใช้ id เป็น key
3.11 ฟังก์ชัน (Functions)#
สร้างไฟล์ app/05_function/page.js — เข้าถึงที่ http://localhost:3000/05_function ↗
export default function FunctionPage() {
// Function Declaration — add two numbers
function add(a, b) {
return a + b;
}
// Function Expression — assign a function to a variable
const square = function (n) {
return n * n;
};
// Arrow Function — multiply two numbers
const multiply = (a, b) => {
return a * b;
};
// Arrow Function (implicit return) — a short one-liner
const subtract = (a, b) => a - b;
// check whether the person is an adult
const isAdult = (age) => {
return age >= 18;
};
// build a greeting message
const greet = (name, timeOfDay) => {
return `Good ${timeOfDay}, ${name}!`;
};
return (
<div>
<h1>Functions</h1>
<h2>Basic Calculations</h2>
<p>5 + 3 = {add(5, 3)}</p>
<p>7 × 7 = {square(7)}</p>
<p>4 × 6 = {multiply(4, 6)}</p>
<p>10 - 4 = {subtract(10, 4)}</p>
<h2>Conditional Logic</h2>
<p>Age 20 is adult: {isAdult(20) ? "Yes" : "No"}</p>
<p>Age 15 is adult: {isAdult(15) ? "Yes" : "No"}</p>
<h2>Template Strings</h2>
<p>{greet("Karn", "morning")}</p>
<p>{greet("Somchai", "evening")}</p>
</div>
);
}javascript
รูปแบบฟังก์ชัน
| Type | Syntax | Use Case |
|---|---|---|
| Function Declaration | function name() {} | ประกาศฟังก์ชันที่เรียกใช้ก่อนบรรทัดประกาศได้ภายในขอบเขตเดียวกัน |
| Function Expression | const name = function() {} | เก็บฟังก์ชันไว้ในตัวแปรเพื่อเรียกใช้ภายหลัง |
| Arrow Function | const name = () => {} | เขียนฟังก์ชันด้วยรูปแบบกระชับ เช่น ฟังก์ชันที่ส่งให้ map() |
| Arrow (Implicit Return) | const name = () => value | คืนค่าจากนิพจน์โดยไม่ต้องเขียนวงเล็บปีกกาหรือ return |
การตั้งชื่อฟังก์ชัน
| Convention | Rule | ตัวอย่างที่แนะนำ | ตัวอย่างที่ไม่ตรงแนวทาง |
|---|---|---|---|
| camelCase | ขึ้นต้นคำแรกด้วยตัวพิมพ์เล็ก และขึ้นต้นคำถัดไปด้วยตัวพิมพ์ใหญ่ | getUserData, calculateTotal, isValid | GetUserData, get_user_data |
| Verb-first | เริ่มด้วยคำกริยาที่อธิบายการกระทำ | fetchUser, saveData, deleteItem | user, data, item |
| Booleans | ใช้คำนำหน้า is, has, can, should | isLoggedIn, hasPermission, canEdit | logged, permission, editable |
ตัวอย่างเพิ่มเติม: ฟังก์ชันกับ map()
เราสามารถแยกงานที่ใช้ซ้ำออกเป็นฟังก์ชัน แล้วเรียกใช้ระหว่างแสดงรายการด้วย map() ได้ ตัวอย่างนี้แยกการคำนวณส่วนลดและการจัดรูปแบบราคาออกจากส่วนที่สร้างหน้าตาของรายการสินค้า:
export default function FunctionMapPage() {
const products = [
{ id: 1, name: "Laptop", price: 25000 },
{ id: 2, name: "Mouse", price: 500 },
{ id: 3, name: "Keyboard", price: 1500 }
];
// calculate the price after a 10% discount
const calculateDiscount = (price) => {
return price * 0.9;
};
// format as currency
const formatCurrency = (amount) => {
return `฿${amount.toLocaleString()}`;
};
return (
<div>
<h1>Functions with Arrays</h1>
<h2>Product Prices (after 10% discount)</h2>
{products.map((product) => (
<div key={product.id} style={{ border: "1px solid #ccc", margin: "10px", padding: "10px" }}>
<h3>{product.name}</h3>
<p>Original price: {formatCurrency(product.price)}</p>
<p>Discounted price: {formatCurrency(calculateDiscount(product.price))}</p>
</div>
))}
</div>
);
}javascript
เคล็ดลับ: ลองแยกงานแต่ละอย่างเป็นฟังก์ชันเล็ก ๆ ที่มีหน้าที่ชัดเจน เช่น คำนวณราคาหรือจัดรูปแบบข้อความ วิธีนี้ช่วยให้นำโค้ดกลับมาใช้ซ้ำและอ่าน component ได้ง่ายขึ้น
3.12 การแสดงผลตามเงื่อนไข (Conditional Rendering)#
สร้างไฟล์ app/06_condition/page.js — เข้าถึงที่ http://localhost:3000/06_condition ↗
นอกจากแสดงข้อมูลแล้ว เรายังเลือกเนื้อหาตามเงื่อนไขได้ ตัวอย่างนี้ใช้ && เพื่อแสดงข้อความเมื่อเงื่อนไขเป็นจริง และใช้ ternary ? : เพื่อเลือกแสดงผลอย่างใดอย่างหนึ่งจากสองกรณี
export default function ConditionPage() {
const isLoggedIn = true;
const score = 75;
return (
<div>
<h1>Conditional Rendering</h1>
{/* && — render only when the condition is true */}
{isLoggedIn && <p>Welcome back!</p>}
{/* ternary — choose between two cases */}
<p>Status: {isLoggedIn ? "Online" : "Offline"}</p>
<p>Result: {score >= 50 ? "Pass" : "Fail"}</p>
</div>
);
}javascript
| Pattern | Syntax | ใช้เมื่อ |
|---|---|---|
| Logical AND | {cond && <p>...</p>} | แสดง element เฉพาะตอนเงื่อนไขเป็นจริง |
| Ternary | {cond ? A : B} | เลือกแสดงระหว่างสองกรณี |
หมายเหตุ: ภายใน
{}ของ JSX ต้องเป็นนิพจน์ จึงเขียนคำสั่งif/elseลงไปโดยตรงไม่ได้ ให้ใช้&&หรือ ternary หรือใช้if/elseเตรียมค่าก่อนถึงreturn
3.13 การกรองและค้นหาข้อมูล (filter และ find)#
สร้างไฟล์ app/07_filter_find/page.js — เข้าถึงที่ http://localhost:3000/07_filter_find ↗
เมื่อต้องการแสดงข้อมูลเฉพาะบางรายการ ให้ใช้ filter() เพื่อสร้าง อาร์เรย์ใหม่ ที่มีเฉพาะรายการตรงเงื่อนไข แล้วใช้ map() แสดงผลต่อได้ ส่วน find() ใช้ค้นหา รายการแรก ที่ตรงเงื่อนไข โดยจะได้ undefined หากไม่พบรายการนั้น
export default function FilterFindPage() {
const products = [
{ id: 1, name: "Laptop", price: 25000 },
{ id: 2, name: "Mouse", price: 500 },
{ id: 3, name: "Keyboard", price: 1500 },
{ id: 4, name: "Monitor", price: 6000 }
];
// filter — keep only products priced at 2000 or less
const cheapProducts = products.filter((product) => product.price <= 2000);
// find — get the first product whose id equals 3
const selected = products.find((product) => product.id === 3);
return (
<div>
<h1>Filter and Find</h1>
<h2>Products under 2,000</h2>
<ul>
{cheapProducts.map((product) => (
<li key={product.id}>{product.name} - {product.price}</li>
))}
</ul>
<h2>Selected Product</h2>
<p>{selected.name} - {selected.price}</p>
</div>
);
}javascript
| Method | คืนค่า | ใช้เมื่อ |
|---|---|---|
filter() | อาร์เรย์ใหม่ (อาจว่างหรือมีหนึ่งรายการขึ้นไป) | ต้องการทุกรายการที่ตรงเงื่อนไข |
find() | รายการเดียว (หรือ undefined) | ต้องการรายการแรกที่ตรงเงื่อนไข |
เคล็ดลับ: ใช้
filter()กรองรายการที่ต้องการก่อน แล้วใช้map()แปลงเป็น JSX สำหรับแสดงผล ส่วนค่าที่ได้จากfind()ควรตรวจสอบว่าพบข้อมูลก่อนอ่านคุณสมบัติ เช่นselected.name
3.14 สารบัญ#
เมื่อทำครบทุกหัวข้อแล้ว ให้แก้ไข app/page.js เป็นหน้าสารบัญ โดยใช้ Link สร้างลิงก์ไปยังบทเรียนแต่ละหน้า เพื่อกลับมาทบทวนได้สะดวก:
import Link from 'next/link'
export default function Home() {
return (
<div style={{ padding: '20px' }}>
<h1>JavaScript Lessons</h1>
<ul>
<li><Link href="/01_var">Variables</Link></li>
<li><Link href="/02_array">Arrays</Link></li>
<li><Link href="/03_object">Objects</Link></li>
<li><Link href="/04_array_objects">Array of Objects</Link></li>
<li><Link href="/05_function">Functions</Link></li>
<li><Link href="/06_condition">Conditional Rendering</Link></li>
<li><Link href="/07_filter_find">Filter and Find</Link></li>
</ul>
</div>
)
}javascript
สรุป#
ส่วนที่ 1: HTML#
- HTML ใช้กำหนดโครงสร้างและความหมายของเนื้อหาบนหน้าเว็บ
- องค์ประกอบพื้นฐาน ได้แก่ หัวข้อ ย่อหน้า ลิงก์ รูปภาพ รายการ ตาราง และแบบฟอร์ม
- เลือกแท็กให้ตรงกับความหมายของเนื้อหา เพื่อช่วยให้ผู้ใช้และเครื่องมือช่วยการเข้าถึงเข้าใจหน้าเว็บได้ดีขึ้น
ส่วนที่ 2: CSS#
- CSS ใช้ตกแต่งและจัดวางองค์ประกอบบนหน้าเว็บ
- เพิ่มสไตล์ได้ 3 วิธี คือ inline, internal และ external
- แยก CSS เป็นไฟล์ภายนอกเพื่อจัดการสไตล์และใช้ร่วมกันหลายหน้าได้สะดวก
- ใช้ Flexbox จัดเรียงองค์ประกอบและให้รายการขึ้นบรรทัดใหม่ตามพื้นที่ที่มี
ส่วนที่ 3: JavaScript กับ Next.js#
- ใช้ React component บน Next.js เพื่อสร้างหน้าเว็บและแสดงข้อมูลด้วย JSX
- ประกาศตัวแปรด้วย
constเมื่อไม่ต้องกำหนดค่าใหม่ และใช้letเมื่อต้องกำหนดค่าใหม่ภายหลัง - ใช้อาร์เรย์เก็บข้อมูลหลายรายการ และใช้ออบเจกต์เก็บคุณสมบัติเป็นคู่ key-value
- รวมทั้งสองแบบเป็นอาร์เรย์ของออบเจกต์ เมื่อแต่ละรายการมีหลายคุณสมบัติ
- แยกงานที่ใช้ซ้ำเป็นฟังก์ชัน ทั้งแบบปกติและ arrow function
- ใช้
map()สร้างรายการ,filter()กรองข้อมูล,find()ค้นหารายการ และ conditional rendering เลือกเนื้อหาตามเงื่อนไข
บทความถัดไป: เราจะต่อยอดพื้นฐานเหล่านี้ด้วย React และ Next.js ให้ลึกขึ้น ทั้งการส่งข้อมูลผ่าน props การจัดการ state และ hooks การดึงข้อมูลจาก API และการกำหนดเส้นทางหน้าเว็บ (routing)