Size "öğrendiğim" kadarıyla HTML5 Drag & Drop ve birkaç örneğini göstereceğim.
Önce yeni Listener'larımızı tanıyalım.
- dragstart
- dragenter
- dragover
- dragleave
- dragend
- drop
dragstart : Drag olayı başladığı anki olayımızdır. bir nesneyi tuttuğumuz zaman "Nesne Tutuldu." uyarısı vermek istiyorsak bu listener'ı kullanabiliriz.
dragenter : Dragzone'a nesne giriş yaptığı zamanki olayımızdır. Bir nesne dragable="true" değeri ile tutulabilir yapılır. Bir nesneyi dragable="true" olan alana sürüklersek bu olay gerçekleşir.
dragover : Bu olay dragenter'a benzer arasındaki fark ise dragenter nesne giriş yaptığı zaman 1 kere çalışırken dragover nesne üzerinde bulunduğu sürece işler.
dragleave : Dragzone'dan nesne çıkış yaptığı zaman işler.
dragend : Mouse ile tuttuğumuz nesneyi bıraktığımız zaman işler. Nesnenin bırakılması olayıdır.
drop : Nesneyi dropzone'a koyduğumuz zaman işler. Drag & Drop olayı tamamlanmış olur.
Not : dragenter, dragover, dragleave olayları istenirse dropzone için de kullanılabilir.
Şimdi gelelim listener'larımızı nesnelerimize eklemeye.
var drags = document.querySelectorAll('.dragable');
[].forEach.call(drags, function(drag) {
drag.addEventListener('dragstart', handleDragStart, false);
drag.addEventListener('dragenter', handleDragEnter, false);
drag.addEventListener('dragover', handleDragOver, false);
drag.addEventListener('dragleave', handleDragLeave, false);
drag.addEventListener('dragend', handleDragEnd, false);
});
Yukarıdaki örneğimizde class="dragable" olan nesnelerimizi alıp dragstart, dragenter, dragover, dragleave, dragend olaylarını ekledik.
İstersek tek bir nesneyede ekleyebilir.
var dragr = document.getElementById('drag1');
dragr.addEventListener('dragstart', handleDragStart, false);
Yukarıda ise id="drag1" olan bir nesneye dragstart olayını ekledik.
Olaylar eklenir de silinmez mi?
O da var silmek içinse aşağıdaki kodumuza bakalım...
var dragr = document.getElementById('drag1');
dragr.removeEventListener('dragstart', handleDragStart, false);
dragr.removeEventListener('dragenter', handleDragEnter, false);
dragr.removeEventListener('dragover', handleDragOver, false);
dragr.removeEventListener('dragleave', handleDragLeave, false);
dragr.removeEventListener('dragend', handleDragEnd, false);
removeEvetListener ile olaylarımızı silmiş olduk.
Şimdi ise dropzone'umuzu ayarlayalım.
var drop = document.getElementById('box-list');
drop.addEventListener('drop', handleDrop, false);
['dragenter', 'dragover'].forEach(function(item){
drop.addEventListener(item, function(e){
e.preventDefault();
}, false);
});
Yukarıdaki kodumuz ile id="box-list" olan dropzone'a dragenter ve dragover olayları sırasında drop olma özelliğini kattık.
Not : handleDragStart, handleDragEnter, handleDragOver, handleDragLeave, handleDragEnd, handleDrop bunları herbiri kendi yazacağımız fonksiyonlardır. Aşağıda örnek fonksiyonları göreceksiniz.
function handleDragStart(e){
e.dataTransfer.setData("Text",this.id);
this.classList.add('dragon');
var dragIcon = document.createElement('img');
dragIcon.src = 'images/ark2.png';
dragIcon.width = 128;
e.dataTransfer.setDragImage(dragIcon, -20, -10);
}
e.dataTransfer.setData("Text",this.id); //Drag olayımız başladı ve ben tuttuğum nesnein ID'sini "Text" değerine atadım.
this.classList.add('dragon'); //Tuttuğum nesneye dragon class'ı ekledim. (Dragon = Drag - On :) )
Burda bir şey daha öğreneceğiz o da nesneyi tuttuğumuz icon şeklinde resim eklemeyi.
var dragIcon = document.createElement('img'); //image nesnemizi oluşturduk
dragIcon.src = 'images/ark2.png'; //adresimizi atadık.
dragIcon.width = 128; //genişliğini ayarladık.
e.dataTransfer.setDragImage(dragIcon, -20, -10); //mouseun biraz yanına yerleştirdik.
function handleDragEnter(e){
e.preventDefault();
this.classList.add('over');
}
Bu kodumuz ile nesnenin bulunduğu alana girdiğimizde nesnemize over class'ı atadık.
function handleDragOver(e){
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
}
Dragover olayımızı da yaptık.
e.dataTransfer.dropEffect = 'move'; // Dropzone üzerine geldiğimizde mouse imlecinin alacağı şekli belirler.
function handleDragLeave(e){
this.classList.remove('over');
}
DragLeave ile nesnenin bulunduğu yerden çıktığımız için over class'ını sildirdik.
function handleDragEnd(e){
e.preventDefault();
var drags = document.querySelectorAll('.dragable');
[].forEach.call(drags, function (col) {
col.classList.remove('over');
col.classList.remove('dragon');
});
}
Drag olayımız bittiğinde class="dragable" olan tüm nesnelerimizin over ve dragon classlarını sildiriyoruz.
function handleDrop(e){
if (e.stopPropagation) {
e.stopPropagation();
}
var veriID = e.dataTransfer.getData("Text");
var nesne = document.getElementById(veriID);
if (nesne){
if(nesne.className.indexOf('dragable') >= 0){
sendData(veriID);
}}
e.preventDefault();
}
Drop olayımızda ise "Text" değerine atadığımız ID'mizi çekiyoruz ve sendData() fonksiyonumuz ile gerekli işlemleri yapıyoruz.
Ben ID'yi alıp ajax ile işlemler yaptım. Bundan sonrası sizlere kalmış. :)
function sendData(data){
$.ajax({
url: 'index.html?box=add&ID='+data,
success: function(gelVeri) {
if (gelVeri != 'false'){
$('#new-list').html(gelVeri).attr('id','file'+data).after('');
$('#'+data).removeClass('dragable').addClass('soluk').parent().addClass('soluk');
removeDragDrop(data);
//runDragDrop();
}
}
});
return true;
}
sendData fonksiyonunu da vereyim aklınız kalmasın. :)
$('#new-list').html(gelVeri).attr('id','file'+data).after(''); //burada gelen veriyi new-list ID'li div'e yazdırdım ve ID'sini değiştirdim. Div'den hemen sonra yeni bir new-list ID'li bir div ekledim.
$('#'+data).removeClass('dragable').addClass('soluk').parent().addClass('soluk'); //burada ise nesnemin dragable özelliğini (class="dragable") sildim. "soluk" class'ını ekledim ve içersinde bulunduğu yere de "soluk" class'ı ekledim.
removeDragDrop(data); //yukarıda da bahsetmiştim listener'ları silmek için bu fonksiyonu kullandım ve tamamen drag özelliği kalktı.
Yukarda kullandığım fonksiyonları denemek için http://pskpt.net.tc/ adresindeki indirme kutusunu deneyebilirsiniz.
__________________________________________________
Drag & Drop Çoklu Dosya Yükleme.
var dropArea = document.getElementById('dropArea');
var count = document.getElementById('count');
var result = document.getElementById('result');
var pbar = document.getElementById('pbar');
var list = [];
var totalSize = 0;
var totalProgress = 0;
değişkenlerimizi tanıttık.
function initHandlers() {
dropArea.addEventListener('drop', handleDrop, false);
dropArea.addEventListener('dragover', handleDragOver, false);
dropArea.addEventListener('dragleave', handleDragLeave, false);
}
Drop, Dragover, Dragleave olaylarımızı ekledik.
function drawProgress(progress) {
pbar.value = Math.floor(progress*100)
}
Progressbar'ımızı güncellemek için.
function handleDragOver(event) {
event.stopPropagation();
event.preventDefault();
dropArea.className = 'hover';
dropArea.innerHTML = 'Bırak Şimdi!';
}
Dosyamızı dropzone'umuza getirdik ve dropArea'mızın class'ı "hover" olarak değişti. İçeriğine "Bırak Şimdi!" yazdırdık.
function handleDragLeave(event) {
event.stopPropagation();
event.preventDefault();
dropArea.className = '';
dropArea.innerHTML = 'Gitme Gel!';
}
Dosyamız dropzone'muzdan dışarı çıkarsa "over" class'ımızı sildirdik ve içeriğine "Gitme Gel!" yazdırdık.
function handleDrop(event) {
event.stopPropagation();
event.preventDefault();
dropArea.innerHTML = 'Yükleniyor';
processFiles(event.dataTransfer.files);
}
Dosyamızı bıraktık ve bırakılan dosyalarımızı processFiles() fonksiyonu ile gönderdik.
Buraya kadar Drag & Drop olayımızı yaptık.
Not: evenstopPropagation(); sürüklenen dosyanın browser tarafından çalıştırılmasını önlemek içindir.
Şimdi ise sıra AJAX ile dosyamızı yüklemek ve progessbar'ımızı kontrol etmekte.
function processFiles(filelist) {
if (!filelist || !filelist.length || list.length) return;
totalSize = 0;
totalProgress = 0;
result.textContent = '';
for (var i = 0; i < filelist.length && i < 10; i++) {
list.push(filelist);
totalSize += filelist[i].size;
}
uploadNext();
}
Yukarıdaki fonksiyonda filelist'imizi kontrol ediyoruz.
Dosyalarımızı saydırık toplam boyutlarını aldık (progressbar'da kullanacağız) ve her bir dosyayı "list" arrayına atadık.
function uploadNext() {
if (list.length) {
count.textContent = list.length - 1;
dropArea.className = 'uploading';
var nextFile = list.shift();
if (nextFile.size >= 602000) {
result.innerHTML += ''+nextFile.name+' | Dosya Çok Büyük! (Max : 500 KB)';
handleComplete(nextFile.size);
} else {
uploadFile(nextFile, status);
}
} else {
dropArea.className = '';
}
}
upload etmeden önce son kontrolleri yapıyoruz. Dosya boyutunu kontrol ediyoruz.
[I]var nextFile = list.shift(); // list.shift() ile array'in ilk elemanını siliyoruz.
upload fonksiyonunu ben birazcık değiştirdim hata kodları JSON vs. PHP dosyasını da paylaşacağım
Javascript ile formData oluşturuyoruz buna dosyamızı tanıtıyoruz ve ardından AJAX ile post ediyoruz.
function handleComplete(size) {
totalProgress += size;
drawProgress(totalProgress / totalSize);
uploadNext();
}
dosya yüklenmesi tamamlandıktan sonra progressbar'ımızı güncelliyoruz.
function handleProgress(event) {
var progress = totalProgress + event.loaded;
drawProgress(progress / totalSize);
}
Bu da progressbar'ın güncellenmesi.
Bu yazımda asıl önemli olan Drop olayındaki event.dataTransfer.files kısmıdır. :)
Denemek için : http://pskpt.net.tc/upload/
İndirmek için : http://pskpt.net.tc/upload/upload.rar
Gelecek yazıma buradan devam edeceğim.
Drag & Drop ile yapılmış Güvenlik Sorusu Uygulaması.
Not : Kodlar tamamıyla bana ait değildir. Nette araştırıp bulduğum kodları düzenledim ve anladığım kadarıyla sizlere işlevlerini aktarmaya çalıştım.