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 menarik link di halaman web, Anda akan melihat kotak kecil dengan judul dan URL yang dapat Anda letakkan di kolom URL atau desktop untuk membuat pintasan atau membuka link tersebut. Untuk membuat jenis konten lain dapat ditarik, Anda harus menggunakan API Tarik lalu Lepas HTML5.
Untuk membuat objek dapat ditarik, tetapkan draggable=true
pada elemen tersebut. Hampir semua
apa pun dapat diaktifkan untuk ditarik, termasuk gambar, file, link, file, atau
markup apa pun di halaman.
Contoh berikut membuat antarmuka untuk mengatur ulang kolom yang telah
ditata dengan Petak CSS. Markup dasar untuk kolom akan terlihat seperti ini, dengan
atribut draggable
untuk setiap kolom 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 properti
cursor: move
. Kode lainnya mengontrol tata letak dan gaya visual elemen 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 perilaku, 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 (tempat tarik dimulai), payload data (objek yang ditarik), dan target (area untuk menangkap lepas). Elemen sumber dapat berupa hampir semua jenis elemen. Target adalah zona lepas atau kumpulan zona lepas yang menerima data yang coba dihapus oleh pengguna. Tidak semua elemen dapat menjadi target. Misalnya, target Anda tidak boleh berupa gambar.
Memulai dan mengakhiri urutan tarik
Setelah menentukan atribut draggable="true"
pada konten, lampirkan
pengendali peristiwa dragstart
untuk memulai urutan tarik untuk setiap kolom.
Kode ini menetapkan opasitas kolom menjadi 40% saat pengguna mulai menariknya, lalu mengembalikannya ke 100% saat peristiwa tarik 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. Tarik item, dan
opasinya akan berubah. Karena elemen sumber memiliki peristiwa dragstart
, menetapkan
this.style.opacity
ke 40% akan memberi pengguna masukan visual bahwa elemen tersebut adalah
pilihan saat ini yang dipindahkan. Saat Anda melepas item, elemen sumber
akan kembali ke opasitas 100%, meskipun Anda belum menentukan perilaku lepas.
Menambahkan isyarat visual tambahan
Untuk membantu pengguna memahami cara berinteraksi dengan antarmuka Anda, gunakan pengendali peristiwa dragenter
, dragover
, dan dragleave
. Dalam contoh ini,
kolom adalah target lepas, selain dapat ditarik. Bantu pengguna untuk memahami hal ini dengan membuat batas putus-putus saat mereka menahan item yang ditarik di atas kolom. Misalnya, di CSS, Anda dapat membuat class over
untuk elemen yang merupakan target drop:
.box.over {
border: 3px dotted #666;
}
Kemudian, di JavaScript, siapkan pengendali peristiwa, tambahkan class over
saat
kolom ditarik, dan hapus saat elemen yang ditarik keluar. Di
pengendali dragend
, pastikan kita juga menghapus class di akhir
penarikan.
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 ini mencegah peristiwadrop
diaktifkan. Untuk mengganti perilaku ini, panggile.preventDefault()
. Praktik baik lainnya adalah menampilkanfalse
dalam pengendali yang sama.Pengendali peristiwa
dragenter
digunakan untuk mengalihkan classover
, bukandragover
. Jika Anda menggunakandragover
, peristiwa akan diaktifkan berulang kali saat pengguna memegang item yang ditarik di atas kolom, sehingga class CSS akan beralih berulang kali. Hal ini membuat browser melakukan banyak tugas rendering yang tidak perlu, yang dapat memengaruhi pengalaman pengguna. Kami sangat merekomendasikan untuk meminimalkan penggambaran ulang, dan jika Anda perlu menggunakandragover
, pertimbangkan throttling atau deboument pemroses peristiwa.
Menyelesaikan drop
Untuk memproses pelepasan, tambahkan pemroses peristiwa untuk peristiwa drop
. Dalam pengendali drop
, Anda harus mencegah perilaku default browser terkait 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 dihapus ke lokasi baru. Untuk
mewujudkannya, gunakan objek
DataTransfer
.
Properti dataTransfer
menyimpan data yang dikirim dalam tindakan tarik. dataTransfer
ditetapkan dalam peristiwa dragstart
dan dibaca atau ditangani dalam peristiwa drop. Dengan memanggil
e.dataTransfer.setData(mimeType, dataPayload)
, Anda dapat menetapkan jenis MIME
dan payload data objek.
Dalam contoh ini, kita akan mengizinkan pengguna mengatur ulang urutan kolom. Untuk melakukannya, Anda harus menyimpan HTML elemen sumber terlebih dahulu saat proses menarik dimulai:
function handleDragStart(e) {
this.style.opacity = '0.4';
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
Dalam peristiwa drop
, Anda memproses drop kolom dengan menetapkan HTML kolom sumber
ke HTML kolom target tempat Anda meletakkan data. Hal ini
termasuk memeriksa apakah pengguna tidak meletakkan kembali ke kolom yang sama dengan
kolom yang 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 dapat berfungsi, Anda memerlukan browser desktop. API Tarik lalu Lepas tidak didukung di perangkat seluler. Tarik lalu lepaskan kolom A di atas kolom B dan perhatikan bagaimana posisinya berubah:
Properti menarik lainnya
Objek dataTransfer
mengekspos properti untuk memberikan masukan visual kepada
pengguna selama proses tarik dan mengontrol cara setiap target lepas merespons
jenis data tertentu.
dataTransfer.effectAllowed
membatasi 'jenis tarik' yang dapat dilakukan pengguna pada elemen. Fungsi ini digunakan dalam model pemrosesan tarik lalu lepas untuk melakukan inisialisasidropEffect
selama peristiwadragenter
dandragover
. Properti ini dapat memiliki nilai berikut:none
,copy
,copyLink
,copyMove
,link
,linkMove
,move
,all
, danuninitialized
.dataTransfer.dropEffect
mengontrol masukan yang diterima pengguna selama peristiwadragenter
dandragover
. Saat pengguna mengarahkan kursor ke elemen target, kursor browser akan menunjukkan jenis operasi yang akan terjadi, seperti penyalinan atau pemindahan. Efeknya dapat menggunakan salah satu nilai berikut:none
,copy
,link
,move
.e.dataTransfer.setDragImage(imgElement, x, y)
berarti bahwa Anda dapat menyetel ikon tarik, bukan menggunakan masukan 'gambar hantu' default browser.
Upload file
Contoh sederhana ini menggunakan kolom sebagai sumber tarik dan target tarik. Hal ini mungkin terjadi di UI yang meminta pengguna untuk mengatur ulang item. Dalam beberapa situasi, target dan sumber tarik mungkin memiliki jenis elemen yang berbeda, seperti pada antarmuka saat pengguna harus memilih satu gambar sebagai gambar utama untuk suatu produk dengan menarik gambar yang dipilih ke target.
Tarik lalu lepas sering digunakan untuk memungkinkan pengguna menarik item dari desktop ke
aplikasi. Perbedaan utamanya ada pada pengendali drop
Anda. Datanya tidak disimpan dalam properti dataTransfer.getData()
untuk mengakses file, tetapi disimpan 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 selengkapnya tentang hal ini di Tarik lalu lepas kustom.