Bài 44: Kéo – thả (Drag/ Drop) trong HTML5

Bài học hôm nay sẽ giúp các bạn có thể thực thi việc kéo/ thả trong HTML5. Ví dụ dưới minh họa cho việc kéo thả. Bạn có thể kéo logo từ hình chữ nhật bên trên xuống hình chữ nhật bên dưới.


Kéo/Thả trong HTML5

Kéo và thả là một tính năng rất phổ biến. Bạn có thể chọn một đối tượng và di chuyển nó đến một vị trí khác.

Trong HTML5, kéo/thả  là một phần của chuẩn: bất cứ phần tử nào cũng có thể thực hiện việc kéo thả.


Trình duyệt hỗ trợ

Bảng dưới đây là một số phiên bản trình duyệt đầu tiên hỗ trợ việc kéo/ thả trong HTML5

API icon_chrome compatible_edge2020 icon_firefox  icon_safari  icon_opera
Kéo và Thả 4.0 9.0 3.5 6.0 12.0

Ví dụ cụ thể về việc kéo/ thả:


<!DOCTYPE HTML>
<html>
<head>
<style>
#div1 {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(ev) {
ev.preventDefault();
}

function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}

function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>

<p>Kéo ảnh logo TimODay vào hình chữ nhật:</p>

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="336" height="69">

</body>
</html>

Trông có vẻ rất phức tạp nhưng nó thể hiện rất đầy đủ từng phần của việc kéo/ thả.


Phần tử Draggable

Đầu tiên: để một phần tử có thể kéo được cần thiết lập thuộc tính draggable của phần tử thành “True”:

<img draggable="true">

Dữ liệu gì sẽ được kéo đi – ondragstart và setData()

Sau đó cần chỉ định điều gì sẽ xảy ra khi một phần tử được kéo đi?

Trong ví dụ ở trên, thuộc tính ondragstart gọi hàm drag(event), hàm này quy định dữ liệu được kéo đi.

Phương thức dataTransfer.setData() cho phép chúng ta đặt kiểu dữ liệu và giá trị của thẻ được kéo:

function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}

Trong trường hợp này, kiểu dữ liệu là “text” và giá trị id của thẻ là (“drag1”).


Dữ liệu sau khi kéo sẽ được thả ở đâu? – ondragover

Sự kiện ondragover chỉ định nơi dữ liệu được thả xuống.

Theo mặc định, dự liệu/các phần tử không thể được thả vào các thành phần khác của trang. Để cho thả xuống, chúng ta sẽ phải thay đổi mặc định của phần tử bằng cách gọi phương thức event.preventDefault() cho sự kiện ondragover:

event.preventDefault()

Thả – ondrop

Khi người dùng thả đối tượng, sự kiện thả sẽ được kích hoạt.

Trong ví dụ ở trên, thuộc tính ondrop gọi hàm drop(event):

function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}

Giải thích ví dụ:

  • Gọi phương thức preventDefault() để thay đổi cách xử lý mặc định của trình duyệt đối với dữ liệu (mặc định trình duyệt sẽ mở liên kết tới dữ liệu)
  • Lấy dữ liệu vừa được thả xuống bằng phương thức dataTransfer.getData(). Phương thức này sẽ trả về kiểu dữ liệu giống như kiểu đã được đặt trong phương thức setData()
  • Ở đây dữ liệu được thả xuống là id của thẻ (“drag1”)
  • Chèn thẻ được kéo vào bên trong thẻ được thả

Ví dụ bổ sung

Kéo thả hình ảnh qua lại

Trong ví dụ này chúng ta sẽ cải tiến đề thực hiện việc kéo – thả ảnh qua lại giữa 2 thẻ div.
Ví dụ:


<!DOCTYPE HTML>
<html>
<head>
<style>
#div1, #div2 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
</style>
<script>
function allowDrop(ev) {
ev.preventDefault();
}

function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}

function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>

<h2>Kéo và thả</h2>
<p>Kéo ảnh trở lại giữa hai phần tử.</p>

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="img_logo.gif" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
</div>

<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

</body>
</html>

Có thể bạn sẽ thích…

5 phản hồi

  1. Đức Anh viết:

    em làm y như trên chỉ kéo được thôi chứ không thả được ạ ! em kéo thẻ thẻ div von trong div cha không được ạ . trong body cũng không được luôn . có ai giải thích giúp em được không ạ

    • User Avatar Phan Tiến viết:

      Có thể code của em bị lỗi nên không chạy được. Em đang dùng trình duyệt Chrome thì em có thể kích vào View > Developer > JavaScript Console để xem code mình lỗi dòng nào để sửa.

  2. Trung Hiếu viết:

    cho mình hỏi mình kéo video 2 thả vào vị trí của video 1 thì video1 bị mất luôn .. và mình kéo video tu div1 qua div2 làm sao để video ở div 1 ko bị mất mà vẫn hiện thêm video ở div2

Trả lời