Faylları yükləmək üçün gözəl AJAX forması. HTML5: Drag & Drop istifadə edərək faylların yüklənməsi Şəklin sürüklə və buraxma üsulu ilə yüklənməsi




İstifadəçiyə faylları, məsələn, masaüstündən sürükləməklə serverə yükləməyə icazə verin. Üstəlik, eyni anda bir neçə faylı sürükləyib buraxmaq mümkün olardı.

Həll

Yuxarıdakı nümunədən göründüyü kimi, fayllar seçildikdən dərhal sonra serverə göndərilir. Gəlin onları hadisəyə görə göndərək:

Window.onload = function())( var uploader = new qq.FileUploader(( autoUpload: false, element: document.getElementById("file-loader"), action: "php/upload.php" )); $(" # startUpload").on("klik", funksiya())( uploader.uploadStoredFiles(); )); );

Nəticə

Ümumiyyətlə, plaginin bir çox variantları və parametrləri var və geri çağırışlar var. Bütün bunlar təsvir edilmişdir. Fineuploader daimi inkişaf mərhələsindədir, ona görə də əlaqə qurarkən mən repozitoriyaya baş çəkməyi və ən son versiyanı yükləməyi məsləhət görürəm.

Stilizasiya

Plugin öz strukturunu .qq-yükləyici sinfi əsasında yaradır, bütün elementlər fileuploader.css css faylında təsvir edilmişdir.

Qeyddə

Eşşəklər inadla işləməkdən imtina edərlərsə, ssenarini açın və oradakı xətti axtarın:

Var forma = qq.toElement("");

və dəyişdirin:

Var forma = qq.toElement("");

Birincisi, əlbəttə ki, faylı "tutacaq" bir element yaratmalısınız. Bundan əlavə, yükləmə statusu və haqqında mesajları göstərmək üçün bu elementdə span etiketi yerləşdirəcəyik giriş növü ilə fayl, belə ki, fayl seçimini sürükləyib buraxmaqla məhdudlaşdırmamaq, həm də istifadəçilərə bu təyin olunmuş sahəyə klikləməklə fayl seçmək imkanı vermək. Belə bir quruluşun son forması aşağıda təqdim olunur.

Bura klikləyin və ya yükləmək üçün faylı sürükləyib buraxın.

CSS buna HTML sahə dizaynı istisna olmaqla, kod diqqətəlayiq deyil giriş:

#fayl(en:100%; hündürlük:100%; displey:blok; mövqe:mütləq; üst:0; sol:0; qeyri-şəffaflıq:0,01; )

Biz həmçinin iki sinfi təsvir edirik ki, onlar faylın “tutma” sahəsinə əlavə edildikdə, faylın uğurlu endirilməsini və ya baş verərsə, xətanı göstərəcək:

#drop-zone.success( background-color:#2ecc71; ) #drop-zone.error( background-color:#e74c3c; )

İndi səhifəmizin “hərəkətini” yazmağa davam edə bilərik. Əvvəlcə tez-tez daxil olacağımız obyektlərə istinadları dəyişənlərə yazaq:

Var dropZone = document.getElementById("düşmə zonası"); var msgContainer = document.querySelector("#drop-zone .text");

Bundan sonra kursor fayl qəbul sahəsinə aşağıdakı kimi toxunduqda standart hadisələrdən xilas olacağıq:

Var eventClear = funksiya (e) ( e.stopPropagation(); e.preventDefault(); ) dropZone.addEventListener("dragenter", eventClear, false); dropZone.addEventListener("dragover", eventClear, false);

DropZone.addEventListener("drop", funksiya (e) (if(!e.dataTransfer.files) qaytarmaq; e.stopPropagation(); e.preventDefault(); sendFile(e.dataTransfer.files); ), false); document.getElementById("fayl").addEventListener("dəyişiklik", funksiya (e) ( sendFile(e.target.files); ), false);

Hər iki halda hadisə funksiya çağırışı ilə başa çatır fayl göndər, istifadəçidən alınan faylın köçürüldüyü.

Bu funksiya faylın serverə ötürülməsinə cavabdehdir. Aşağıda onun təsvirinə baxa bilərsiniz.

