Cách sử dụng API kéo và thả HTML
Kéo và thả là một tính năng thiết yếu giúp tăng cường tương tác người dùng và tạo điều kiện cho trải nghiệm người dùng liền mạch. Cho dù bạn đang tìm cách xây dựng trình tải tệp lên, danh sách có thể sắp xếp hay trò chơi tương tác thì việc hiểu cách khai thác các khả năng của API này là một kỹ năng quan trọng cần có trong bộ công cụ phát triển web của bạn.
Khái niệm cơ bản về kéo và thả trong HTML
danh mục ban đầu bao gồm các phần tử có thể được thao tác bằng thiết bị trỏ, chẳng hạn như chuột và được di chuyển đến các khu vực thay thế; trong khi danh mục thứ hai bao gồm các phần tử thường mô tả các đích đến được chỉ định cho các phần tử nói trên, cho phép người dùng thả chúng vào các vị trí đó.
Để kích hoạt chức năng kéo và thả trong ứng dụng web, cần chỉ định thành phần nào được dùng để thao tác thông qua việc sử dụng thuộc tính “có thể kéo” trong đánh dấu HTML tương ứng của chúng. Bằng cách đặt giá trị của thuộc tính này thành “true”, chẳng hạn như trong ví dụ được cung cấp, người dùng có thể di chuyển hoặc định vị lại phần tử nhất định trong giao diện thông qua hành động kéo và thả.
<div draggable="true">This element is draggable</div>
Khi bắt đầu thao tác kéo bằng sự kiện đầu vào do người dùng tạo được gọi là “sự kiện kéo”, trình duyệt web thường cung cấp một biểu diễn giữ chỗ được gọi là hình ảnh “ma”. Dấu hiệu trực quan này dùng để chỉ ra và cung cấp phản hồi liên quan đến trạng thái hoặc tiến trình của một phần tử đang được thao tác thông qua quá trình kéo.
Bạn có tùy chọn cá nhân hóa hình minh họa này bằng cách cung cấp nội dung trực quan của riêng bạn vào vị trí của nó. Điều này có thể đạt được bằng cách chọn thành phần có thể di chuyển được từ Mô hình đối tượng tài liệu (DOM), tạo ra một hình ảnh mới để làm đồ họa phản hồi phù hợp và kết hợp một
let img = new Image();
img.src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Twemoji_1f600.svg/220px-Twemoji_1f600.svg.png';
document.querySelector('div').addEventListener('dragstart', (event)=>{
event.dataTransfer.setDragImage(img, 10, 10);
})
Khối mã nói trên thể hiện cách sử dụng phương thức setDragImage
, bao gồm ba tham số đầu vào. Tham số ban đầu ám chỉ hình ảnh mong muốn, trong khi cặp tham số tiếp theo chỉ định các chuyển vị ngang và dọc tương ứng của biểu diễn hình ảnh nói trên. Khi thực thi trong trình duyệt web và bắt đầu hành động kéo một phần tử, có thể thấy rõ rằng hình ảnh kéo mặc định đã được thay thế bằng mô tả tùy chỉnh được định cấu hình trước đó.
Để cho phép giải phóng, cần phải chống lại hoạt động tiêu chuẩn bằng cách hủy bỏ cả hai trường hợp kéo và kéo, như được minh họa dưới đây:
const dropElement = document.querySelector("drop-target");
dropElement.addEventListener("dragenter", (ev) => {
ev.preventDefault();
});
dropElement.addEventListener("dragover", (ev) => {
ev.preventDefault();
});
Tìm hiểu giao diện DragEvent
JavaScript cung cấp giao diện DragEvent, gói gọn tương tác kéo và thả của người dùng. Sau đây là một số loại sự kiện được liên kết với giao diện này:
Trong quá trình kéo một phần tử cụ thể, người dùng sẽ kích hoạt sự kiện “kéo”.
Sự kiện dragend được kích hoạt sau khi hoàn thành thao tác kéo, do nhả nút chuột hoặc nhấn phím thoát.
Sự kiện dragenter
được kích hoạt bởi phần tử được kéo khi nó di chuyển qua mục tiêu thả hợp lệ, điều này có thể biểu thị một hành động hoặc tương tác liên quan đến việc di chuyển dữ liệu từ vị trí này sang vị trí khác trong giao diện người dùng.
Sự kiện"dragleave"được kích hoạt khi một phần tử đang được kéo không còn được định vị phía trên hoặc phía trên một mục tiêu thả cụ thể. Sự kiện này đóng vai trò như một đối trọng với sự kiện"dragenter", xảy ra khi phần tử được kéo ban đầu đi vào mục tiêu thả tiềm năng.
Trong quá trình kéo một thành phần có thể điều khiển được qua khu vực tiếp nhận, một hành động của người dùng sẽ xảy ra.
Khi bắt đầu, sự kiện “bắt đầu kéo” được kích hoạt để bắt đầu hành động kéo.
Khi nhận được thông tin đầu vào từ người dùng, chúng tôi sẽ bắt đầu hành động “thả” trong hệ thống của mình. Sự kiện này được kích hoạt khi người dùng thả một vật phẩm lên trên khu vực mục tiêu được chỉ định được thiết kế cho mục đích đó.
Khi tệp được chuyển sang trình duyệt web thông qua các phương tiện bên ngoài, chẳng hạn như công cụ quản lý tệp của hệ điều hành, trình duyệt sẽ không khởi tạo các sự kiện “dragstart” hoặc “dragend” thông thường để phản hồi.
Việc sử dụng DragEvent
có thể mang lại lợi ích khi tìm cách gửi một sự kiện kéo tùy chỉnh theo thuật toán. Bằng cách minh họa, giả sử một người muốn bắt đầu các sự kiện kéo tùy chỉnh cho một phần tử div nhất định khi tải trang. Quá trình này sẽ đòi hỏi phải tạo một phiên bản mới của DragEvent
, chẳng hạn như hiển thị bên dưới:
const customDragStartEvent = new DragEvent('dragstart', {
dataTransfer: new DataTransfer(),
})
const customDragEndEvent = new DragEvent('dragend');
Trong đoạn mã nói trên, customDragStartEvent
là bản khởi tạo của lớp DragEvent()
, chứa hai tham số hàm tạo. Tham số ban đầu biểu thị loại sự kiện kéo cụ thể, bao gồm bất kỳ loại nào trong số bảy loại sự kiện có thể được liệt kê trước đó.
Tham số thứ hai đại diện cho một đối tượng chứa thuộc tính có tên là “dataTransfer”, tương ứng với một phiên bản của giao diện DataTransfer. Giao diện này sẽ được khám phá chi tiết hơn trong suốt hướng dẫn này. Để truy cập phần tử mong muốn trong Mô hình đối tượng tài liệu (DOM), hãy làm theo các bước sau…
const draggableElement = document.querySelector("#draggable");
Sau đó thêm, người nghe sự kiện như thế này:
draggableElement.addEventListener('dragstart', (event) => {
console.log('Drag started!');
event.dataTransfer.setData('text/plain', 'Hello, world!');
});
draggableElement.addEventListener('dragend', () => {
console.log('Drag ended!');
});
Trong trình xử lý sự kiện ban đầu, chúng tôi đã sử dụng chức năng gọi lại để ghi nhật ký thông báo, “Kéo đã bắt đầu!”, đồng thời gọi phương thức setData
trên thuộc tính dataTransfer
của đối tượng sự kiện
. Điều này cho phép chúng tôi bắt đầu các sự kiện tùy chỉnh của mình một cách hiệu quả một cách liền mạch.
draggableElement.dispatchEvent(customDragStartEvent);
draggableElement.dispatchEvent(customDragEndEvent);
Truyền dữ liệu bằng dataTransfer
Đối tượng truyền dữ liệu hoạt động như một trình kết nối trung gian giữa phần tử gốc, là thực thể có thể kéo và người nhận dự định của nó hoặc vùng có thể thả. Trong quá trình kéo và thả, nó hoạt động như một kho lưu trữ tạm thời được thiết kế để lưu trữ thông tin nhằm mục đích chia sẻ giữa hai thực thể này.
Tính linh hoạt của dữ liệu này được thể hiện rõ qua khả năng xử lý nhiều định dạng, bao gồm văn bản, URLS và các loại dữ liệu tùy chỉnh, từ đó cho phép thực hiện nhiều chức năng kéo và thả.
Sử dụng setData() cho dữ liệu gói
Để truyền tải thông tin từ một thành phần có thể thao tác đến một ổ cắm, bạn có thể tận dụng các khả năng của phương thức setData()
được cung cấp bởi đối tượng dataTransfer
. Cách tiếp cận này cho phép bạn đóng gói dữ liệu mà bạn định truyền đồng thời chỉ định loại dữ liệu của nó. Một minh họa cơ bản được trình bày dưới đây:
element.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', 'Hello, world!');
});
Khi bắt đầu hành động di chuyển một mục được chỉ định là có thuộc tính cụ thể, chúng tôi sẽ gửi một tin nhắn chứa thông tin “Xin chào, thế giới!” ở định dạng được chỉ định là văn bản/thuần túy. Nội dung này được kết nối với nhau bằng hành động kéo và sau đó có thể được người nhận dự định đánh rơi sẽ lấy lại trong quá trình thả nó ra.
Lấy dữ liệu bằng getData()
Trong phạm vi của một phần tử có khả năng bị loại bỏ và đã đăng ký khả năng này thông qua việc triển khai trình xử lý sự kiện, người ta có thể truy xuất dữ liệu đã được truyền bằng cách sử dụng phương thức getData()
:
element.addEventListener('drop', (event) => {
const transferredData = event.dataTransfer.getData('text/plain');
console.log(`Received data: ${transferredData}`);
});
Đoạn mã nói trên lấy thông tin có cùng phân loại nội dung (văn bản/thuần túy) đã được thiết lập bởi thủ tục setData()
trước đó. Do đó, điều này cho phép người ta lấy và sửa đổi dữ liệu được truyền tải phù hợp với mong muốn của môi trường của thành phần có thể phân tách được.
Các trường hợp sử dụng cho giao diện kéo và thả
Việc kết hợp các khả năng kéo và thả trong các ứng dụng web có tiềm năng nâng cấp rất lớn, tuy nhiên điều quan trọng là phải hiểu rõ các tình huống và lý do cụ thể để triển khai tính năng này.
Bằng cách cho phép người dùng dễ dàng chuyển tệp từ trình khám phá tệp hoặc máy tính để bàn của máy tính bằng vùng thả được chỉ định, quá trình gửi nội dung phương tiện được sắp xếp hợp lý và thân thiện hơn với người dùng.
Trong trường hợp tương tác của người dùng với ứng dụng liên quan đến danh sách các thành phần khác nhau, bao gồm tác vụ, tệp phương tiện hoặc các mục có liên quan khác, việc cung cấp cho họ phương tiện để sắp xếp lại các mục này thông qua chức năng kéo và thả có thể nâng cao trải nghiệm tổng thể của họ bằng cách cung cấp một phương pháp trực quan và hiệu quả hơn để tổ chức nội dung.
Để tạo bảng điều khiển tương tác với khả năng báo cáo và trực quan hóa dữ liệu, chức năng kéo và thả cho phép người dùng dễ dàng sắp xếp lại các tiện ích và biểu đồ khác nhau theo sở thích của họ. Tính năng này cho phép người dùng điều chỉnh trải nghiệm bảng điều khiển cho phù hợp với nhu cầu cụ thể của họ trong thời gian thực, nâng cao khả năng sử dụng tổng thể và tính linh hoạt của nền tảng.
Lưu ý đến khả năng tiếp cận
Mặc dù sự hấp dẫn trực quan của chức năng kéo và thả có thể đóng góp tích cực vào trải nghiệm tổng thể của người dùng, nhưng bắt buộc phải đảm bảo khả năng truy cập của nó qua các khả năng đa dạng. Để đạt được tính toàn diện, hãy cân nhắc việc kết hợp các phương thức tương tác bổ sung, chẳng hạn như các tùy chọn điều khiển dựa trên bàn phím, phù hợp với người khuyết tật và mở rộng phạm vi khả năng sử dụng.