Bên dưới lớp vỏ: Kéo, Chạm và CSS Cascade
Xây dựng một bảng điều khiển UI có thể thay đổi kích thước khó hơn vẻ ngoài của nó. Bạn phải quản lý bố cục, các sự kiện chạm và các quy tắc CSS cùng một lúc.
Dưới đây là ba bài học kỹ thuật từ đợt thiết kế lại giao diện visual-diff gần đây của tôi.
- Ngừng sử dụng chiều rộng cửa sổ cho bố cục
Đừng sử dụng window.innerWidth để quyết định xem bố cục của bạn là dọc hay ngang. Nếu người dùng thay đổi kích thước cửa sổ, logic của bạn sẽ bị lỗi.
Thay vào đó, hãy sử dụng trạng thái CSS thực tế. Sử dụng getComputedStyle để kiểm tra flex-direction. Cách này sẽ đọc giá trị thực sau khi tất cả các media query đã được áp dụng. Nó đảm bảo logic kéo của bạn khớp với những gì người dùng thực sự nhìn thấy.
- Xử lý đồng thời các sự kiện chạm và chuột
Để tính năng kéo hoạt động trên cả máy tính để bàn và thiết bị di động, bạn cần một cách tiếp cận thống nhất.
- Sử dụng optional chaining để trích xuất tọa độ. Điều này cho phép một hàm xử lý cả sự kiện chuột và chạm.
- Sử dụng
{ passive: false }chotouchmove. Các trình duyệt mặc định các sự kiện chạm là passive để hỗ trợ cuộn trang. Nếu bạn không đặt giá trị này thànhfalse, bạn sẽ không thể gọie.preventDefault(). Nếu không có lệnh đó, trang sẽ bị cuộn trong khi bạn đang cố gắng kéo. - Gắn các trình lắng nghe (listeners)
movevàendvàodocument. Nếu người dùng di chuyển ngón tay quá nhanh, họ có thể rời khỏi thanh chia (divider). Việc gắn vàodocumentđảm bảo quá trình kéo vẫn tiếp tục ngay cả khi con trỏ bị lệch.
- Tránh xung đột với hệ thống hiển thị của bạn
Tôi đã gặp phải một lỗi về độ ưu tiên CSS (specificity). Tôi có một class để ẩn các bảng điều khiển và một class khác để thiết lập hướng bố cục.
Vấn đề:
.view-panel { display: none; }.diff-layout { display: flex; }
Vì hai class này có độ ưu tiên bằng nhau, class xuất hiện cuối cùng trong tệp sẽ được áp dụng. Điều này có nghĩa là các bảng điều khiển của tôi vẫn hiển thị ngay cả khi chúng đáng lẽ phải bị ẩn.
Cách khắc phục:
Đừng bao giờ để một class hỗ trợ bố cục thiết lập thuộc tính display. Hãy để class hiển thị đảm nhận việc đó.
Thay vì:
.diff-layout { display: flex; flex-direction: column; }
Hãy dùng:
.view-panel.diff-layout { flex-direction: column; }
Điều này làm tăng độ ưu tiên và đảm bảo class bố cục chỉ thay đổi hướng, chứ không phải tính hiển thị.
Nguồn: https://dev.to/bonzai2carn/under-the-hood-drag-touch-and-css-cascade-in-a-real-diff-ui-1b66