Var sendFile = function(fayl) ( // əlavə edilmiş dövlət siniflərini silmək // əgər istifadəçi artıq nəsə yükləməyə cəhd edibsə dropZone.classList.remove("uğur"); dropZone.classList.remove("xəta") ; / / fayl növü üçün müntəzəm ifadədən istifadə edərək yoxlayırıq // (nümunədə yalnız şəkillərin yüklənməsinə icazə verilir) var re = /(.jpg|.jpeg|.bmp|.gif|.png)$/ i; əgər (!re. exec(file.name)) ( msgConteiner.innerHTML = "Yanlış fayl formatı!"; dropZone.classList.remove("uğur"); dropZone.classList.add("xəta"); ) başqa ( var fd = new FormData( ); // forma obyekti yaratmaq fd.append("upfile", fayl); // göndərmə formasına fayl əlavə etmək var xhr = new XMLHttpRequest(); xhr.open("POST" , "./upload.php", doğru ); xhr.upload.onprogress = showProgress; xhr.onreadystatechange = statChange; xhr.send(fd); // serverə göndərilir ) )

Diqqət etdiyiniz kimi, məlumatları serverə göndərməzdən əvvəl iki hadisə də təyin olunur, bunlardan birincisi yükləmə gedişatını göstərmək üçün cavabdehdir, ikincisi isə yükləmə nəticəsi haqqında məlumat verir. Onlar aşağıdakı kimi fəaliyyət göstərirlər:

Var showProgress = funksiya(e) ( əgər (e.lengthComputable) ( // yükləmə faizini hesablayın var faiz = Math.floor((e.loaded / e.total) * 100); // cari faizi göstərin msgConteiner.innerHTML = " Yüklənir... ("+ faiz +"%)"; ) ); var statChange = funksiya (e) ( if (e.target.readyState == 4) ( // serverə sorğunun işlənməsi başa çatdıqdan sonra if (e.target.status == 200) ( // sorğu uğurlu olarsa msgConteiner.innerHTML = "Yükləmə uğurla tamamlandı!"; dropZone.classList.remove("xəta"); dropZone.classList.add("uğur"); document.getElementById("showUpFile").innerHTML = this.responseText; ) başqa ( // əks halda msgConteiner.innerHTML = "Xəta baş verdi!"; dropZone.classList.remove("uğur"); dropZone.classList.add("xəta"); ) ) )

Son mərhələ server tərəfindən alınan məlumatların işlənməsi olacaq.

Bu işarələmənin "drag and drop"la xüsusi əlaqəsi yoxdur. Potensial vəziyyətlər üçün bəzi əlavə HTML elementləri olsa da, bu, sadəcə normal, funksionaldır.

Fayl seçin və ya bura sürükləyin. Yükləmə Bitdi! Xəta! .

Bizə lazım olana qədər həmin dövlətləri gizlədəcəyik:

Box__dragndrop, .box__loading, .box__success, .box__xəta (ekran: heç biri; )

Kiçik bir izahat:

  • Vəziyyətlərə gəldikdə: .box__uploading elementi faylın yüklənməsinin Ajax prosesi zamanı görünəcək (digərləri isə hələ də gizli qalacaq). Sonra baş verənlərdən asılı olaraq .box__success və ya .box__error göstərilir.
  • giriş və etiket formanın funksional hissələridir. Fayl girişlərinin fərdiləşdirilməsi haqqında yazımda bunları bir araya gətirmək haqqında yazdım. Həmin yazıda atributun məqsədini də təsvir etdim. Daxiletmə və etiket həmçinin standart şəkildə faylları seçmək üçün alternativ kimi xidmət edir (və ya sürükləyib buraxma dəstəklənmirsə yeganə yol).
  • Brauzer faylı sürükləyib yükləmə funksiyasını dəstəklədiyi halda .box__dragndrop göstəriləcək.
Xüsusiyyət aşkarlanması

Biz 100% sürükləyib buraxmağı dəstəkləyən brauzerlərə etibar edə bilmərik. Biz ehtiyat həlli təmin etməliyik. Və beləliklə: xüsusiyyət aşkarlanması. Faylı sürükləyin və buraxın yükləmə bir sıra müxtəlif JavaScript API-lərinə əsaslanır, ona görə də biz onların hamısını yoxlamalı olacağıq.

Bəlkə də bəzi hallarda xidmət tərtibatçıları günahkardır, lakin çox vaxt problem brauzerlər tərəfindən qoyulan məhdudiyyətlərdə olur. Faylları serverə yükləməyi nəzərdən keçirək.

Əksər hallarda sizə kompüterinizdən fayl seçmək düyməsi və/yaxud İnternetdə haradasa yerləşən faylın URL-ni təyin edə biləcəyiniz sahə olan standart sahə təqdim olunacaq.

Hələlik yerli kompüterdən faylları endirməyə toxunmayacağıq, bu mövzuda ayrıca bir yazı dərc etməyi planlaşdırıram, uzaq serverdən yükləməyə baxaq.

Problemlər elə ilk addımdan başlayır. URL-i harada axtarmaq lazım olduğunu aydın başa düşsəniz və firebug kimi alətlərdən istifadə etməyi bacarsanız belə, düzgün ünvanı əldə etmək üçün hələ də bir neçə klik lazım olacaq. İstədiyiniz şəkli sadəcə bir brauzer pəncərəsindən digərinə sürükləmək daha rahat olardı.

Bu məqalədə belə bir interfeysin tətbiqlərini göstərəcəyəm. İstəyirsinizsə, demo səhifəsində onun necə işlədiyini görə bilərsiniz və ya arxivi mənbələrlə birlikdə yükləyə bilərsiniz.

Qeyd! Bu nümunə yalnız Google Chrome brauzerində işləyir. Teorik olaraq, Firefox və Safari bütün lazımi texnologiyaları dəstəkləyir, lakin mən hələ onları başa düşməmişəm.

Mən sürükləmək üçün obyekt kimi əsasən Vikipediyadan şəkillər çəkmişəm. Şəkillərin URL-lərində latın olmayan hərflərlə bağlı bir neçə problem müşahidə olundu, lakin nümunəni yoxlamalar və dəyişikliklərlə yükləməmək üçün onları olduğu kimi buraxdım.


Əməliyyat prinsipi

HTML5 standartı səhifə obyektlərinin sürüklənməsi və salınması üçün dəstək verir. Yeri gəlmişkən, mən artıq D&D-nin ən sadə tətbiqi nümunəsini göstərmişəm - HTML5-dən istifadə edərək Drag & Drop. Bundan əlavə, D&D dəstəyini həyata keçirən bir neçə JavaScript kitabxanası var.

Ancaq burada başa düşmək vacibdir ki, üçüncü tərəf mənbələrindən şəkilləri "sürükləmək" lazımdırsa, o zaman kitabxanalardan istifadə edə bilməyəcəksiniz. Çünki JS kodunuzu başqasının səhifəsinə əlavə edə bilməyəcəksiniz. Və bir şəkil yükləmək üçün onun URL-sini əldə etməliyik, yəni. Brauzer həmçinin öz parametrlərini sürüklənmiş obyektlə (məsələn, şəklin src atributu və ya bütün img teqi) ötürməlidir.

Bu halda səhifəmizdə şəkillərin “qəbuledicisini” yarada bilərik. Bu, düşmə hadisəsi idarəedicisi təyin edilmiş adi bir div olacaq. Əgər istifadəçi bu div-in üstündəki şəkli “atırsa”, işləyici çağırılacaq və birinci parametrdə sürüklənən şəkil haqqında məlumat olan obyekti alacaq.

İcra

Tətbiq səhifəmizdən başlayaq.





Şəkillər Yüklə








O, iki blokdan ibarətdir: şəkillər - burada yüklənmiş şəkilləri göstərəcəyik və img_target - şəkilləri bu blokun üzərinə çəkmək lazımdır.

Səhifənin aşağı hissəsində jQuery kitabxanasını və sürüklənmiş şəkillər haqqında məlumatı serverə göndərəcək main.js skriptini birləşdiririk.

Gəlin main.js-ə baxaq

$(funksiya()(
$("#img_target")
.bind("dragenter", funksiya(hadisə) (
$(bu).addClass("bura_bura");
yalanı qaytarmaq;
})
.bind("dragleave", funksiya(hadisə) (
yalanı qaytarmaq;
})
.bind("dragover", funksiya(hadisə) (
yalanı qaytarmaq;
})
.bind("düşmə", funksiya(hadisə) (
$(bu).removeClass("bura_bura");
var srcRegex = /src=\"([^\s]+)\"/ig;
var data = event.originalEvent.dataTransfer.getData("text/html");
var img_data = srcRegex.exec(data);
$.post("yüklə.php", ("fayl_url":img_data), funksiya(res) (
var cavab = qiymətləndirmə ("(" + res + ")");
$("#şəkillər").append($(" "));
});
doğru qayıt;
});

Burada biz dragenter, dragleave və dragover hadisələrinə işləyicilər təyin edirik. Onların hamısı sadəcə olaraq false qaytarmalıdır və istifadəçiyə şəklin “yıxıla biləcəyi” barədə məlumat vermək üçün dragenter işləyicisində qəbuledici blok üçün drop_here CSS sinifini təyin etdik.

İşin çox hissəsi drop hadisə idarəedicisində edilir. Bu hadisə baş verdikdə, biz "reset" obyekti haqqında məlumatları oxuyuruq və src atributunun dəyərini "kəsdik", yəni. Şəklin URL-i (sətir 16-18). Məlumat hadisə.originalEvent.dataTransfer obyektində ötürülür (sətir 17).

Sonra adi AJAX sorğusu yaradırıq və tapılan URL-i parametr kimi ötürürük.

Server skripti (upload.php) uzaq serverdəki şəklin URL-sini alacaq və onu yükləyəcək. Və AJAX sorğusuna cavab olaraq yüklənmiş şəklin yeni URL-ni göndərəcək.

Öz növbəsində, AJAX sorğu işləyicisi img teqi yaradacaq və onu şəkillər blokuna daxil edəcək. Beləliklə, yüklənmiş şəkillər yükləmə sahəsinin üstündə görünəcək.

upload.php-ni nəzərdən keçirin

müəyyən ("BASE_URL", "http://localhost/tests/images-upload/");

funksiyası upload_from_url($file_url) (
$url_segments = partlatmaq("/", $file_url);
$fayl_adı = urldecode(son($url_seqmentlər));
əgər (yanlış !== $fayl_adı) (
$fayl_adı_hissələri = partlatmaq(".", $fayl_adı);
if (in_array(strtolower(end($file_name_parts))), array("jpeg","jpg","png","gif"))) (
$destination=fopen("yüklə/".$fayl_adı,"w");
$source=fopen($fayl_url,"r");
$maxsize=300*1024;
$uzunluq=0;
while (($a=fread($source,1024))&&($length "Fayl URL-i göstərilməyib");

if (isset($_POST["fayl_url"])) (
$new_url = upload_from_url($_POST["fayl_url"]);
$res = massiv("fayl_url" => $new_url);
}

echo json_encode($res);

Əməliyyat prinsipi aşağıdakı kimidir. Şəklin URL-sini oxuyuruq və onu endirməyə çalışırıq (sətir 29-32).

Şəkil yüklənibsə, onu yükləmə qovluğunda saxlayın. Uzaq serverdən şəkil qəbulu fread funksiyalarından istifadə etməklə həyata keçirilir. Fayl 1kB bloklarda oxunur (sətir 15-18). Bu yanaşma, faylın ölçüsü müəyyən edilmiş həddi (bu halda 300 kB) keçərsə, onun yüklənməsini dayandırmağa imkan verir.

Faylı endirdikdən sonra biz onun üçün URL yaradırıq və onu JSON formatında brauzerə göndəririk.

Gördüyünüz kimi, belə bir yükləyicinin tətbiqi çətin deyil. Və istifadə etmək olduqca rahatdır. Təbii ki, əsas çatışmazlıq HTML5 üçün brauzer dəstəyi, daha doğrusu onun olmamasıdır

Bununla belə, əgər siz bir şirkətin işçiləri üçün interfeys yaradırsınızsa və brauzerin növünü təyin edə bilsəniz, o zaman HTML5 istifadə edilə bilər.

Və bu dərsdə mən sizə bir neçə kod sətirində faylları serverə yükləmək üçün gözəl Dropzone.js plaginini PHP vebsaytınızla inteqrasiya etmək nümunəsini göstərəcəyəm.

Dropzone.JS vanil JS-də yazılmış gözəl açıq mənbəli kitabxanadır və sizə faylları önizləmə ilə faylları yükləmək üçün sürükləyib buraxma interfeysi təqdim edir.

Əvvəlcə kitabxananın ən son versiyasını və onun üslublarını yükləyin:

Sonra yükləmələr qovluğu və index.php və upload.php faylları yaradın

İndeks php faylı kodunuzun sayta material əlavə etmək üçün formanı ehtiva edən hissəsi ola bilər. Mənim nümunəmdə minimal işarələmə və daxil edilmiş Dropzone.js kitabxanası və üslubları olan boş səhifə yaradacağam:

Yəqin ki, fikir verdiyiniz kimi, biz upload.php hərəkəti ilə forma yaratdıq, lakin faylları əlavə etmək üçün heç bir giriş yaratmadıq və formanın enktipini elan etmədik. Bunda heç bir səhv yoxdur, hər şeyi DropzoneJS kitabxanasının özü idarə edir. Bizə lazım olan tək şey formaya dropzone sinfi verməkdir. Varsayılan olaraq, DropzoneJS bu siniflə bütün formaları tapır və avtomatik olaraq onun interfeysini çəkir.

Brauzerdə icra üçün index.php səhifəsini aça və kitabxananın nəzərdə tutulduğu kimi işlədiyinə əmin ola bilərsiniz. Əldə etdiyim budur:

İndi artıq bir upload.php faylı yaratdığımız bir yükləmə idarəçisi yaradaq. Budur mənim ən sadə yükləmə kodumun bir nümunəsi:

Yüklənmiş fayllarla işləmək

Fayllarınızla tam qarşılıqlı əlaqə yaratmaq üçün sadəcə onları manipulyasiya etmək imkanı əlavə etməliyik. Əvvəlcə saxlanan fayllar (adı və ölçüsü) haqqında məlumatı çıxarmaq və onu JSON formatında qaytarmaq üçün kod parçası əlavə etməliyik.

Bunun üçün upload.php faylını bu forma yeniləyin (başqa şərt daxil edilir):

  • PHP scandir funksiyası yükləmələr qovluğunu skan edir və qovluq boşdursa bir sıra fayl və ya FALSE qaytarır.
  • Skandir funksiyasından qaytarılan dəyəri dövrələyirik və onu $result massivində saxlayırıq. Unutmayın, biz "." Və ".." çünki skandir həmişə "." Və cari və əvvəlki kataloqa aid etibarlı məzmun kimi "..".
  • Biz JSON işarələməsi üçün düzgün başlıqları çıxarırıq, həmçinin json_encode funksiyasından istifadə edərək PHP massivini JSON sətirinə çeviririk.
  • İndi index.php-ni yeniləməyin vaxtıdır:

    Dropzone.options.myDropzone = ( init: function() ( thisDropzone = this; $.get("upload.php", function(data) ( $.each(data, function(açar,value))( var mockFile = ( ad) : value.name, size: value.size ); thisDropzone.options.addedfile.call(thisDropzone, mockFile); thisDropzone.options.thumbnail.call(thisDropzone, mockFile, "yükləmələr/"+dəyər.adı); )); ))))))

    Biz burada nə etdik? Gəlin bunu anlayaq:

  • Təəssüf ki, JQuery kitabxanasını səhifəmizə əlavə etdik. Bu, həqiqətən, DropzoneJs üçün bir zərurət deyil. Biz yalnız JQuery $.get ajax funksiyasından istifadə edirik. Öz mülahizənizlə, oxşar sorğuları vue.js-də və ya istədiyiniz hər şeyi həyata keçirə bilərsiniz.
  • Formaya ID elementi (my-dropzone) əlavə etdik. Bu, konfiqurasiya dəyərlərini Dropzone-a ötürmək üçün lazımdır. Bunun üçün ona işarə edən unikal identifikatorumuz olmalıdır. Bu yolla biz Dropzone.options.myDropzone-a dəyərlər təyin edərək kitabxananı konfiqurasiya edə bilərik.
  • Redaktənin əsas hissəsini işə salaq. Burada gördüyümüz iş Dropzone-a init hadisəsini dinləmək funksiyasını ötürdü. Dropzone işə salındıqda bu hadisə işə salınır.
  • Biz ajax istifadə edərək “upload.php”dən bir sıra faylları alırıq.
  • Serverdən alınan dəyərlərdən istifadə edərək bir istehza faylı yaradın. MockFiles sadəcə ad və ölçü xassələri olan JavaScript obyektləridir. Daha sonra biz açıq şəkildə Dropbox funksiyalarını çağırırıq və mövcud faylları Dropzone yükləmə sahəsinə gətirmək və onların miniatürlərini yaratmaq üçün nişanlar əlavə edirik.
  • Hər şeyi düzgün etmisinizsə. Bəzi şəkilləri yükləyin və forma səhifəsini yenidən yükləyin. Əvvəllər yüklənmiş fayllar avtomatik olaraq Dropzone sahəsində görünməlidir.