Hoạt động Drag và Drop trong HTML5

Drag và Drop (DnD) là khái niệm Giao diện người sử dụng (User Interface) mạnh mẽ mà giúp nó dễ dàng để sao chép, đặt lại thứ tự và xóa các item với sự trợ giúp của các cú nhấn chuột. Điều này cho phép để nhấn chuột và giữ nút chuột di chuyển qua một phần tử, kéo nó tới vị trí khác, và buông nút chuột để thả phần tử tại vị trí đó.

Để thực hiện tính năng kéo và thả này trong HTML4 truyền thống, các nhà lập trình sẽ hoặc phải sử dụng chương trình Javascript phức tạp hoặc các khung Javascript khác như jQuery.

Bây giờ HTML5 đưa ra giải pháp DnD API mà mang lại sự hỗ trợ DnD tự nhiên tới trình duyệt, làm cho nó dẽ dàng hơn để mã hóa.

HTML5 DnD được hỗ trợ bởi tất cả các trình duyệt lớn như Chrome, Firefox 3.5 và Safari, …

Các sự kiện Drag và Drop

Có một số sự kiện mà xuất hiện trong suốt các bước của hoạt động kéo và thả. Bảng dưới đây liệt kê chúng:

Sự kiệnMiêu tả
dragstartĐược kích hoạt khi người sử dụng bắt đầu kéo đối tượng.
dragenterĐược kích hoạt khi con chuột được di chuyển lần đầu qua phần tử mục tiêu trong khi một hoạt động kéo diễn ra. Một Listener cho sự kiện này nên chỉ rằng có hay không một hoạt động thả được cho phép qua vị trí này. Nếu không được phép, hoặc Listener không thực hiện hoạt động nào, thì khi đó một hoạt động kéo là không được phép theo mặc định.
dragoverĐược tạo khi chuột di chuyển qua một phần tử khi một hoạt động kéo đang xảy ra. Hầu hết thời gian, hoạt động sẽ là giống như sự kiện dragenter.
dragleaveĐược tạo ra khi con chuột rời khỏi một phần tử trong khi một hoạt động kéo đang diễn ra. Listener nên gỡ bỏ bất cứ đánh dấu nào được sử dụng cho sự phản hồi hoạt động thả.
dragBắt đầu mỗi khi con chuột được di chuyển trong khi đối tượng đang được kéo.
dropSự kiện thả được tạo trên một phần tử, nơi mà hoạt động thả được xảy ra tại cuối của hoạt động kéo. Một Listener sẽ có trách nhiệm thu nhận dữ liệu đang được kéo và chèn nó tại vị trí thả.
dragendTạo ra khi người sử dụng thả nút chuột trong khi kéo một đối tượng.

Ghi chú: Ghi chú rằng chỉ các sự kiện kéo được kích hoạt; các sự kiện về chuột như mousemove không được kích hoạt trong suốt hoạt động kéo.

Đối tượng DataTransfer

Các phương thức listener sự kiện cho tất cả các sự kiện kéo và thả chấp nhận đối tượng Event mà có một thuộc tính ngẫu nhiên được gọi là dataTransfer. event.dataTransfer trả về đối tượng DataTransfer được liên kết với sự kiện đó như sau:

function EnterHandler(event) {
    DataTransfer dt = event.dataTransfer;
    .............
}

Đối tượng DataTransfer giữ dữ liệu về hoạt động kéo và thả. Dữ liệu này có thể được thu nhận và thiết lập theo các thuộc tính đa dạng được liên kết với đối tượng DataTransfer như được giải thích dưới đây:

STTCác thuộc tính DataTransfer và Miêu tả
1**dataTransfer.dropEffect \[ = value \]** - Trả về loại hoạt động mà hiện tại được chọn. - Thuộc tính này có thể được thiết lập, để thay đổi hoạt động chọn. - Các giá trị có thể là: **none, copy, link,** và **move**.
2**dataTransfer.effectAllowed \[ = value \]** - Trả về loại hoạt động mà được cho phép. - Thuộc tính này có thể được thiết lập để thay đổi hoạt động cho phép. - Các giá trị có thể là: **none, copy, copyLink, copyMove, link, linkMove, move, all** và **uninitialized**.
3**dataTransfer.types** Trả về một DOMStringList liệt kê các định dạng mà được thiết lập trong sự kiện dragstart. Ngoài ra, nếu bất cứ file nào đang được kéo, thì khi đó một trong số các kiểu sẽ là chuỗi "File".
4**dataTransfer.clearData( \[ format \] )** Gỡ bỏ dữ liệu của các định dạng đã xác định trước. Gỡ bỏ tất cả dữ liệu nếu tham số là bỏ trống.
5**dataTransfer.setData(format, data)** Thêm dữ liệu đã xác định.
6**data = dataTransfer.getData(format)** Trả về dữ liệu đã xác định. Nếu không có dữ liệu nào, trả về chuỗi trống.
7**dataTransfer.files** Trả về một danh sách file của các file đang được kéo.
8**dataTransfer.setDragImage(element, x, y)** Sử dụng phần tử đã cho để cập nhật sự phản hồi hoạt động kéo, thay thế bất kỳ sự phản hồi đã xác định trước đó.
9**dataTransfer.addElement(element)** Thêm phần tử đã cho tới danh sách các phần tử được sử dụng để trả về sự phản hồi hoạt động kéo.

