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:
document
biế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)window
biến kiểuWindow
biể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ãnselector
querySelectorAll(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); } }