Nếu bạn đã làm việc với JavaScript một thời gian, bạn có thể khá quen thuộc với tập lệnh DOM (Mô hình đối tượng tài liệu) và CSSOM (Mô hình đối tượng CSS). Ngoài các giao diện được xác định bởi các thông số kỹ thuật DOM và CSSOM, một tập hợp con các phương thức và thuộc tính được chỉ định trong Mô-đun Chế độ xem CSSOM, cung cấp API để xác định và thao tác hình học phần tử DOM nhằm hiển thị giao diện người dùng thú vị trên web.
Điều kiện tiên quyết:
Chế độ xem CSSOM là một mô-đun CSS chứa một loạt các thuộc tính và phương thức, tất cả được đóng gói lại để cung cấp cho tác giả một giao diện riêng để lấy thông tin về chế độ xem trực quan của các thành phần. Các thuộc tính trong mô-đun này chủ yếu là chỉ đọc và được tính toán mỗi lần chúng được truy cập — các giá trị trực tiếp.
Hiện tại, Mô-đun Chế độ xem CSSOM chỉ là bản nháp đang hoạt động và đang được sửa đổi trong Bảng thông số kỹ thuật của W3C. Do đó, bản chất của nó là xác định các giao diện này, cả giao diện đã tồn tại và giao diện mới, theo cách có thể tương thích trên nhiều trình duyệt.
Đầu tiên, không phải giao diện người dùng hàng ngày yêu cầu các thành phần có thể di chuyển để đạt được các câu chuyện người dùng cơ bản nhất của nó. Trừ khi bạn đang xây dựng giao diện trò chơi, bạn có thể không phải lúc nào cũng cần làm cho các thứ có thể di chuyển trên trang web của mình. Các thuộc tính hình học rất hữu ích mặc dù có những điều này vì khả năng thao tác theo chương trình chế độ xem trực quan của các phần tử DOM cung cấp cho các nhà phát triển nhiều siêu năng lực hơn để triển khai giao diện người dùng động.
Bảng Kanban được triển khai vì các thành phần có thể được kéo và thả ở các phần có liên quan. Nhiều nội dung hơn được tải khi người dùng cuộn xuống cuối tài liệu vì các giá trị vị trí cuộn có thể đọc được. Vì vậy, mặc dù có vẻ không rõ ràng ngay lập tức, nhưng thông qua việc biết thông tin chính xác về kích thước và vị trí của các phần tử mà các tính năng này có thể đạt được.
Thứ hai, khi xem tài liệu HTML trong trình duyệt web, các Phần tử DOM được hiển thị dưới dạng hình dạng trực quan, do đó, chúng có biểu diễn trực quan tương ứng mà trình duyệt có thể xem/trực quan. Truy cập các thuộc tính trực quan trực tiếp của các phần tử DOM này thông qua các thuộc tính và phương thức Chế độ xem CSSOM mang lại lợi thế hơn so với các thuộc tính CSS thông thường. Và sau đó bạn hỏi cách:


Vì vậy, khi một tài liệu có hướng viết từ phải sang trái và thanh cuộn dọc bên trái, thì

Các pixel được trả về bởi thuộc tính
Các thuộc tính
Lưu ý: Các thuộc tính
Đây là lý do tại sao nếu một phần tử không có nội dung tràn trên trục
MDN giải thích các giá trị thuộc tính
Vì có một phần tử

