Postingan ini menjelaskan dasar-dasar tarik lalu lepas.
Membuat konten yang dapat ditarik
Di sebagian besar browser, pilihan teks, gambar, dan link dapat ditarik secara default. Misalnya, jika Anda menyeret sebuah tautan ke laman web, Anda akan melihat kotak kecil dengan dan URL yang dapat Anda letakkan di kolom URL atau desktop untuk membuat atau membuka tautan tersebut. Untuk membuat jenis konten lain dapat ditarik, Anda menggunakan API Seret dan Lepas HTML5.
Untuk membuat objek dapat ditarik, tetapkan draggable=true
pada elemen tersebut. Hampir
apa pun dapat diaktifkan untuk menarik, termasuk gambar, file, link, file, atau
markup di halaman.
Contoh berikut membuat antarmuka untuk mengatur ulang kolom yang telah
ditata dengan CSS Grid. Markup dasar untuk kolom terlihat seperti ini, dengan
atribut draggable
untuk setiap kolom yang ditetapkan ke true
:
<div class="container">
<div draggable="true" class="box">A</div>
<div draggable="true" class="box">B</div>
<div draggable="true" class="box">C</div>
</div>
Berikut adalah CSS untuk elemen penampung dan kotak. Satu-satunya CSS yang terkait dengan
fitur tarik adalah cursor: move
saat ini. Kode lainnya mengontrol tata letak dan gaya visual penampung
dan kotak.
.container {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px;
}
.box {
border: 3px solid #666;
background-color: #ddd;
border-radius: .5em;
padding: 10px;
cursor: move;
}
Pada tahap ini Anda dapat menarik item, tetapi tidak akan terjadi apa pun. Untuk menambahkan ini, Anda harus menggunakan JavaScript API.
Memproses peristiwa tarik
Untuk memantau proses tarik, Anda dapat memproses salah satu peristiwa berikut:
Untuk menangani alur tarik, Anda memerlukan semacam elemen sumber (dengan elemen dimulai), {i>payload<i} data (hal yang sedang ditarik), dan target (area yang akan menangkap drop-nya). Elemen sumber dapat berupa hampir semua jenis elemen. Tujuan target adalah zona lepas atau kumpulan zona lepas yang menerima data pengguna mencoba menjatuhkannya. Tidak semua elemen dapat menjadi target. Misalnya, target Anda tidak bisa menjadi gambar.
Memulai dan mengakhiri urutan tarik
Setelah menentukan atribut draggable="true"
di konten Anda, lampirkan
Pengendali peristiwa dragstart
untuk memulai urutan tarik bagi setiap kolom.
Kode ini menyetel opasitas kolom menjadi 40% saat pengguna mulai menariknya, lalu mengembalikannya ke 100% saat peristiwa penyeretan berakhir.
function handleDragStart(e) {
this.style.opacity = '0.4';
}
function handleDragEnd(e) {
this.style.opacity = '1';
}
let items = document.querySelectorAll('.container .box');
items.forEach(function (item) {
item.addEventListener('dragstart', handleDragStart);
item.addEventListener('dragend', handleDragEnd);
});
Hasilnya dapat dilihat di demo Glitch berikut. Seret item, dan
perubahan opasitas. Karena elemen sumber memiliki peristiwa dragstart
, setelan
this.style.opacity
hingga 40% memberikan masukan visual kepada pengguna bahwa elemen tersebut
pilihan saat ini sedang dipindahkan. Saat Anda melepaskan item, elemen sumber
akan kembali ke opasitas 100%, meskipun Anda belum menentukan perilaku penurunan.
Menambahkan isyarat visual tambahan
Untuk membantu pengguna memahami cara berinteraksi dengan antarmuka Anda, gunakan
Pengendali peristiwa dragenter
, dragover
, dan dragleave
. Dalam contoh ini,
adalah target lepas, selain dapat ditarik. Membantu pengguna
memahami hal ini dengan membuat garis batas putus-putus saat mereka menahan item yang ditarik di atas
. Misalnya, di CSS, Anda dapat membuat class over
untuk
elemen yang merupakan target operasi lepas:
.box.over {
border: 3px dotted #666;
}
Kemudian, di JavaScript Anda, siapkan pengendali peristiwa, tambahkan class over
saat
kolom ditarik, dan menghapusnya ketika elemen yang ditarik keluar. Di beberapa
pengendali dragend
, pastikan untuk menghapus class di akhir
tarik.
document.addEventListener('DOMContentLoaded', (event) => {
function handleDragStart(e) {
this.style.opacity = '0.4';
}
function handleDragEnd(e) {
this.style.opacity = '1';
items.forEach(function (item) {
item.classList.remove('over');
});
}
function handleDragOver(e) {
e.preventDefault();
return false;
}
function handleDragEnter(e) {
this.classList.add('over');
}
function handleDragLeave(e) {
this.classList.remove('over');
}
let items = document.querySelectorAll('.container .box');
items.forEach(function(item) {
item.addEventListener('dragstart', handleDragStart);
item.addEventListener('dragover', handleDragOver);
item.addEventListener('dragenter', handleDragEnter);
item.addEventListener('dragleave', handleDragLeave);
item.addEventListener('dragend', handleDragEnd);
item.addEventListener('drop', handleDrop);
});
});
Ada beberapa poin yang perlu dibahas dalam kode ini:
Tindakan default untuk peristiwa
dragover
adalah menetapkan propertidataTransfer.dropEffect
ke"none"
. PropertidropEffect
akan dibahas nanti di halaman ini. Untuk saat ini, perlu diketahui bahwa tindakan tersebut mencegah peristiwadrop
diaktifkan. Untuk menggantinya perilakunya, panggile.preventDefault()
. Praktik baik lainnya adalah mengembalikanfalse
di pengendali yang sama.Pengendali peristiwa
dragenter
digunakan untuk mengalihkan classover
, bukandragover
. Jika Anda menggunakandragover
, peristiwa akan diaktifkan berulang kali saat pengguna menahan item yang ditarik di atas kolom, yang menyebabkan class CSS beralih berulang kali. Hal ini membuat {i>browser<i} melakukan banyak pekerjaan {i>rendering<i} yang tidak perlu, yang dapat mempengaruhi pengalaman pengguna. Kami sangat menyarankan untuk mengurangi menggambar ulang, dan jika Anda perlu menggunakandragover
, sebaiknya melakukan throttling atau debue pemroses peristiwa.
Selesaikan pelepasan
Untuk memproses pelepasan, tambahkan pemroses peristiwa untuk peristiwa drop
. Di drop
Anda harus mencegah perilaku {i>default<i}
browser untuk penurunan, yang
biasanya semacam pengalihan yang mengganggu. Untuk melakukannya, panggil e.stopPropagation()
.
function handleDrop(e) {
e.stopPropagation(); // stops the browser from redirecting.
return false;
}
Pastikan untuk mendaftarkan pengendali baru bersama pengendali lainnya:
let items = document.querySelectorAll('.container .box');
items.forEach(function(item) {
item.addEventListener('dragstart', handleDragStart);
item.addEventListener('dragover', handleDragOver);
item.addEventListener('dragenter', handleDragEnter);
item.addEventListener('dragleave', handleDragLeave);
item.addEventListener('dragend', handleDragEnd);
item.addEventListener('drop', handleDrop);
});
Jika Anda menjalankan kode pada tahap ini, item tidak akan diturunkan ke lokasi baru. Kepada
untuk melakukannya, gunakan DataTransfer
.
Properti dataTransfer
menyimpan data yang dikirim dalam tindakan tarik. dataTransfer
ditetapkan dalam peristiwa dragstart
dan dibaca atau ditangani dalam peristiwa lepas. Menelepon
e.dataTransfer.setData(mimeType, dataPayload)
memungkinkan Anda menyetel MIME objek
jenis dan {i>payload<i} data.
Dalam contoh ini, kita akan mengizinkan pengguna mengatur ulang urutan kolom. Untuk melakukannya, pertama-tama Anda harus menyimpan HTML elemen sumber saat metode tarik dimulai:
function handleDragStart(e) {
this.style.opacity = '0.4';
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
Di peristiwa drop
, Anda akan memproses penghapusan kolom dengan menetapkan nilai
HTML ke HTML kolom target tempat Anda meletakkan data. Ini
termasuk memeriksa apakah pengguna tidak kembali ke kolom yang sama dengan
ditarik.
function handleDrop(e) {
e.stopPropagation();
if (dragSrcEl !== this) {
dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
}
return false;
}
Anda dapat melihat hasilnya di demo berikut. Agar berfungsi, Anda memerlukan browser desktop. API Tarik lalu Lepas tidak didukung di perangkat seluler. Seret dan lepaskan kolom A di atas kolom B dan perhatikan bagaimana kolom tersebut mengubah tempat:
Properti tarik lainnya
Objek dataTransfer
mengekspos properti untuk memberikan masukan visual ke
selama proses {i>drag<i} dan mengendalikan bagaimana setiap target {i>drop <i}merespons terhadap
tipe data tertentu.
dataTransfer.effectAllowed
membatasi 'jenis tarik' dapat dilakukan pengguna pada elemen itu. Sudah digunakan dalam model pemrosesan tarik lalu lepas untuk menginisialisasidropEffect
selama peristiwadragenter
dandragover
. Properti dapat memiliki nilai berikut:none
,copy
,copyLink
,copyMove
,link
,linkMove
,move
,all
, danuninitialized
.dataTransfer.dropEffect
mengontrol masukan yang didapatkan pengguna selamadragenter
dandragover
peristiwa. Saat pengguna mengarahkan kursor ke elemen target, elemen kursor menunjukkan jenis operasi apa yang akan terjadi, seperti penyalinan atau pindah. Efeknya dapat menggunakan salah satu nilai berikut:none
,copy
,link
,move
.e.dataTransfer.setDragImage(imgElement, x, y)
berarti bahwa alih-alih menggunakan 'gambar hantu' default browser, masukan, Anda dapat mengatur ikon {i>drag<i}.
Upload file
Contoh sederhana ini menggunakan kolom sebagai sumber tarik dan target tarik. Ini mungkin terjadi di UI yang meminta pengguna untuk mengatur ulang item. Dalam beberapa situasi, target dan sumber tarik mungkin berupa jenis elemen yang berbeda, seperti pada antarmuka di mana pengguna perlu memilih satu gambar sebagai gambar utama untuk suatu produk dengan menyeret gambar yang dipilih ke target.
{i>Drag and <i}sering digunakan untuk memungkinkan pengguna menarik item dari {i>desktop<i} mereka ke
aplikasi. Perbedaan utamanya adalah pada pengendali drop
Anda. Daripada menggunakan
dataTransfer.getData()
untuk mengakses file, datanya dimuat dalam
Properti dataTransfer.files
:
function handleDrop(e) {
e.stopPropagation(); // Stops some browsers from redirecting.
e.preventDefault();
var files = e.dataTransfer.files;
for (var i = 0, f; (f = files[i]); i++) {
// Read the File objects in this FileList.
}
}
Anda dapat menemukan informasi lebih lanjut tentang hal ini di Tarik lalu lepas kustom.