ผู้ช่วยศาสตราจารย์ ปองพล นิลพฤกษ์
jQuery คือไลบรารี (Library) ของภาษา JavaScript ที่ได้รับความนิยมอย่างสูงในอดีต ถูกสร้างขึ้นมาเพื่อทำให้การเขียน JavaScript สำหรับจัดการหน้าเว็บ (DOM Manipulation), การจัดการเหตุการณ์ (Event Handling), การสร้างแอนิเมชัน และการทำ AJAX เป็นเรื่องง่ายและสั้นลงอย่างมาก jQuery ถูกออกแบบมาภายใต้ปรัชญา "Write less, do more" หรือ "เขียนน้อยลง แต่ทำได้มากขึ้น"
ในยุคที่เบราว์เซอร์มีความแตกต่างกันสูง (โดยเฉพาะยุคของ Internet Explorer 6) การเขียน JavaScript ให้ทำงานได้เหมือนกันทุกเบราว์เซอร์เป็นเรื่องที่น่าปวดหัวมาก jQuery จึงเปรียบเสมือน "ฮีโร่" ที่เข้ามาแก้ปัญหานี้โดยสร้าง API ที่เรียบง่ายและทำงานได้สอดคล้องกันในทุกเบราว์เซอร์ แม้ว่าปัจจุบัน JavaScript สมัยใหม่ (Vanilla JS) จะมีความสามารถหลายอย่างที่เทียบเท่า jQuery แล้ว เช่น document.querySelector หรือ fetch API แต่การเรียนรู้ jQuery ยังคงมีประโยชน์อย่างยิ่ง เนื่องจากโปรเจกต์และปลั๊กอินจำนวนมหาศาลยังคงใช้งาน jQuery อยู่
หัวใจของ jQuery คือการลดความซับซ้อนของการเขียนโค้ด ลองดูตัวอย่างการเปรียบเทียบปริมาณโค้ดที่ต้องเขียนสำหรับงานง่ายๆ อย่างการเพิ่ม Event Listener ให้กับปุ่มเมื่อถูกคลิก ระหว่าง JavaScript แบบดั้งเดิม, JavaScript สมัยใหม่ และ jQuery
จากแผนภูมิจะเห็นได้ว่า jQuery ช่วยลดจำนวนบรรทัดของโค้ดลงได้อย่างมีนัยสำคัญ ทำให้โค้ดอ่านง่ายขึ้นและพัฒนาได้รวดเร็วยิ่งขึ้น
สำหรับนักศึกษาที่คุ้นเคยกับ Bootstrap 5 อาจจะทราบว่า Bootstrap 5 ได้ตัด jQuery ออกจากการเป็น Dependency หลัก และเปลี่ยนไปใช้ Vanilla JS แทนทั้งหมดเพื่อประสิทธิภาพที่ดีขึ้นและลดขนาดของโปรเจกต์
อย่างไรก็ตาม Bootstrap 5 ยังคงถูกออกแบบมาให้ทำงานร่วมกับ jQuery ได้ หาก Bootstrap ตรวจพบว่ามี jQuery อยู่ในหน้าเว็บ มันจะทำการเพิ่มคอมโพเนนต์ทั้งหมดเข้าไปในระบบปลั๊กอินของ jQuery โดยอัตโนมัติ ทำให้เรายังสามารถใช้ синтаксисแบบ jQuery เพื่อควบคุมคอมโพเนนต์ของ Bootstrap ได้ เช่น การเปิดใช้งาน Tooltip ด้วย $('[data-bs-toggle="tooltip"]').tooltip()
ดังนั้น การทำความเข้าใจ jQuery จะช่วยให้คุณสามารถทำงานกับโปรเจกต์เก่าที่ใช้ Bootstrap เวอร์ชันก่อนหน้า (3 หรือ 4) ซึ่งจำเป็นต้องใช้ jQuery และยังช่วยให้คุณมีทางเลือกในการทำงานกับ Bootstrap 5 ได้อย่างยืดหยุ่นมากขึ้น
การนำ jQuery มาใช้งานในโปรเจกต์ทำได้ 2 วิธีหลัก:
<script> ไปวางไว้ในไฟล์ HTML ของคุณก่อนปิดแท็ก </body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="path/to/your/jquery-3.7.1.min.js"></script>
ก่อนที่เราจะเริ่มจัดการหรือเปลี่ยนแปลงส่วนต่างๆ ของหน้าเว็บ เราต้องมั่นใจก่อนว่าหน้าเว็บ (DOM) ถูกโหลดขึ้นมาจนครบถ้วนสมบูรณ์แล้ว jQuery มีฟังก์ชันพิเศษที่เรียกว่า "Document Ready Event" เพื่อจัดการเรื่องนี้
โค้ด jQuery ทั้งหมดควรถูกเขียนอยู่ภายในฟังก์ชันนี้ เพื่อป้องกันการทำงานผิดพลาดจากการพยายามเข้าถึง Element ที่ยังไม่ถูกสร้างขึ้น
ทดลองสร้างไฟล์ pm25.js ใน js/pm25.js แล้ว เพิ่ม script ต่อไปนี้ในหน้า page ที่ต้องการ (เพิ่มหลังจาก script JQuery แล้ว)
// ทดสอบการเพิ่ม
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<!-- Bootstrap Bundle with Popper -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"
></script>
<script src="js/pm25.js"></script>
// รูปแบบเต็ม
$(document).ready(function(){
// โค้ด jQuery ทั้งหมดจะถูกเขียนที่นี่
console.log("DOM is ready!");
});
// รูปแบบย่อ (เป็นที่นิยม)
$(function(){
// โค้ด jQuery ทั้งหมดจะถูกเขียนที่นี่
console.log("DOM is ready!");
});
การใช้งาน jQuery ส่วนใหญ่จะวนเวียนอยู่กับ 3 แนวคิดหลัก คือ การเลือกองค์ประกอบ (Selectors), การจัดการ DOM (DOM Manipulation) และการจัดการเหตุการณ์ (Event Handling)
Selectors คือส่วนที่ทรงพลังที่สุดของ jQuery มันคือวิธีการ "ค้นหา" หรือ "เลือก" HTML elements ที่เราต้องการจะทำงานด้วย โดยใช้ синтаксисที่คล้ายกับ CSS Selector มาก ทำให้ง่ายต่อการเรียนรู้
$('p') จะเลือกทุก <p> ในหน้าเว็บ$('#myButton') จะเลือก Element ที่มี id="myButton"$('.alert') จะเลือกทุก Element ที่มี class="alert"$('a[target="_blank"]') จะเลือกทุก <a> ที่มี attribute target เป็น _blank$('div.content p') จะเลือกทุก <p> ที่อยู่ภายใน <div> ที่มี class="content"หลังจากที่เราเลือก Element ที่ต้องการได้แล้ว เราสามารถใช้เมธอดต่างๆ ของ jQuery เพื่อจัดการกับมันได้หลากหลายรูปแบบ
.text(): อ่านหรือกำหนดเนื้อหาที่เป็นข้อความธรรมดา.html(): อ่านหรือกำหนดเนื้อหาที่เป็น HTML.val(): อ่านหรือกำหนดค่า (value) ของฟอร์ม เช่น <input>, <select>.attr('attributeName'): อ่านหรือกำหนดค่าของ Attribute// Get (อ่านค่า)
var pageTitle = $('h1').text();
var content = $('#main-content').html();
var username = $('#username-input').val();
// Set (กำหนดค่า)
$('h1').text('New Page Title');
$('#main-content').html('<p>This is new content.</p>');
$('#username-input').val('defaultUser');
$('a').attr('href', 'https://new-link.com');
.append(): เพิ่มเนื้อหาเข้าไป "ข้างในสุด" ของ Element ที่เลือก.prepend(): เพิ่มเนื้อหาเข้าไป "ข้างหน้าสุด" ของ Element ที่เลือก.after(): เพิ่มเนื้อหาเข้าไป "ต่อท้าย" Element ที่เลือก.before(): เพิ่มเนื้อหาเข้าไป "ก่อนหน้า" Element ที่เลือก.remove(): ลบ Element ที่เลือกและลูกๆ ของมันทั้งหมด.empty(): ลบเฉพาะลูกๆ ของ Element ที่เลือกออกไป$('#myList').append('<li>New item at the end</li>');
$('#myList').prepend('<li>New item at the start</li>');
$('.item-to-remove').remove();
jQuery ทำให้การดักจับและตอบสนองต่อการกระทำของผู้ใช้ (Events) เป็นเรื่องง่ายมาก
.click(), .dblclick(), .hover(), .mouseenter(), .mouseleave().keydown(), .keyup(), .keypress().submit(), .change(), .focus(), .blur().ready(), .scroll(), .resize()$('#myButton').click(function() {
alert('Button was clicked!');
});
$('#myInput').on('keyup', function() {
console.log('User is typing...');
});
ปัญหาส่วนใหญ่ในการเขียน JavaScript คือเมื่อเราเพิ่ม Element ใหม่เข้ามาในหน้าเว็บแบบไดนามิก (เช่น ผ่าน AJAX) Event ที่เราผูกไว้ก่อนหน้าจะไม่ทำงานกับ Element ใหม่นี้
jQuery แก้ปัญหานี้ด้วยเทคนิคที่เรียกว่า Event Delegation โดยการผูก Event ไว้ที่ Element แม่ (Parent) ที่มีอยู่แล้ว และระบุว่าจะให้ Event นี้ทำงานกับ Element ลูกตัวไหน วิธีนี้มีประสิทธิภาพสูงและยืดหยุ่นมาก
// ผูก Event กับ Element ที่มีอยู่แล้ว
// ถ้ามี .list-item ใหม่เพิ่มเข้ามา โค้ดนี้จะไม่ทำงานกับปุ่มใหม่
$('.list-item .delete-btn').on('click', function() {
$(this).parent().remove();
});
// ใช้ Event Delegation (วิธีที่แนะนำ)
// ผูก Event กับ #list-container ซึ่งเป็นแม่และมีอยู่ตลอด
// Event จะทำงานกับ .delete-btn ใดๆ ก็ตามที่ถูกคลิก แม้จะถูกเพิ่มเข้ามาทีหลัง
$('#list-container').on('click', '.delete-btn', function() {
$(this).closest('.list-item').remove();
});
jQuery มีชื่อเสียงในเรื่องการสร้างแอนิเมชันและเอฟเฟกต์ที่สวยงามได้อย่างง่ายดาย
คุณสามารถซ่อน, แสดง, หรือสลับการแสดงผลของ Element ได้ด้วยเมธอดง่ายๆ
.show() / .hide() / .toggle().fadeIn() / .fadeOut() / .fadeToggle().slideDown() / .slideUp() / .slideToggle()$('#myPanel').slideToggle(500); // 500 คือความเร็วในหน่วยมิลลิวินาที
สำหรับแอนิเมชันที่ซับซ้อนขึ้น คุณสามารถใช้เมธอด .animate() เพื่อเปลี่ยนค่า CSS ที่เป็นตัวเลขได้ คุณสามารถกำหนดคุณสมบัติ CSS หลายอย่างพร้อมกันได้
синтаксис-$(selector).animate({params}, speed, callback);
params- Object ของ CSS properties ที่ต้องการจะเปลี่ยนspeed- ความเร็ว (เช่น 'slow', 'fast', หรือตัวเลขมิลลิวินาที)callback- ฟังก์ชันที่จะทำงานหลังจากแอนิเมชันเสร็จสิ้น
$('#myBox').on('click', function() {
$(this).animate({
left: '+=250px', // เคลื่อนที่ไปทางขวา 250px จากตำแหน่งปัจจุบัน
opacity: 0.5,
height: 'toggle'
}, 1000, function() {
// Animation complete.
alert('Animation finished!');
});
});
jQuery ยังมีความสามารถในการทำ "Queue" หรือการเข้าคิวแอนิเมชันโดยอัตโนมัติ หากคุณเรียกใช้ .animate() หลายครั้งติดต่อกันบน Element เดียวกัน มันจะทำงานทีละขั้นตอนจนครบ
AJAX (Asynchronous JavaScript and XML) คือเทคนิคที่ช่วยให้หน้าเว็บสามารถดึงข้อมูลจากเซิร์ฟเวอร์มาอัปเดตบางส่วนของหน้าได้ โดยไม่ต้องรีโหลดทั้งหน้า ซึ่ง jQuery ทำให้การทำ AJAX เป็นเรื่องง่ายมาก
$.ajax(): เป็นเมธอดหลักที่มีความยืดหยุ่นสูงสุด สามารถตั้งค่าได้ทุกอย่าง $.get(): รูปแบบย่อสำหรับการส่งคำขอแบบ GET$.post(): รูปแบบย่อสำหรับการส่งคำขอแบบ POSTตัวอย่างการดึงข้อมูลผู้ใช้จาก API สมมติ แล้วนำมาแสดงผล-
$('#load-user-btn').on('click', function() {
$.ajax({
url: 'https://api.example.com/users/1',
type: 'GET',
dataType: 'json', // บอก jQuery ว่าคาดหวังข้อมูลประเภท JSON
beforeSend: function() {
$('#user-info').text('Loading...');
},
success: function(data) {
// เมื่อสำเร็จ (status 200)
var userInfoHtml = `
<h4>${data.name}</h4>
<p>Email: ${data.email}</p>
<p>Website: ${data.website}</p>
`;
$('#user-info').html(userInfoHtml);
},
error: function(xhr, status, error) {
// เมื่อเกิดข้อผิดพลาด
$('#user-info').text('Failed to load user data.');
console.error("AJAX Error: " + status + ' ' + error);
}
});
});
jQuery ได้ปฏิวัติวงการพัฒนาเว็บในยุคสมัยของมัน และถึงแม้ว่าปัจจุบันจะมีเครื่องมือและเฟรมเวิร์กใหม่ๆ เกิดขึ้นมากมาย แต่ความรู้เกี่ยวกับ jQuery ยังคงเป็นทักษะที่มีค่า
การเรียนรู้ jQuery ไม่ใช่การเดินถอยหลัง แต่เป็นการเพิ่มเครื่องมือในกล่องเครื่องมือของคุณ ทำให้คุณเข้าใจวิวัฒนาการของการพัฒนาเว็บ และสามารถเลือกใช้เทคโนโลยีที่เหมาะสมกับงานแต่ละประเภทได้อย่างมีประสิทธิภาพ ลองนำความรู้ที่ได้ไปสร้างโปรเจกต์เล็กๆ เช่น To-Do List, เกมง่ายๆ, หรือแอปแสดงสภาพอากาศ เพื่อฝึกฝนทักษะของคุณต่อไป
ใน Workshop นี้ เราจะประยุกต์ใช้ความรู้เรื่อง jQuery AJAX และ DOM Manipulation เพื่อดึงข้อมูลคุณภาพอากาศจาก API ของ Air4Thai และนำมาแสดงผลในรูปแบบของ Bootstrap Cards
เราจะใช้ API endpoint- air4thai.com/forweb/getStationData.php?stationID=20t ซึ่งจะดึงข้อมูลคุณภาพอากาศรายวันในรูปแบบ JSON
โครงสร้างข้อมูล JSON ที่ได้รับจะมีลักษณะดังนี้-
[
{
"DATETIMEDATA": "2025-12-24",
"AQI": "87",
"PM25": "34.3",
"PM10": "61",
"CO": "0.40",
"O3": "11",
"SO2": "3",
"NO2": -999
},
{
"DATETIMEDATA": "2025-12-23",
"AQI": "76",
"PM25": "31.5",
"PM10": "57",
"CO": "0.50",
"O3": "6",
"SO2": "3",
"NO2": -999
}
// ... and so on
]
เตรียมพื้นที่สำหรับแสดงผลข้อมูล โดยใช้ Bootstrap's grid system และ card components
<!-- index.html -->
<div class="container mt-4">
<h2>รายงานคุณภาพอากาศ</h2>
<p>สถานี- 20t</p>
<button id="load-aqi-btn" class="btn btn-primary mb-3">โหลดข้อมูล</button>
<div id="aqi-cards-container" class="row">
<!-- ข้อมูล AQI จะถูกแทรกที่นี่ -->
</div>
</div>
เขียนโค้ด jQuery เพื่อดักจับการคลิกปุ่ม, เรียกใช้ AJAX, และสร้าง Bootstrap cards จากข้อมูลที่ได้รับ
// สร้างไฟล์ script.js ของตนเองแล้วทดสอบในหน้า page ที่ต้องการ
$(function() {
$('#load-aqi-btn').on('click', function() {
$.ajax({
url: 'http://air4thai.com/forweb/getStationData.php?stationID=20t',
type: 'GET',
dataType: 'json',
beforeSend: function() {
$('#aqi-cards-container').html('<p>กำลังโหลดข้อมูล...</p>');
},
success: function(data) {
var cardsHtml = '';
$('#aqi-cards-container').empty(); // ล้างข้อมูลเก่า
// วนลูปสร้าง card สำหรับแต่ละวัน
$.each(data, function(index, record) {
// ค่า -999 หมายถึงไม่มีข้อมูล
var pm25 = record.PM25 !== -999 ? record.PM25 : 'N/A';
cardsHtml += `
<div class="col-md-4 mb-3">
<div class="card">
<div class="card-body">
<h5 class="card-title">วันที่- ${record.DATETIMEDATA}</h5>
<h6 class="card-subtitle mb-2 text-muted">AQI- ${record.AQI}</h6>
<p class="card-text">PM2.5- ${pm25} µg/m³</p>
</div>
</div>
</div>
`;
});
$('#aqi-cards-container').html(cardsHtml);
},
error: function(xhr, status, error) {
$('#aqi-cards-container').html('<p class="text-danger">เกิดข้อผิดพลาดในการโหลดข้อมูล</p>');
console.error("AJAX Error- " + status + ' ' + error);
}
});
});
});
$('#load-aqi-btn').on('click', ...) เพื่อรอรับการคลิกที่ปุ่ม$.ajax() จะถูกเรียกเพื่อส่ง GET request ไปยัง URL ของ Air4Thai#aqi-cards-container ด้วย .empty()$.each() เพื่อวนลูปข้อมูลที่ได้รับมาในรูปแบบ Array of ObjectsDATETIMEDATA, AQI, และ PM25 จาก object#aqi-cards-container ด้วย .html()// card body
<div class="card-body">
<h6>สถานีตรวจวัด 20</h6>
<h5 class="card-title">AQI:<font id="aqi-value">...</font></h5>
<p class="card-text">
PM2.5: <font id="pm25-value">45</font>µg/m³<br />
PM10: <font id="pm10-value">80</font> µg/m³<br />
ข้อมูล ณ <font id="data-time">...</font>
</p>
<a href="#" class="btn btn-primary">ดูรายละเอียด</a>
</div>// pm25.js
$(document).ready(function(){
console.log("DOM is ready!");
fetchAirQualityData();
});
function fetchAirQualityData() {
$.ajax({
url: 'http://air4thai.com/forweb/getStationData.php?stationID=20t', // Replace with actual API endpoint
method: 'GET',
beforeSend: function() {
console.log("Fetching air quality data...");
},
success: function(data) {
console.log("Data fetched successfully:", data);
console.log("AQI:", data[0].AQI);
console.log("PM2.5:", data[0].PM25);
console.log("PM10:", data[0].PM10);
console.log("Data Time:", data[0].DATETIMEDATA);
$('#aqi-value').text(data[0].AQI);
$('#pm25-value').text(data[0].PM25);
$('#pm10-value').text(data[0].PM10);
$('#data-time').text(data[0].DATETIMEDATA);
// Process and display the data on the webpage
},
error: function(error) {
console.error("Error fetching data:", error);
},
});
}
<select> สำหรับเลือกสถานีตรวจวัดอื่นๆ และส่ง stationID ที่เลือกไปกับ AJAX request