JavaScript and DOM Interaction
TRƯỜNG ĐẠI HỌC CẦN THƠ TRƯỜNG CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG
- Nhập môn Lập trình Đa phương tiện
- Nhóm tác giả: Khoa Truyền thông Đa Phương tiện
- BÀI GIẢNG CT089
JavaScript (JS)
JavaScript DOM Overview
- DOM: Document Object Model
- Các lớp thuộc tính và phương thức để tương tác với DOM.
Document Object Model (DOM)
Khái niệm
- Mỗi phần tử (element) trong trang HTML được xem là một object
- Cấu trúc DOM tạo thành một cây phân cấp, có nút gốc là
window - Một số đối tượng trong DOM:
- Element nodes
- Text nodes
- Document nodes
- Comment nodes
- Tag nodes
Ví dụ về cấu trúc DOM
- Ví dụ cấu trúc DOM của trang HTML:
<html>
<head>
<title>Sample Document</title>
</head>
<body>
<h1>An HTML Document</h1>
<p>This is a <i>simple</i> document</p>
</body>
</html>
Tính năng của JS trong DOM
- Cung cấp các phương thức để thao tác trên DOM:
- Duyệt DOM
- Thay đổi thuộc tính, giá trị, định dạng của các element
- Tạo mới phần tử
- Chèn thêm phần tử vào các node trên trang HTML
- Loại bỏ phần tử từ trang HTML
- Tìm kiếm các phần tử với nhiều tiêu chí khác nhau
Các thuộc tính truy xuất DOM
| Property | Description |
|---|---|
| document.baseURI | Trả về URL của trang HTML |
| document.body | Trả về phần tử <body> |
| document.cookie | Trả về cookie |
| document.doctype | Trả về phần tử doctype |
| document.documentElement | Trả về phần tử <html> của trang |
| document.domain | Trả về tên miền (example: yoursite.com) |
| document.forms | Trả về tất cả phần tử form |
| document.head | Trả về phần tử <head> |
| document.images | Trả về tất cả phần tử <img> |
| document.inputEncoding | Trả về mã hóa của trang |
| document.links | Trả về tất cả phần tử <area> và <a> có thuộc tính href |
| document.readyState | Trả về trạng thái loading của trang |
| document.scripts | Trả về tất cả phần tử <script> |
| document.title | Trả về phần tử <title> |
Chọn phần tử DOM
Cách chọn phần tử
document.getElementById(“e_id”)- Chọn phần tử có thuộc tính
id=“e_id”
- Chọn phần tử có thuộc tính
document.getElementsByName(“str”)- Chọn tất cả phần tử có thuộc tính
name=“str”
- Chọn tất cả phần tử có thuộc tính
document.getElementsByTagName(“tag”)- Chọn tất cả phần tử theo loại (VD:
<input>,<form>,<span>…)
- Chọn tất cả phần tử theo loại (VD:
document.getElementsByClassName(“cls”)- Chọn phần tử với thuộc tính
class=“cls”
- Chọn phần tử với thuộc tính
document.querySelectorAll(CSS_selectors)- Chọn các phần tử khớp với bộ chọn CSS
Lưu ý
- Các phương thức từ 2 đến 5 trả về danh sách các node thỏa mãn điều kiện.
Ví dụ:
- Chọn và thay đổi thuộc tính của phần tử.
<html>
<head>
<title>DOM</title>
<script>
function checkall() {
var x = document.getElementsByName("course");
for (let i = 0; i < x.length; i++) {
if (x[i].type == "checkbox") {
x[i].checked = true;
}
}
}
</script>
</head>
<body>
JavaScript <input name="course" type="checkbox" value="js">
Python <input name="course" type="checkbox" value="py">
C++ <input name="course" type="checkbox" value="cpp">
<br />
<button onclick="checkall()">Select all</button>
</body>
</html>
Duyệt phần tử DOM
Các thuộc tính và phương thức
node.childNodes: Trả về danh sách các node con, bao gồm text node và element node.node.children: Trả về danh sách chỉ các element nodes con.node.firstChild: Trả về node con đầu tiên, trả về null nếu không có.node.firstElementChild: Trả về element node con đầu tiên.node.lastChild: Trả về node con cuối cùng.node.lastElementChild: Trả về element node cuối cùng.node.parentNode: Trả về node cha.node.parentElement: Trả về element node cha.node.closest(ancestor): Tìm phần tử tổ tiên.node.nextSibling: Trả về node anh em bên phải.node.nextElementSibling: Trả về element node bên phải.node.previousSibling: Trả về node anh em bên trái.node.previousElementSibling: Trả về element node bên trái.
Ví dụ:
- Lấy tất cả element nodes con từ parent node.
<div id="main">
<p>This is an element node</p>
This is a text node
<h3>This is heading element</h3>
</div>
<script>
var root = document.getElementById("main");
var elements = root.children;
for (let i = 0; i < elements.length; i++) {
console.log(elements[i].textContent);
}
</script>
Ví dụ:
- Lấy tất cả nodes huyền từ parent node.
<div id="main">
<p>This is an element node</p>
This is a text node
<h3>This is heading element</h3>
</div>
<script>
var root = document.getElementById("main");
var elements = root.childNodes;
for (let i = 0; i < elements.length; i++) {
console.log(elements[i].textContent);
}
</script>
Các phương thức và thuộc tính
Cách sử dụng
document.write(data): Ghi giá trị trực tiếp lên trang HTML.node.getAttribute(attrib): Nhận giá trị của thuộc tínhattrib.node.setAttribute(attrib, val): Gán giá trịvalcho thuộc tínhattrib.node.style.property: Nhận/ thay đổi giá trị định dạng của node.
Nội dung node
node.innerText: Trả về nội dung của node mà không bao gồm mã HTML.node.textContent: Tương tựinnerText, nhưng bao gồm cả khoảng trắng và nội dung ẩn.node.innerHTML: Trả về toàn bộ mã HTML trong node.
Ví dụ: Sự khác biệt
```html
This element has extra spacing and contains a span element.
var x = document.getElementById("demo");
alert(x.innerText); // "This element has extra spacing and contains a span element."
alert(x.textContent); // " This element has extra spacing and contains a span element."
alert(x.innerHTML); // " This element has extra spacing and contains a span element."
---
# Thêm, sửa, xóa node
## Tạo document fragment
- `document.createDocumentFragment()`: Tạo tài liệu rỗng để thêm các node con vào trước khi chèn vào trang HTML.
### Ví dụ:
- Chèn phần tử `<li>` vào `<ul>`.
html
## Tạo mới các phần tử
- `node.createElement(name)`: Tạo mới một element (VD: `span`, `div`, `h1`, `table`, `td`).
- `node.createTextNode(string)`: Tạo mới một text node.
- `document.createAttribute(name)`: Tạo mới attribute cho element.
- `node.setAttributeNode(attrOjb)`: Gán attribute cho node với `attrObj` tạo ra bởi `createAttribute()`.
- `node.cloneNode(bool)`: Nhân bản node (true: nhân bản và tất cả node con, false: chỉ nhân bản node).
### Ví dụ: Tạo liên kết và chèn vào tài liệu
- ```html
<body>
<div id="main"></div>
<script>
var main = document.getElementById("main");
var a = document.createElement("a");
var href = document.createAttribute("href");
href.value = "http://www.ctu.edu.vn";
a.setAttributeNode(href);
a.innerText = "Can Tho University Website";
a.style.textDecoration = "none";
a.style.color = "blue";
main.appendChild(a);
</script>
</body>
JavaScript Events
Các loại sự kiện
- Mouse events: Liên quan đến tương tác chuột.
- Keyboard events: Liên quan đến nhập liệu trên bàn phím.
- Event handler: Mã xử lý sự kiện.
- Form Validation: Kiểm tra và xác thực thông tin biểu mẫu.
Tương tác với người dùng
- JavaScript sử dụng sự kiện để tương tác với người dùng.
- Ví dụ: nhấn chuột, gõ phím, thay đổi kích thước màn hình, v.v.
- Khi sự kiện phát sinh, mã lệnh đã định nghĩa trước sẽ được thực thi (event handler).
- Các trình duyệt có cách phản ứng khác nhau với một số sự kiện.
Dòng sự kiện (Event Flow)
- Khi có sự kiện, sự kiện sẽ lan truyền từ đối tượng này sang đối tượng khác.
- Có hai dòng sự kiện: capturing (từ trên xuống dưới) và bubbling (từ dưới lên trên).
Ví dụ:
- Khi người dùng nhấn chuột lên thẻ
div, sự kiện click sẽ lan truyền:- Capturing:
- đối tượng document
- phần tử html
- phần tử body
- phần tử div
- Bubbling:
- phần tử div
- phần tử body
- phần tử html
- đối tượng document
Các loại sự kiện
Các loại sự kiện chính
- UI Events: Liên quan đến giao diện (VD:
load,resize,scroll,abort,error,select). - Focus Events: Xảy ra khi các control nhận được hoặc mất tiêu điểm.
- Mouse & Wheel Events: Liên quan đến các nút nhấn và cuộn chuột.
- Keyboard Events: Sự kiện xảy ra khi nhấn phím.
- Mutation Events: Xảy ra khi một node được chèn vào hoặc xóa bỏ khỏi DOM Tree.
- Device Events: Xảy ra khi thiết bị cầm tay di chuyển, xoay hướng.
- Touch Events: Khi người dùng chạm vào màn hình cảm ứng.
UI Events chi tiết
load:- Xảy ra trên window khi nội dung trang đã load hoàn toàn.
- Xảy ra trên frameset khi tất cả các frame đã tải xong.
- Xảy ra trên hình ảnh khi nội dung đã tải hoàn toàn.
- Xảy ra trên object khi đã được load hoàn toàn.
unload: Xảy ra trên đối tượng window khi người dùng đóng cửa sổ.abort: Xảy ra trên object khi người dùng bỏ qua quá trình tải.error: Xảy ra khi có lỗi JS trong window hay không thể load hình ảnh, object hay frame.resize: Xảy ra trên window khi thay đổi kích thước.scroll: Xảy ra trên các đối tượng có scrollbar khi người dùng cuộn màn hình.
Focus Events
blur: Xảy ra trên phần tử mất focus.focusout: Xảy ra trên phần tử và tất cả con bên trong khi mất focus (bubbling).focus: Xảy ra khi phần tử nhận được tiêu điểm.focusin: Xảy ra trên phần tử và tất cả con bên trong khi nhận được tiêu điểm.
Mouse Events
click: Khi nhấn chuột trái và thả ra.dblclick: Khi nhấn chuột trái hai lần liên tiếp.mousedown: Khi nhấn chuột trái.mouseup: Khi nhả chuột trái.mouseenter: Khi rê chuột vào phần tử.mouseover: Khi rê chuột vào phần tử và các phần tử con.mouseleave: Khi con trỏ rời khỏi phần tử.mouseout: Khi con trỏ rời khỏi phần tử và các con bên trong.mousemove: Khi con trỏ rê trên phần tử và các phần tử bên trong.
Keyboard Events
keydown: Khi nhấn phím, sự kiện lặp lại nếu giữ phím.keypress: Khi nhấn phím không báo cáo với phím đặc biệt.keyup: Khi nhả phím.
Event Handlers
Bắt sự kiện
Có hai cách để bắt sự kiện:
- Sử dụng thuộc tính của phần tử
- Sử dụng phương thức
addEventListener()
**Cú pháp: **
- Sử dụng thuộc tính:
<button onclick="alert('Hi!')">Click me</button>- Sử dụng
addEventListener():
var btn = document.getElementById('test'); btn.addEventListener('click', function() { alert('Hi!'); });
Event Object
Thông tin sự kiện
- Khi sự kiện xảy ra, JS sẽ truyền một object vào trong callback function.
- Đặc tính của event object:
key: Phím được nhấn trên keyboard event.keyCode: Mã phím được nhấn.target: Đối tượng đang bắt sự kiện.currentTarget: Đối tượng lắng nghe sự kiện.
Ví dụ: Nhấn phím
```html
Key:
Code:
### Ví dụ: Đổi màu nền ô textbox khi có sự kiện focus
- ```html
<form id="regForm" action="#" method="POST">
<label for="fName">First name: </label>
<input type="text" name="fName" id="fName" />
<br/>
<label for="lName">Last name: </label>
<input type="text" name="lName" id="lName" />
<br/>
<button type="submit">Submit</button>
</form>
<script>
var form = document.getElementById('regForm');
form.addEventListener('focusin' , function(e) {
if (e.target.tagName == 'INPUT') {
e.target.style.backgroundColor = 'yellow';
}
});
// loại bỏ màu nền khi mất focus
form.addEventListener('focusout' , function(e) {
if (e.target.tagName == 'INPUT') {
e.target.style.backgroundColor = null;
}
});
</script>
Form Validation
Kiểm tra ràng buộc form
- Dữ liệu trước khi lưu trữ cần được kiểm tra các điều kiện như kiểu dữ liệu, miền giá trị, yêu cầu bắt buộc.
- Các điều kiện kiểm tra ràng buộc phải dựa trên thuộc tính của dữ liệu.
- Kiểm tra ràng buộc thường thực hiện ở cả phía client và server.
- Nếu dữ liệu không thỏa mãn, quá trình submit sẽ bị hủy và thông báo lỗi sẽ hiển thị.
Required Fields
- Tối thiểu một số trường dữ liệu không được phép trống trong CSDL.
- Trên form, cần các phần tử bắt buộc nhập (ô textbox, textarea) hoặc các lựa chọn bắt buộc (checkbox, radio, select).
- Một ví dụ kiểm tra ô nhập không được rỗng:
<form action="register.php" onsubmit="return formValidate()" name="regForm" method="post">
<label for="fname">First name: </label>
<input type="text" name="fname" />
<label for="lname">Last name: </label>
<input type="text" name="lname" />
<button type="submit">Submit</button>
</form>
<script>
function formValidate() {
var frm = document.forms['regForm'];
if (frm.fname.value.length == 0) {
alert("Please enter First name.");
frm.fname.focus();
return false;
}
if (frm.lname.value.length == 0) {
alert("Please enter Last name.");
frm.lname.focus();
return false;
}
return true;
}
</script>
Kiểm tra ràng buộc kiểu
- Chỉ cho phép nhập số vào ô textbox.
<form name="frm" action="" method="post">
<label for="age">Age: </label>
<input type="text" name="age" onkeypress="return isNumber(event)" />
<button type="button" onclick="formValidate()">Submit</button>
</form>
<script>
function formValidate() {
var frm = document.forms['frm'];
var age = parseInt(frm.age.value);
if (age == NaN || age < 10 || age > 50) {
alert('Only 10 to 50 allowed.');
return false;
}
if (frm.age.value.length == 0) {
alert("Please enter your age.");
return false;
}
alert("That's OK.");
frm.submit();
}
function isNumber(event) {
var key = event.which || event.keyCode;
if (key < 48 || key > 57) {
return false;
}
return true;
}
</script>
Pattern Matching in Validation
Diễn giải
- Pattern matching là cách kiểm tra dữ liệu nhập có khớp với mẫu đã cho.
- Các pattern là biểu thức chính quy (regular expressions) cho phép kiểm tra dữ liệu một cách đơn giản.
- Ví dụ:
/(a|b)/: Kiểm tra dữ liệu có chứaahoặcb./[a-zA-Z]/: Kiểm tra dữ liệu có chứa ký tự HOA hoặc thường./[0-9]/: Kiểm tra dữ liệu có chứa chữ số./[^a-z]/: Kiểm tra dữ liệu KHÔNG chứa ký tự thường.
Ví dụ
- Một số cách xác thực đơn giản với regex về địa chỉ email, mật khẩu:
- Kiểm tra địa chỉ email:
var emailReg = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
- Kiểm tra độ dài mật khẩu ít nhất 8 ký tự:
var passReg = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/g;