Để có được chiều rộng và chiều cao bên trong của cửa sổ, các thuộc tính
Bạn có thể cần lấy chiều rộng hoặc chiều cao của khung nhìn bên trong của cửa sổ không có thanh cuộn và đường viền và trong những trường hợp như vậy, hãy sử dụng
Do đó, để xác định trạng thái cuộn trái hoặc trên cùng của một tài liệu, sử dụng các thuộc tính
Các giá trị trạng thái cuộn của một tài liệu cũng có thể được lấy theo cách khác và tốt hơn bằng cách sử dụng các giá trị
Các phương thức
Hai phương thức cửa sổ này về cơ bản là cùng một phương thức và cho phép bạn cuộn trang đến các tọa độ cụ thể (
Để trực quan hóa điều này, hãy chạy mã này:
Sau khi chạy
Các phương thức
Giá trị hành vi xác định cách cuộn xảy ra. Có thể là
Phương pháp
Đây là phương pháp cuộn tương đối. Phương pháp này cuộn trang tương đối với vị trí hiện tại của trang và không liên quan gì đến nguồn gốc
Để xem xét phương pháp này, chúng ta hãy sử dụng ví dụ mã từ phần phương pháp

Phương thức
Phương thức này trả về một đối tượng được gọi là đối tượng
Bạn nên lưu ý rằng trong một số trường hợp, đối tượng
Lý do cho điều này khá hợp lý:
Xem Bút [Thuộc tính DOM Rect [phân nhánh]](https://codepen.io/smashingmag/pen/KKedmYx) của Pearl Akpan.
Xem Bút Thuộc tính DOM Rect [phân nhánh] của Pearl Akpan.
Đối tượng được trả về bởi phương thức
Các Tọa độ tương đối theo cửa sổ cho các sự kiện chuột được lưu trữ trong các thuộc tính
Mặt khác, tọa độ tương đối theo tài liệu cho các sự kiện chuột và con trỏ được lưu trữ trong các thuộc tính
Chúng tôi sẽ xem xét bốn giải pháp giao diện người dùng hàng ngày được sử dụng trong các trang web và ứng dụng web hiện đại hàng ngày có thể được tạo bằng các API này.
Trong phần này, chúng tôi sẽ chỉ tập trung vào mã JavaScript để triển khai các giải pháp giao diện người dùng này, không phải CSS hay HTML.
Sau đây là cách triển khai nút cuộn lên đầu:
Xem Bút [Cuộn Lên Đầu [phân nhánh]](https://codepen.io/smashingmag/pen/VwdvWwK) của Pearl Akpan.
Xem Bút Cuộn Lên Đầu [forked] của Pearl Akpan.
Để đạt được điều này, chúng ta cần tạo một nút cuộn lên đầu. Trong tệp
Sau đó, chúng ta đăng ký một trình xử lý cho sự kiện này để thực thi (xử lý) những gì xảy ra khi nhấp vào nút này. Mã trong trình xử lý sự kiện gọi phương thức
Đối với trải nghiệm người dùng, chắc chắn sẽ không có tác dụng gì khi thấy nút cuộn lên đầu nếu người dùng đã ở đầu trang:
Mã trên chỉ hiển thị nút cuộn lên đầu khi người dùng đã cuộn một khoảng cách bằng cách sử dụng giá trị
Bạn có đoán được trình duyệt biết cách tải thêm nội dung khi người dùng cuộn xuống trang không? Làm thế nào để xác định khi nào người dùng đã đến cuối trang?
Chúng ta biết rằng
Xem Bút [Cuộn vô hạn - [phân nhánh]](https://codepen.io/smashingmag/pen/OJEygVz) của Pearl Akpan.
Xem Bút Cuộn vô hạn - [phân nhánh] của Pearl Akpan.
Cây bút này sử dụng kỹ thuật cuộn vô hạn để nạp thẻ vào trang cho đến khi chúng đạt đến số lượng tối đa. Ở dạng cơ bản nhất, nó mô phỏng cách các trang web thương mại điện tử hiển thị kết quả tìm kiếm cho sản phẩm. Hãy cùng phân tích cách thực hiện điều này.
Chúng tôi sử dụng HTML và CSS để xác định hình thức và kiểu của hộp đựng thẻ và các kiểu mà mỗi phần tử có lớp
Đầu tiên, chúng tôi lấy và gán cho các hằng số những nội dung sau:
Chúng ta cần viết một bài kiểm tra để kiểm tra khi nào người dùng ở cuối trang và tải các thẻ. Theo phỏng đoán trước đó của chúng ta, nếu
Trong bút của chúng ta, chúng ta thêm một trình lắng nghe sự kiện cuộn vào tài liệu của mình và sử dụng một hàm mũi tên để xử lý sự kiện cuộn. Hàm này “xử lý” tất cả các hành động liên quan đến việc tải thẻ nhưng chỉ thực hiện khi người dùng thực sự ở cuối trang đó, tức là điều kiện
Khi người dùng ở cuối trang, chúng ta khởi tạo một hằng số,
Trong mã của chúng tôi, chúng tôi sử dụng giá trị của
Bây giờ chúng ta thêm một trình lắng nghe sự kiện cuộn vào tài liệu của mình và đăng ký một trình xử lý kiểm tra xem phần tử có hiển thị 50 pixel trên khung nhìn hay không. Nếu điều kiện trả về true, lớp hoạt hình sẽ được thêm vào phần tử hiển thị một lần và mãi mãi.
Hãy xem kết quả cuối cùng của cây bút này, nơi tôi triển khai một thanh trượt cơ bản:
Xem Bút [Thanh trượt phạm vi [phân nhánh]](https://codepen.io/smashingmag/pen/QWxjgKJ) của Pearl Akpan.
Xem Bút Thanh trượt phạm vi [phân nhánh] của Pearl Akpan.
Chúng tôi sử dụng HTML và CSS để định nghĩa và định kiểu cho các phần tử được chỉ định bằng các lớp
Vì vậy, chúng tôi đang lấy và gán các phần tử
Theo trình tự cơ bản nhất, kéo và thả được thực hiện bằng cách:
Các sự kiện cần có trình xử lý, vì vậy chúng ta khai báo trình xử lý cho từng sự kiện
Vai trò của trình xử lý này là chuẩn bị phần tử để di chuyển. Ví dụ, nếu phần tử được định vị tĩnh, để chuẩn bị cho phần tử cho sự kiện di chuyển hoặc "kéo", trình xử lý
Khởi tạo
Cuối cùng, trong trình xử lý này, chúng ta thêm trình lắng nghe sự kiện
Hàm thứ hai,
Chúng tôi muốn giới hạn việc kéo
Điều này được thực hiện bằng cách thao tác giá trị kiểu
Hàm cuối cùng,
Vì các sự kiện này được thiết lập để bắt đầu theo một chuỗi liên tục, nên hợp lý khi trình xử lý của chúng không tiếp tục chạy sau khi sự kiện
Cuối cùng, chúng ta thêm trình lắng nghe sự kiện
Khi không xem xét đến thao tác DOM nặng nề, tôi tin rằng các phương thức và thuộc tính trong API này cung cấp cho chúng ta rất nhiều công cụ để tùy chỉnh các thuộc tính hình học của các thành phần web để phù hợp với các nhu cầu giao diện khác nhau.
Điều kiện tiên quyết:
- Ôn tập về Hệ tọa độ;
- Hiểu biết về Bố cục và Định vị CSS;
- Viết các lệnh gọi lại trong JavaScript;
- Một chút kiên nhẫn.
- Mô-đun Chế độ xem CSSOM
- Tại sao các Phương thức và Thuộc tính Hình học lại Quan trọng?
- Hình học Nút Phần tử
- Hình học cửa sổ và tài liệu
- Tọa độ
- Các trường hợp sử dụng
Mô-đun chế độ xem CSSOM
Mô hình đối tượng CSS (CSSOM) là một tập hợp các API cho phép thao tác CSS từ JavaScript. Giống như DOM cung cấp giao diện để thao tác HTML, CSSOM cho phép tác giả đọc và thao tác CSS.Chế độ xem CSSOM là một mô-đun CSS chứa một loạt các thuộc tính và phương thức, tất cả được đóng gói lại để cung cấp cho tác giả một giao diện riêng để lấy thông tin về chế độ xem trực quan của các thành phần. Các thuộc tính trong mô-đun này chủ yếu là chỉ đọc và được tính toán mỗi lần chúng được truy cập — các giá trị trực tiếp.
Hiện tại, Mô-đun Chế độ xem CSSOM chỉ là bản nháp đang hoạt động và đang được sửa đổi trong Bảng thông số kỹ thuật của W3C. Do đó, bản chất của nó là xác định các giao diện này, cả giao diện đã tồn tại và giao diện mới, theo cách có thể tương thích trên nhiều trình duyệt.
Tại sao các phương pháp và thuộc tính hình học lại quan trọng?
Theo quan điểm của tôi, có một số lý do để thử hiểu và sử dụng các thuộc tính và phương thức Chế độ xem CSSOM.Đầu tiên, không phải giao diện người dùng hàng ngày yêu cầu các thành phần có thể di chuyển để đạt được các câu chuyện người dùng cơ bản nhất của nó. Trừ khi bạn đang xây dựng giao diện trò chơi, bạn có thể không phải lúc nào cũng cần làm cho các thứ có thể di chuyển trên trang web của mình. Các thuộc tính hình học rất hữu ích mặc dù có những điều này vì khả năng thao tác theo chương trình chế độ xem trực quan của các phần tử DOM cung cấp cho các nhà phát triển nhiều siêu năng lực hơn để triển khai giao diện người dùng động.
Bảng Kanban được triển khai vì các thành phần có thể được kéo và thả ở các phần có liên quan. Nhiều nội dung hơn được tải khi người dùng cuộn xuống cuối tài liệu vì các giá trị vị trí cuộn có thể đọc được. Vì vậy, mặc dù có vẻ không rõ ràng ngay lập tức, nhưng thông qua việc biết thông tin chính xác về kích thước và vị trí của các phần tử mà các tính năng này có thể đạt được.
Thứ hai, khi xem tài liệu HTML trong trình duyệt web, các Phần tử DOM được hiển thị dưới dạng hình dạng trực quan, do đó, chúng có biểu diễn trực quan tương ứng mà trình duyệt có thể xem/trực quan. Truy cập các thuộc tính trực quan trực tiếp của các phần tử DOM này thông qua các thuộc tính và phương thức Chế độ xem CSSOM mang lại lợi thế hơn so với các thuộc tính CSS thông thường. Và sau đó bạn hỏi cách:
- Sau khi thiết lập các thuộc tính width và height của các phần tử HTML trong CSS, thuộc tính CSS box-sizing cuối cùng sẽ thiết lập cách tính tổng chiều rộng và chiều cao của phần tử. Điều này tạo ra JavaScript dễ bị lỗi nếu giá trị của box-sizing của chúng ta thay đổi.
- Thứ hai, hầu như không có cách nào để đọc giá trị số chính xác của chiều rộng của phần tử được đặt thành auto. Và đôi khi, chúng ta cần chiều rộng theo pixel và kích thước chính xác.
Hình học nút phần tử
Độ lệch
Không giống như các thuộc tính khác trong CSSOM View, các thuộc tính độ lệch chỉ khả dụng cho các nútTọa độ được chỉ định bằng mô hình "độ lệch" sử dụng góc trên cùng bên trái của phần tử đang được kiểm tra hoặc nơi sự kiện đã xảy ra.
— MDN
HTMLElement
bắt nguồn từ nút Element. Do đó, bạn không thể đọc các thuộc tính bù trừ của SVGElement
vì chúng không tồn tại.
Offset Left và Top
Sử dụng các thuộc tính chỉ đọc offsetLeft
và offsetTop
sẽ cung cấp tọa độ x
/y
của một phần tử so với offsetParent
của nó. Thuộc tính offsetLeft
trả về khoảng cách của đường viền ngoài bên trái của phần tử hiện tại so với đường viền trong bên trái của offsetParent
trong khi thuộc tính offsetTop
trả về khoảng cách của đường viền trên cùng bên ngoài của phần tử hiện tại so với đường viền trên cùng bên trong của offsetParent
.Offset Parent
offsetParent
của bất kỳ phần tử nào là phần tử tổ tiên gần nhất của nó có thuộc tính vị trí CSS không tĩnh, phần tử
,
hoặc [TABLE]
hoặc ở phần gốc, phần tử
.Chiều rộng và chiều cao offset
Các thuộc tính chỉ đọc này cung cấp kích thước bên ngoài đầy đủ của các nút phần tử. offsetWidth
được xác định bằng cách tính tổng kích thước của đường viền dọc, phần đệm và nội dung của phần tử, bao gồm bất kỳ thanh cuộn nào có thể tồn tại. offsetHeight
được tính theo cách tương tự bằng cách sử dụng đường viền ngang, phần đệm và chiều cao nội dung của phần tử.Clients

Client Left và Top
Theo nghĩa cơ bản nhất, các thuộc tính chỉ đọc này cung cấp kích thước tính bằng pixel của chiều rộng đường viền trái và chiều rộng đường viền trên cùng của phần tử. Tuy nhiên, theo nghĩa sâu hơn, giá trị của các thuộc tính clientLeft
và clientTop
của một phần tử cung cấp tọa độ tương đối của mặt trong (đệm ngoài) của phần tử đó so với mặt ngoài (viền ngoài) của nó.Vì vậy, khi một tài liệu có hướng viết từ phải sang trái và thanh cuộn dọc bên trái, thì
clientLeft
sẽ trả về các giá trị tọa độ, bao gồm kích thước của thanh cuộn. Điều này là do thanh cuộn hiển thị giữa mặt trong (đệm ngoài) của phần tử đó so với mặt ngoài (viền ngoài).Chiều rộng và chiều cao của Client
Các thuộc tính clientWidth
và clientHeight
chỉ đọc của một phần tử trả về kích thước của vùng bên trong đường viền của phần tử. Thuộc tính clientWidth
sẽ trả về kích thước của chiều rộng nội dung của phần tử và phần đệm dọc của phần tử đó mà không có thanh cuộn. Nếu không có phần đệm, thì clientWidth
chỉ là kích thước của chiều rộng nội dung của phần tử đó. Điều này cũng tương tự đối với thuộc tính clientHeight
, thuộc tính này sẽ trả về kích thước của chiều cao nội dung của phần tử cộng với phần đệm ngang và nếu không có phần đệm nào, thuộc tính này sẽ chỉ trả về chiều cao nội dung là clientHeight
.Cuộn

Cuộn sang trái và lên trên
Một phần tử không có nội dung tràn trên trục x
hoặc trục y
của nó sẽ trả về 0
khi các thuộc tính scrollLeft
và scrollTop
của nó được truy vấn tương ứng. Thuộc tính scrollLeft
của một phần tử trả về khoảng cách tính bằng pixel mà nội dung của phần tử được cuộn theo chiều ngang, trong khi thuộc tính scrollTop
cung cấp khoảng cách tính bằng pixel mà nội dung của phần tử được cuộn theo chiều dọc.Các pixel được trả về bởi thuộc tính
scrollLeft
và scrollTop
của một phần tử không phải lúc nào cũng có thể xem được trong khung nhìn có thể cuộn hoặc vùng máy khách do quá trình cuộn. Các pixel có thể được xem như biểu diễn kích thước của khu vực đã được cuộn đi sang trái hoặc lên trên cùng.Các thuộc tính
scrollLeft
và scrollTop
là các thuộc tính đọc-ghi, do đó các giá trị của chúng có thể được thao tác.Lưu ý: Các thuộc tính
scrollLeft
và scrollTop
không phải lúc nào cũng trả về số nguyên và có thể trả về các giá trị dấu phẩy động.Chiều rộng và chiều cao cuộn
Thuộc tính scrollWidth
của một phần tử tính toán clientWidth
của phần tử đó cộng với toàn bộ nội dung tràn ở bên trái và bên phải của phần tử đó, trong khi thuộc tính scrollHeight
tính toán clientHeight
của phần tử đó cộng với toàn bộ nội dung tràn ở mặt trên và mặt dưới của phần tử.Đây là lý do tại sao nếu một phần tử không có nội dung tràn trên trục
x
hoặc y
của nó, thì các thuộc tính scrollWidth
và scrollHeight
của nó sẽ trả về cùng một giá trị tương ứng với các thuộc tính clientWidth
và clientHeight
của nó.MDN giải thích các giá trị thuộc tính
scrollWidth
và scrollHeight
như sau:“… Bằng chiều rộng hoặc chiều cao tối thiểu mà phần tử cần để vừa với toàn bộ nội dung trong khung nhìn mà không cần sử dụng thanh cuộn ngang hoặc dọc.”
Hình học cửa sổ và tài liệu
Các thuộc tính hình học của tài liệu được tải trong cửa sổ và bản thân cửa sổ có liên quan vì một số lý do. Đôi khi chúng ta cần đọc chiều rộng của toàn bộ khung nhìn và toàn bộ chiều cao của tài liệu, đôi khi chúng ta thậm chí muốn cuộn một trang đến một mức độ nhất định nào đó và vân vân. Vâng, tất nhiên, các thuộc tính để đọc các giá trị và thông tin có liên quan không bị bỏ sót trong CSSOM View Module.Giao diệnCửa sổ
biểu diễn một cửa sổ chứa tài liệu DOM; thuộc tínhdocument
trỏ đến tài liệu DOM được tải trong cửa sổ đó.
Vì có một phần tử
gốc (được gắn nhãn là Document.documentElement
trong DOM) định nghĩa toàn bộ tài liệu HTML, chúng ta cũng có thể lấy các thuộc tính chiều cao, chiều rộng và vị trí khác nhau của tài liệu HTML bằng cách truy vấn phần tử gốc.
Chiều rộng và chiều cao cửa sổ
Các thuộc tính để tính chiều rộng và chiều cao của cửa sổ được chia thành các thuộc tính chiều rộng và chiều cao bên trong và bên ngoài. Để tính chiều rộng và chiều cao bên ngoài của cửa sổ, các thuộc tính chỉ đọcouterWidth
và outerHeight
được sử dụng và chúng lần lượt trả về chiều rộng và chiều cao của toàn bộ cửa sổ trình duyệt.Để có được chiều rộng và chiều cao bên trong của cửa sổ, các thuộc tính
innerWidth
và innerHeight
được sử dụng. Giá trị được trả về là chiều rộng và chiều cao (bao gồm thanh cuộn) của toàn bộ khung nhìn nơi tài liệu hiển thị.Bạn có thể cần lấy chiều rộng hoặc chiều cao của khung nhìn bên trong của cửa sổ không có thanh cuộn và đường viền và trong những trường hợp như vậy, hãy sử dụng
clientWidth
hoặc clientHeight
trên Document.documentElement
, đây là phần tử gốc biểu diễn cho tài liệu.Chiều rộng và chiều cao của tài liệu
Chúng tôi không bao giờ đặt giá trị đường viền, khoảng đệm hoặc lề trên chính phần tử gốc. Tuy nhiên, trên các phần tử có trong Tài liệu, sử dụng các thuộc tínhscrollWidth
và scrollHeight
trên phần tử gốc Document.documentElement
sẽ trả về toàn bộ chiều rộng và chiều cao của tài liệu.Giá trị cuộn của cửa sổ và tài liệu
Cuộn trái và trên cùng
Như đã khám phá trong phần Hình học nút phần tử, các thuộc tínhscrollLeft
và scrollTop
trả về kích thước pixel của vùng cuộn trái hoặc trên cùng của một phần tử.Do đó, để xác định trạng thái cuộn trái hoặc trên cùng của một tài liệu, sử dụng các thuộc tính
scrollLeft
và scrollTop
trên Document.documentElement
sẽ trả về các giá trị biểu thị kích thước của phần Tài liệu đã được cuộn đi và không hiển thị trong khung nhìn của cửa sổ.Các giá trị trạng thái cuộn của một tài liệu cũng có thể được lấy theo cách khác và tốt hơn bằng cách sử dụng các giá trị
window.pageXOffset
và window.pageYOffset
.Các phương pháp cuộn cửa sổ và tài liệu
Chúng ta có thể cuộn trang theo chương trình để phản hồi một số tương tác của người dùng bằng các phương pháp cuộn được xác định trong Mô-đun chế độ xem CSSOM. Hãy cùng xem xét chúng.Các phương thức scroll()
và scrollTo()
Hai phương thức cửa sổ này về cơ bản là cùng một phương thức và cho phép bạn cuộn trang đến các tọa độ cụ thể (x
, y
) trong Tài liệu. Các giá trị tọa độ biểu thị vị trí tuyệt đối từ góc trên cùng và góc trái của chính tài liệu.Để trực quan hóa điều này, hãy chạy mã này:
Mã:
window.scrollTo(0, 500);//Cuộn trang theo chiều dọc đến 500 pixel từ gốc trang (0, 0).window.scrollTo(0, 500);//Trang vẫn ở cùng một điểm.
window.scrollTo(0, 500)
lần đầu tiên, việc chạy lần thứ hai sẽ không có tác dụng gì vì trang đã ở vị trí tuyệt đối cách gốc của Tài liệu 500 pixel trên trục y
của nó.Các phương thức
scroll()
và scrollTo()
định nghĩa các tham số x
và y
cho các đối số tương ứng biểu diễn số pixel theo trục ngang và trục dọc tương ứng mà bạn muốn trang được cuộn đến hoặc một từ điển các tùy chọn chứa các giá trị trên cùng, bên trái và hành vi.Giá trị hành vi xác định cách cuộn xảy ra. Có thể là
"smooth"
, tạo hiệu ứng cuộn mượt mà, hoặc "auto"
, làm cho việc cuộn giống như một cú nhảy nhanh đến tọa độ đã chỉ định.Phương pháp scrollBy()
Đây là phương pháp cuộn tương đối. Phương pháp này cuộn trang tương đối với vị trí hiện tại của trang và không liên quan gì đến nguồn gốc Document
.Để xem xét phương pháp này, chúng ta hãy sử dụng ví dụ mã từ phần phương pháp
scroll()
và scrollTo()
:
Mã:
window.scrollTo(0, 500);//Cuộn trang 500 pixel từ vị trí hiện tại, chẳng hạn như (0, 0), đến (0, 500).window.scrollTo(0, 500);//Cuộn trang thêm 500 pixel từ vị trí hiện tại đến (0, 1000).
Tọa độ
Hệ thống tọa độ là nguyên nhân gây ra cách xác định vị trí của các phần tử trong các phương thức và thuộc tính của CSSOM View.Khi chỉ định vị trí của một pixel trong ngữ cảnh đồ họa, vị trí của pixel đó được xác định theo điểm cố định trong ngữ cảnh. Điểm cố định này được gọi là gốc. Vị trí được chỉ định là số pixel lệch khỏi gốc dọc theo mỗi chiều của ngữ cảnh.
CSSOM sử dụng các hệ thống tọa độ chuẩn và nhìn chung chúng chỉ khác nhau về vị trí gốc của chúng.
Tọa độ cửa sổ và tài liệu
Mặc dù CSSOM sử dụng bốn hệ thống tọa độ chuẩn, nhưng hệ thống tọa độ máy khách và trang được sử dụng nhiều nhất trong Mô-đun CSSOM View. Kích thước hoặc vị trí của các phần tử thường được xác định theo tài liệu hoặc khung nhìn.Tọa độ máy khách (Tương đối với cửa sổ)
Tôi không tìm thấy mô tả nào tốt hơn về tọa độ máy khách ngoài mô tả từ MDN:Giá trị tọa độ máy khách tương tự như khi sử dụngHệ tọa độ "máy khách" sử dụng góc trên cùng bên trái của khung nhìn hoặc ngữ cảnh duyệt trong đó sự kiện xảy ra làm gốc. Đây là toàn bộ vùng xem trong đó tài liệu được trình bày. Cuộn không phải là một yếu tố.
position: fixed
trong CSS và được tính toán từ cạnh trên cùng bên trái của khung nhìn.Tọa độ trang (Tương đối với tài liệu)
Giá trị tọa độ trang tương tự như khi sử dụngHệ tọa độ "trang" cung cấp vị trí của một pixel theo góc trên cùng bên trái của toàn bộTài liệu
mà pixel đó nằm trong đó. Điều đó có nghĩa là một điểm nhất định trong một phần tử trong tài liệu sẽ giữ nguyên tọa độ trong mô hình trang trừ khi phần tử đó di chuyển (trực tiếp bằng cách thay đổi vị trí của nó hoặc gián tiếp bằng cách thêm hoặc thay đổi kích thước nội dung khác).
position: absolute
trong CSS và được tính toán từ cạnh trên bên trái của Document
. Vị trí tương đối trên trang của một phần tử sẽ luôn giữ nguyên bất kể cuộn, trong khi vị trí tương đối trên cửa sổ của nó sẽ phụ thuộc vào việc cuộn tài liệu.Tọa độ phần tử

Phương thức Element.getBoundingClientRect()
Phương thức này trả về một đối tượng được gọi là đối tượng DOMRect
có các thuộc tính là vị trí pixel tương đối với cửa sổ và kích thước của một phần tử. Đây là phương pháp duy nhất bạn cần sử dụng khi cần thao tác một phần tử liên quan đến khung nhìn.Bạn nên lưu ý rằng trong một số trường hợp, đối tượng
DOMRect
được trả về không phải lúc nào cũng giữ cùng giá trị thuộc tính hoặc kích thước cho cùng một phần tử. Điều này đặc biệt đúng bất cứ khi nào các phép biến đổi (xoay, xoay, chia tỷ lệ) được thêm vào một phần tử.Lý do cho điều này khá hợp lý:
Bạn có thể hình dung điều này bằng cách nhấp vào nút hiển thị trong bút bên dưới:Trong trường hợp biến đổi,offsetWidth
vàoffsetHeight
trả về chiều rộng và chiều cao bố cục của phần tử, trong khigetBoundingClientRect()
trả về chiều rộng và chiều cao kết xuất. Ví dụ, nếu phần tử cówidth: 100px;
vàtransform: scale(0.5);
thìgetBoundingClientRect()
sẽ trả về 50 là chiều rộng, trong khioffsetWidth
sẽ trả về 100.
— MDN
Xem Bút [Thuộc tính DOM Rect [phân nhánh]](https://codepen.io/smashingmag/pen/KKedmYx) của Pearl Akpan.
Xem Bút Thuộc tính DOM Rect [phân nhánh] của Pearl Akpan.
Đối tượng được trả về bởi phương thức
getBoundingClientRect()
chứa sáu thuộc tính kích thước của phần tử mà phương thức được gọi. Các thuộc tính này là:-
x
vày
trả về tọa độ x và y của gốc phần tử so với cửa sổ; -
top
vàbottom
trả về tọa độ y cho cạnh trên và dưới của hộp phần tử; -
left
vàright
trả về tọa độ x cho cạnh trái và phải của hộp phần tử; -
height
vàwidth
trả về toàn bộ chiều rộng và chiều cao của phần tử như thể phần tử được đặt thànhbox-sizing: border-box
.
Tọa độ sự kiện chuột và con trỏ
Tất cả các đối tượng sự kiện chuột hoặc con trỏ đều có các thuộc tính tọa độ xác định cả tọa độ tương đối với cửa sổ và tương đối với tài liệu nơi xảy ra sự kiện chuột hoặc con trỏ.Các Tọa độ tương đối theo cửa sổ cho các sự kiện chuột được lưu trữ trong các thuộc tính
clientX
và clientY
biểu thị tương ứng các tọa độ x
và y
.Mặt khác, tọa độ tương đối theo tài liệu cho các sự kiện chuột và con trỏ được lưu trữ trong các thuộc tính
pageX
và pageY
của đối tượng sự kiện cho tương ứng các tọa độ x
và y
.Các trường hợp sử dụng
Các API trong Mô-đun Chế độ xem CSSOM kết hợp các phương thức và thuộc tính cơ bản nhất nhưng hữu ích nhất để truy cập các thuộc tính hình học của các Phần tử DOM khi được hiển thị trong trình duyệt. Vì các thuộc tính này đang hoạt động nên chúng đáng tin cậy hơn trong các trường hợp cụ thể so với các giá trị CSS của chúng. Nhưng làm thế nào các API này có thể được sử dụng để tạo ra các tính năng giao diện người dùng thực tế?Chúng tôi sẽ xem xét bốn giải pháp giao diện người dùng hàng ngày được sử dụng trong các trang web và ứng dụng web hiện đại hàng ngày có thể được tạo bằng các API này.
Trong phần này, chúng tôi sẽ chỉ tập trung vào mã JavaScript để triển khai các giải pháp giao diện người dùng này, không phải CSS hay HTML.
Thành phần cuộn lên trên
Nút cuộn lên đầu cho phép người dùng nhanh chóng quay lại đầu trang mà không tốn nhiều công sức. API CSSOM View cung cấp một phương pháp đơn giản để đạt được điều này với các phương thứcscrollTo()
và sao chép các phương thức scroll()
.Sau đây là cách triển khai nút cuộn lên đầu:
Xem Bút [Cuộn Lên Đầu [phân nhánh]](https://codepen.io/smashingmag/pen/VwdvWwK) của Pearl Akpan.
Xem Bút Cuộn Lên Đầu [forked] của Pearl Akpan.
Để đạt được điều này, chúng ta cần tạo một nút cuộn lên đầu. Trong tệp
js
của mình, chúng ta thêm trình lắng nghe sự kiện "click"
vào nút này:
Mã:
scrollToTop.addEventListener("click", (e) => { window.scrollTo({left: 0, top: 0, behavior: "smooth"});});
scrollTo()
của cửa sổ, với các giá trị xác định đầu trang và hành vi cuộn.Đối với trải nghiệm người dùng, chắc chắn sẽ không có tác dụng gì khi thấy nút cuộn lên đầu nếu người dùng đã ở đầu trang:
Mã:
document.addEventListener("scroll", (e)=> { if(window.pageYOffset >= 500) { scrollToTop.style.display = "block"; } else { scrollToTop.style.display = "none"; }});
window.pageYOffset
để xác định trang đã được cuộn đến đâu. Nếu trang đã được cuộn lên đến 500 pixel lên trên cùng, thành phần cuộn lên trên sẽ hiển thị và nếu không, thành phần này sẽ vẫn ẩn.Cuộn vô hạn
Với việc triển khai trên các phương tiện truyền thông xã hội phổ biến, cuộn vô hạn cho phép người dùng cuộn xuống một trang; nhiều nội dung hơn sẽ tự động và liên tục tải ở cuối trang, giúp người dùng không cần phải nhấp vào trang tiếp theo.Bạn có đoán được trình duyệt biết cách tải thêm nội dung khi người dùng cuộn xuống trang không? Làm thế nào để xác định khi nào người dùng đã đến cuối trang?
Chúng ta biết rằng
document.scrollHeight
cung cấp chiều cao tổng thể của một tài liệu, document.clientHeight
cung cấp kích thước của màn hình hoặc khung nhìn có thể xem và document.scrollTop
hoặc window.pageYOffset
cung cấp kích thước của phần tài liệu đã được cuộn lên trên cùng. Chúng ta có thể đoán một cách trực quan rằng nếu document.scrollTop + document.clientHeight >= document.scrollHeight
, thì người dùng đã đến cuối trang không? Tôi nghĩ vậy.Xem Bút [Cuộn vô hạn - [phân nhánh]](https://codepen.io/smashingmag/pen/OJEygVz) của Pearl Akpan.
Xem Bút Cuộn vô hạn - [phân nhánh] của Pearl Akpan.
Cây bút này sử dụng kỹ thuật cuộn vô hạn để nạp thẻ vào trang cho đến khi chúng đạt đến số lượng tối đa. Ở dạng cơ bản nhất, nó mô phỏng cách các trang web thương mại điện tử hiển thị kết quả tìm kiếm cho sản phẩm. Hãy cùng phân tích cách thực hiện điều này.
Chúng tôi sử dụng HTML và CSS để xác định hình thức và kiểu của hộp đựng thẻ và các kiểu mà mỗi phần tử có lớp
thẻ
phải có. Trong bút của mình, chúng tôi mã hóa cứng bộ thẻ đầu tiên bằng HTML.Đầu tiên, chúng tôi lấy và gán cho các hằng số những nội dung sau:
- phần tử hộp đựng thẻ, là phần tử cha cho tất cả các thẻ;
- phần tử trạng thái hiển thị số lượng thẻ hiện tại đã tải.
totalCardsNo
và cardLoadAmount
để lưu trữ các giá trị cho số lượng thẻ tối đa và số lượng thẻ được thêm vào:
Mã:
const cardContainer = document.querySelector("main");const currentCardStats = document.querySelector(".currentCardNo");const cardLoadAmount = 9;const totalCardsNo = 90;let lastIndex;
document.scrollTop + document.clientHeight >= document.scrollHeight
, thì người dùng của chúng ta ở cuối trang.Trong bút của chúng ta, chúng ta thêm một trình lắng nghe sự kiện cuộn vào tài liệu của mình và sử dụng một hàm mũi tên để xử lý sự kiện cuộn. Hàm này “xử lý” tất cả các hành động liên quan đến việc tải thẻ nhưng chỉ thực hiện khi người dùng thực sự ở cuối trang đó, tức là điều kiện
document.scrollTop + document.clientHeight >= document.scrollHeight
trả về true
:
Mã:
document.addEventListener("scroll", (e) => { if (document.documentElement.scrollTop + document.documentElement.clientHeight >= document.documentElement.scrollHeight) { const children = cardContainer.children; lastIndex = children.length; }});
children
, để giữ một HTMLCollection
của tất cả các thẻ hiện đang được tải, là các thẻ con hiện tại của cardContainer
. Độ dài của children
cũng biểu diễn chỉ mục (không phải chỉ mục dạng mảng) của thẻ cuối cùng và chúng tôi lưu trữ giá trị đó trong biến lastIndex
.Trong mã của chúng tôi, chúng tôi sử dụng giá trị của
lastIndex
để biết có nên tải thêm thẻ hay không hoặc chúng tôi đã đạt đến totalCardsNo
sau đó chúng tôi không thể tải thêm thẻ nữa. Nếu giá trị của lastIndex
nhỏ hơn totalCardNo
, chúng tôi tải thêm thẻ:
Mã:
if(lastIndex < totalCardsNo) { for(let i = 1; i { animatingElements.forEach((el) => { if(el.getBoundingClientRect().top + 50 < document.documentElement.clientHeight) { el.classList.add("animated"); } else { return; } });});
Range Slider
Mặc dù có thể khác nhau về cách triển khai và sử dụng, nhưng range slider là một trong những thành phần web phổ biến nhất. Chúng là các điều khiển đầu vào cho phép người dùng chọn giá trị hoặc thay đổi trạng thái từ một điều khiển hoặc thanh trượt.Hãy xem kết quả cuối cùng của cây bút này, nơi tôi triển khai một thanh trượt cơ bản:
Xem Bút [Thanh trượt phạm vi [phân nhánh]](https://codepen.io/smashingmag/pen/QWxjgKJ) của Pearl Akpan.
Xem Bút Thanh trượt phạm vi [phân nhánh] của Pearl Akpan.
Chúng tôi sử dụng HTML và CSS để định nghĩa và định kiểu cho các phần tử được chỉ định bằng các lớp
.track
và .thumb
tương ứng. Kỹ thuật "kéo" là triển khai chính trong thanh trượt vì ngón tay cái được kéo trong rãnh, điều này xác định một số loại phạm vi.Vì vậy, chúng tôi đang lấy và gán các phần tử
.track
và .thumb
cho các hằng số. Sau đó, chúng tôi khai báo nhưng không khởi tạo các biến draggable
và shiftX
, để sử dụng sau:
Mã:
const thumb = document.querySelector(".thumb");const slider = document.querySelector(".track");let draggable;let x;
- Di chuyển con trỏ đến đối tượng.
- Nhấn và giữ nút trên chuột hoặc thiết bị trỏ khác để "lấy" đối tượng (được định nghĩa là sự kiện "
pointerdown
"). - "Kéo" đối tượng đến vị trí mong muốn bằng cách di chuyển con trỏ đến vị trí đó được định nghĩa là sự kiện "
pointermove
"). - "Thả" đối tượng bằng cách nhả nút được định nghĩa là sự kiện "
pointerup
").
Các sự kiện cần có trình xử lý, vì vậy chúng ta khai báo trình xử lý cho từng sự kiện
pointerdown
, pointermove
và pointerup
. Trình xử lý đầu tiên mà chúng ta khai báo là hàm prepDrag
cho sự kiện pointerdown
. Sự kiện pointerdown
được kích hoạt bất cứ khi nào chuột hoặc con trỏ được nhấn xuống phần tử có trình lắng nghe sự kiện:
Mã:
function prepDrag(event) { draggable = event.target; x = event.clientX - draggable.getBoundingClientRect().left; document.addEventListener("pointermove", startDrag); document.addEventListener("pointerup", endDrag);}
prepDrag
sẽ phải đặt vị trí của phần tử thành absolute
hoặc relative
để có thể thao tác vị trí của phần tử thông qua các giá trị top
, left
của nó.Khởi tạo
draggable
và x
được khai báo toàn cục trong phạm vi cục bộ của trình xử lý prepDrag
giúp các trình xử lý khác sẽ được thực thi trong phạm vi đó có thể truy cập các giá trị đó.Cuối cùng, trong trình xử lý này, chúng ta thêm trình lắng nghe sự kiện
pointermove
và pointerup
vào document
chứ không phải phần tử thumb
. Lý do là sự kiện mousemove
thường kích hoạt, nhưng không phải đối với mọi pixel. Do đó, nó có thể gây ra phản hồi kéo và thả không mong muốn. Thêm trình lắng nghe sự kiện vào tài liệu là cách đáng tin cậy hơn để bắt sự kiện mousemove
.Hàm thứ hai,
startDrag
, xử lý sự kiện pointermove
và thực thi tất cả logic xác định cách phần tử thumb
di chuyển và vị trí của nó bằng cách thao tác các giá trị kiểu top
và left
của nó:
Mã:
function startDrag(event) { if (event.clientX < track.offsetLeft || event.clientX > slider.getBoundingClientRect().right){ return; } draggable.style.left = event.clientX - shiftX - track.getBoundingClientRect().left + 'px';}
ngón tay cái
vào ranh giới của đường dẫn
, sao cho ngay cả khi con trỏ di chuyển ra khỏi đường dẫn khi nhấn xuống, ngón tay cái cũng không bị kéo ra ngoài.Điều này được thực hiện bằng cách thao tác giá trị kiểu
left
của draggable
chỉ khi thuộc tính clientX
của sự kiện chuột nằm trong chiều rộng của đường dẫn. Do đó, trong khi con trỏ được nhấn xuống và di chuyển, kiểu vị trí trái
của phần tử draggable
chỉ thay đổi nếu giá trị clientX
của sự kiện chuột không nhỏ hơn giá trị offsetLeft
của track cũng không lớn hơn giá trị getBoundingClientRect().right
của track.Hàm cuối cùng,
endDrag
, xử lý sự kiện pointerup
. Nó xóa trình lắng nghe sự kiện pointermove
và pointerup
khỏi tài liệu:
Mã:
function endDrag() { document.removeEventListener("pointermove", startDrag); document.removeEventListener("pointerup", endDrag);}
pointerdown
(bắt đầu chuỗi) kết thúc:
Mã:
thumb.addEventListener("pointerdown", prepDrag);
pointerdown
vào phần tử thumb
để đăng ký trình xử lý cho sự kiện đầu tiên mà chúng ta lắng nghe.Kết luận
Các trường hợp sử dụng được đề cập trong bài viết này chỉ là một phần nhỏ trong những gì có thể đạt được với CSSOM View Module API.Khi không xem xét đến thao tác DOM nặng nề, tôi tin rằng các phương thức và thuộc tính trong API này cung cấp cho chúng ta rất nhiều công cụ để tùy chỉnh các thuộc tính hình học của các thành phần web để phù hợp với các nhu cầu giao diện khác nhau.