Tiến trình Drag và Drop

Sau đây là các bước để thực hiện hoạt động Drag và Drop:

Bước 1: Tạo một Object Draggable

Dưới đây là các bước thực hiện:

  • Nếu bạn muốn kéo một phần tử, bạn cần thiết lập thuộc tính draggable về true cho phần tử đó.
  • Thiết lập một Event Listener cho dragstart mà lưu giữ dữ liệu được kéo.
  • dragstart của Event Listener sẽ thiết lập các tác động được cho phép (copy, move, link, hoặc một số sự kết hợp khác).

Sau đây là ví dụ để tạo một Object Dragable:

<html>
<head>
<style type="text/css">
#boxA, #boxB {
   float:left;padding:10px;margin:10px; -moz-user-select:none;
}
#boxA { background-color: #6633FF; width:75px; height:75px;  }
#boxB { background-color: #FF6699; width:150px; height:150px; }
</style>
<script type="text/javascript">
function dragStart(ev) {
   ev.dataTransfer.effectAllowed='move';
   ev.dataTransfer.setData("Text", ev.target.getAttribute('id'));
   ev.dataTransfer.setDragImage(ev.target,0,0);
   return true;
}
</script>
</head>
<body>
<center>
<h2>Drag and drop HTML5 demo</h2>
<div>Try to drag the purple box around.</div>


<div id="boxA" draggable="true" 
        ondragstart="return dragStart(event)">
   <p>Drag Me</p>
</div>
<div id="boxB">Dustbin</div>
</center>
</body>
</html>

Bước 2: Thả một đối tượng

Để chấp nhận một hoạt động thả, mục tiêu thả phải nghe theo ít nhất 3 sự kiện:

  • Sự kiện dragenter, mà được sử dụng để quyết định có hoặc không mục tiêu thả chấp nhận hoạt động thả. Nếu hoạt động thả được chấp nhận, thì khi đó sự kiện này phải bị hủy.
  • Sự kiện dragover, mà được sử dụng để quyết định phản hồi nào là được hiển thị tới người sử dụng. Nếu sự kiện bị hủy, thì khi đó phản hồi (đặc trưng là con trỏ chuột) được cập nhật dựa trên giá trị của thuộc tính dropEffect.
  • Cuối cùng, sự kiện drop, mà cho phép hoạt động thả thực sự được thực hiện.

Sau đây là ví dụ để thả một đối tượng vào trong đối tượng khác:

<html>
<head>
<style type="text/css">
#boxA, #boxB {
   float:left;padding:10px;margin:10px;-moz-user-select:none;
}
#boxA { background-color: #6633FF; width:75px; height:75px;  }
#boxB { background-color: #FF6699; width:150px; height:150px; }
</style>
<script type="text/javascript">
function dragStart(ev) {
   ev.dataTransfer.effectAllowed='move';
   ev.dataTransfer.setData("Text", ev.target.getAttribute('id'));
   ev.dataTransfer.setDragImage(ev.target,0,0);
   return true;
}
function dragEnter(ev) {
   event.preventDefault();
   return true;
}
function dragOver(ev) {
    return false;
}
function dragDrop(ev) {
   var src = ev.dataTransfer.getData("Text");
   ev.target.appendChild(document.getElementById(src));
   ev.stopPropagation();
   return false;
}
</script>
</head>
<body>
<center>
<h2>Drag and drop HTML5 demo</h2>
<div>Try to move the purple box into the pink box.</div>


<div id="boxA" draggable="true" 
     ondragstart="return dragStart(event)">
   <p>Drag Me</p>
</div>
<div id="boxB" ondragenter="return dragEnter(event)" 
     ondrop="return dragDrop(event)" 
     ondragover="return dragOver(event)">Dustbin</div>
</center>
</body>
</html>

Bình luận