Thư viện dart:html - tương tác với HTML DOM
Thư viện để Dart làm việc với DOM HTML là dart:html, nên trước khi sử dụng cần nạp thư viện này
ở đầu file:
import 'dart:html';
Cũng cần tìm hiểu về HTML DOM trước Cơ bản về DOM
Khi thư viện này được nạp, chúng ta lập tức có biến (thuộc tính) với tên:
documentbiến có kiểuHtmlDocumentđó là nút gốc của DOM, từ biến này có thể truy cập mọi thành phần DOM (nó giống document trong JavaScript)windowbiến kiểuWindowbiểu diễn cửa sổ trình duyệt (Gống window trong JS), từ đây có thể truy cập các hàm JS thông dụng đã biết, ví dụ alertwindow.alert('Hello!');
Tham khảo Web Dart - Ứng dụng đầu tiên,
hãy tạo ra một dự án theo hướng dẫn đó, để thực hành các đoạn code ngắn ở đây. Tạm thời nội dung file main.dart, main.css index.html
như sau:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Web Dart 02</title>
<link rel="stylesheet" href="main.css">
<script defer src="main.dart.js"></script>
</head>
<body>
</body>
</html>
main.dart
void main() {
}
main.css
body {
font-family: 'Open Sans', sans-serif;
font-size: 14px;
font-weight: normal;
line-height: 1.2em;
margin: 15px;
}
Chạy thử truy cập http://localhost:8080 chỉ là trang trắng, vì chưa có gì trong HTML và chưa có code trong main.dart
Lớp Element phần tử HTML
Lớp Element cùng với các kế thừa của nó dùng để biểu diễn các phần từ HTML trong DOM như các phần tử
<a> <img> <article> <p> <div>
...
Đối tượng Element có được bằng cách khởi tạo đối tượng mới hoặc bằng cách tìm nó trong DOM hiện hành.
Gọi hàm khởi tạo Element.tag(tagname) để tạo ra phần tử HTML có tên là tagname (như a, p, img ...)
hoặc gọi hàm tạo theo tên phần tử HTML Element.a();
Element.img(); Element.table()); ... ví dụ:
var $srcimg = 'https://upload.wikimedia.org/wikipedia/commons/2/2f/Google_2015_logo.svg';
var img = Element.tag('img'); //Tạo phần tử HTML Img
img
..setAttribute('src', $srcimg)
..style.width='150px';
document.body.children.add(img); //Nối vào cuối HTML
var linka = Element.a(); //Ví dụ tạo phần tử a
linka
..text = 'XuanThuLab'
..setAttribute('target', '_blank')
..setAttribute('href', 'https://xuanthulab.net');
document.body.children.add(linka); //Nối vào cuối HTML
Kết quả chạy thử:
Nếu muốn lấy phần tử đang có trong DOM dùng đến phương thức querySelector và querySelectorAll
trình bày phần dưới
Một số phương thức, thuộc tính trong Element
attributes |
Map chứa các thuộc tính của phần tử HTML, mỗi phần tử HTML có nhiều thuộc tính - xem Thuộc tính HTML để biết chi tiết. |
children |
Thuộc tính biểu diễn danh sách (List) các phần tử con của nó |
parent |
Thuộc tính trỏ đến phần tử cha |
className |
Chuỗi biểu diễn lớp CSS của phần tử |
classes |
Tập hợp (Set) các lớp CSS của phần tử |
id |
ID của phần tử |
innerHtml |
Văn bản HTML trong phần tử |
title |
Thuộc tính title của phần tử HTML |
text |
Thuộc tính chứa nội dung text của phần tử |
dataset |
Map cho phép truy cập các thuộc tính dạng tên dạng data-*, ví dụ dataset['abc']
truy cập đến thuộc tính HTML data-abc |
appendHtml(String html) |
Phương thức để nối thêm văn bản HTML vào phần tử |
appendText(String html) |
Phương thức để nối thêm văn bản (không phải HTML) vào phần tử |
getAttribute(String nameAttr) |
Lấy thuộc tính của phần tử |
querySelector(String selectors) |
Tìm 1 phần tử con theo selector - xem phần dưới |
querySelectorAll(String selectors) |
Tìm tất cả phần tử con theo selector - xem phần dưới |
addEventListener |
Thêm một Listener cho sự kiện - xem phần Thêm sự kiện |
remove() |
Loại bỏ phần tử ra khỏi DOM |
onBlur() |
Lấy luồng biêu diễn sự kiện blur (chuột trên phần tử) |
onChange() |
Lấy luồng biêu diễn sự kiện change (thay đổi giá trị phần tử) |
onClick() |
Lấy luồng biêu diễn sự kiện click (bấm vào phần tử) |
Xem đầy đủ tại Element Class
Lấy phần tử, tạo và chèn phần tử trong DOM
Có 2 phương thức để tìm ra phần tử trong DOm là querySelectorAll(string selectors)
và phương thức querySelector(String selectors), trong đó selectors là CSS Selector
quen thuộc nhất là nếu đã từng sử dụng jQuery như "a", như ".class", như "#id"
..., hãy xem phần Selector CSS,
Chọn phần tử trong DOM với JS,
Selector với jQuery để biết
về các biểu thức selector
querySelector(String selectors)trả về phần tử Element đầu tiên nó tìm thấy thỏa mãnselectorquerySelectorAll(string selectors)trả về danh sách các Element (List<Element>) thỏa mãnselector
Trở lại ví dụ trên, xóa bỏ đi code bên trong main.dart và biên tập index.html,
main.css như sau:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Web Dart 02</title>
<link rel="stylesheet" href="main.css">
<script defer src="main.dart.js"></script>
</head>
<body>
<p>Các bài học lập trình với <span id="langid">Dart</span></p>
<ul id="ulcacbaihoc">
<li>Nội dung 1</li>
<li>Nội dung 2</li>
</ul>
<p>Các bài đã học</p>
<ul id="cacbaidahoc">
</ul>
<button id="buttonreset">Reset</button>
</body>
</html>
main.css
body {
font-family: 'Open Sans', sans-serif;
font-size: 14px;
font-weight: normal;
line-height: 1.2em;
margin: 15px;
}
ul li {
border: 1px solid green;
padding: 10px;
margin: 10px;
}
.elementli {
font-weight: bold;
color: red;
}
Đây là code HTML, CSS thông thường chạy thử http://localhost:8080 được
Giờ muốn thực hiện các tác vụ như sau khi mở trang (code trong main.dart):
Thay nội dung Dart trong phần tử span có id là langid
thành WEB DART
var lang = querySelector('#langid'); //Tìm phần tử theo ID
lang.text = 'WEB DART';
Lấy tất cả các li trong ul có id="ulcacbaihoc",
mỗi phần tử li tìm được thiết lập cho nó lớp CSS elementli (chữ màu đỏ),
đồng thời thay nôi dung tương ứng là Bài học 1, Bài học 2 ...
var baihoc = 0;
var lis = querySelectorAll('#ulcacbaihoc li'); //Lấy tất cả li trong UL
lis.forEach((Element li) {
baihoc ++;
li.text = 'Bài học ' + baihoc.toString(); //Thiết lập nội dung li
li.classes.add('elementli'); //Thêm CSS class vào LI
});
Chạy thử đến lúc này được
Tiếp tục, tạo ra 3 phần tử li và chèn vào ul, các li
có nội dung là Bài học 3 ... Bà học 5
Thêm vào main.dart đoạn code
var ul = querySelector('#ulcacbaihoc');
for (int j=1; j <=3; j++) {
var li = Element.li(); //Khởi tạo phần tử li
li.text = 'Bài học ' + (++baihoc).toString(); //Thiết lập nội dung li
ul.children.add(li); //Thêm vào UL
}
Đến lúc này main.dart có nội dung tổng hợp lại là
import 'dart:html';
void main() {
var lang = querySelector('#langid');
lang.text = 'WEB DART';
var baihoc = 0;
var lis = querySelectorAll('#ulcacbaihoc li');
lis.forEach((Element li) {
baihoc ++;
li.text = 'Bài học ' + baihoc.toString();
li.classes.add('elementli');
});
var ul = querySelector('#ulcacbaihoc');
for (int j=1; j <=3; j++) {
var li = Element.li();
li.text = 'Bài học ' + (++baihoc).toString();
ul.children.add(li);
}
}
Kết quả kiểm tra http://localhost:8080
EventListener - Lắng nghe sự kiện cho phần tử
Các sự kiện phát đi từ phần tử (như bấm vào phần tử, thay đổi giá trị phần tử ...) được biểu diễn bằng đối tượng lớp
Event, đối tượng này được làm tham số cho hàm thi hành mà sự kiện xảy ra - hàm đó gọi là Listener
Một Listener là một hàm, khai báo dạng:
void ListenerFunction(Event e) {
}
Khi có các Listener, đăng ký nó lắng nghe các sự kiện trên phần tử bằng các sử dụng các thuộc tính biểu
diễn luồng sự kiện trên phần tử như:
Element.onClick,
Element.onBlur,
Element.onChange,
Element.onKeyDown,
Element.onKeyPress,
Element.onSubmit,
Element.onReset,
Element.onSubmit,
Element.onDoubleClick,
Element.onFocus ... Từ thuộc tính này đăng ký listener theo dạng như sau:
//Đăng ký listener cho sự kiện bấm vào phần tử element element.onClick.listen(listener);
Một số thuộc tính, phương thức trong Event
target |
Đối tượng phát sự kiện |
type |
Chuỗi biểu diễn kiểu sự kiện |
preventDefault() |
Dừng thi hành hành động mặc định của sự kiện - Xem thêm preventDefault |
stopPropagation() |
Dừng lan truyền sự kiện - Xem thêm stopPropagation |
Trở lại ví dụ trên, thực hiện chức năng khi bấm vào phần tử li, sẽ di chuyển nó từ ul
có id=ulcacbaihoc đến ul có id=cacbaidahoc và ngược lại, tùy thuộc phần tử đó
đang nằm ở ul nào
void main() {
var lang = querySelector('#langid');
lang.text = 'WEB DART';
var baihoc = 0;
var lis = querySelectorAll('#ulcacbaihoc li');
lis.forEach((Element li) {
baihoc ++;
li.text = 'Bài học ' + baihoc.toString();
li.classes.add('elementli');
});
var ul = querySelector('#ulcacbaihoc');
for (int j=1; j <=3; j++) {
var li = Element.li();
li.text = 'Bài học ' + (++baihoc).toString();
ul.children.add(li);
}
//Lấy tất cả li
lis = querySelectorAll('#ulcacbaihoc li');
lis.forEach((Element li) {
//Thiết lập Listener khi bấm vào li
li.onClick.listen(moveLiElement);
});
}
//Listener lắng nghe bấm vào li
void moveLiElement(Event e) {
LIElement li = e.target;
if (li.parent.id == 'ulcacbaihoc') {
querySelector('#cacbaidahoc').children.add(li);
}
else {
querySelector('#ulcacbaihoc').children.add(li);
}
}
