Last opp bilde dra og slipp. HTML5: Laste opp filer ved hjelp av dra og slipp

Denne markeringen har ikke noe spesifikt med dra og slipp å gjøre. Det er bare en normal, funksjonell, om enn med noen ekstra HTML-elementer for potensielle tilstander.

Velg en fil eller dra den hit. Last opp ferdig! Feil! .

Vi vil skjule disse statene til vi trenger dem:

Box__dragndrop, .box__uploading, .box__success, .box__error (visning: ingen; )

En liten forklaring:

  • Angående tilstander: .box__uploading-elementet vil være synlig under Ajax-prosessen med filopplasting (og de andre vil fortsatt være skjult). Da vil .box__success eller .box__error vises avhengig av hva som skjer.
  • input og label er de funksjonelle delene av skjemaet. Jeg skrev om å style disse sammen i innlegget mitt om å tilpasse filinndata. I det innlegget beskrev jeg også hensikten med attributt. Inndata og etikett fungerer også som et alternativ for å velge filer på standardmåten (eller den eneste måten hvis dra og slipp ikke støttes).
  • .box__dragndrop vises hvis en nettleser støtter dra og slipp filopplastingsfunksjonalitet.
Funksjonsdeteksjon

Vi kan ikke stole 100 % på nettlesere som støtter dra og slipp. Vi bør tilby en reserveløsning. Og så: funksjonsdeteksjon. Dra og slipp filopplasting er avhengig av en rekke forskjellige JavaScript API-er, så vi må sjekke dem alle.

  • HTML

Takket være innovasjonene til HTML5 har det blitt mye enklere å lage Dra og slipp-grensesnitt. Dessverre har disse innovasjonene ennå ikke omfattende nettleserstøtte, men jeg håper dette vil endre seg snart (fungerer for tiden i Firefox 4+, Chrome og Opera 11.10).

Markup Jeg må si med en gang at artikkelen ble skrevet mer for nybegynnere enn for profesjonelle. Derfor vil noen punkter bli beskrevet i detalj.

Først må vi lage en HTML-fil med følgende innhold:

For å laste ned, dra filen hit.

Alt vårt arbeid vil skje med dropZone-beholderen. La oss nå legge til stiler for dokumentet vårt (style.css):

Brødtekst ( font: 12px Arial, sans-serif; ) #dropZone (farge: #555; font-size: 18px; text-align: center; width: 400px; polstring: 50px 0; margin: 50px auto; bakgrunn: #eee ; border: 1px solid #ccc; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; ) #dropZone.hover ( bakgrunn: #ddd; border-color: #aaa; ) #dropZone.error ( bakgrunn: #faa; border-color: #f00; ) #dropZone.drop ( bakgrunn: #afa; border-color: #0f0; )

I stiler kan du legge merke til tre tilstander for dropZone-elementet: ved hover, hvis det oppstår en feil, og når det er vellykket.

Laster script Nå kommer vi til den morsomme delen - å skrive JavaScript-kode. Først må vi lage variabler, i den ene vil vi plassere vår dropZone, og i den andre vil vi indikere maksimal filstørrelse.

$(document).ready(function() ( var dropZone = $("#dropZone"), maxFileSize = 1000000; // maksimal filstørrelse - 1 MB. ));

Deretter må vi sjekke om nettleseren støtter Dra og slipp, for dette vil vi bruke FileReader-funksjonen. Hvis nettleseren ikke støtter Dra og slipp, vil vi i dropZone-elementet skrive "Ikke støttet av nettleseren!" og legg til "error"-klassen.

If (typeof(window.FileReader) == "udefinert") ( dropZone.text("Støttes ikke av nettleseren!"); dropZone.addClass("feil"); )

Det neste vi skal gjøre er å animere effekten av å dra en fil til dropZone. Vi vil spore disse handlingene ved å bruke hendelsene "ondragover" og "ondragleave". Men siden disse hendelsene ikke kan spores av jQuery-objektet, må vi ikke bare få tilgang til "dropZone", men "dropZone".

DropZone.ondragover = function() ( dropZone.addClass("hover"); return false; ); dropZone.ondragleave = function() ( dropZone.removeClass("hover"); return false; );

Nå må vi skrive en hendelsesbehandler for "ondrop"-hendelsen - dette er hendelsen når den drade filen slippes. I noen nettlesere, når du drar filer inn i nettleservinduet, åpnes de automatisk, slik at dette ikke skjer, må vi avbryte nettleserens standard oppførsel. Vi må også fjerne "hover"-klassen og legge til "slipp"-klassen.

DropZone.ondrop = function(event) ( event.preventDefault(); dropZone.removeClass("hover"); dropZone.addClass("drop"); );

Var file = event.dataTransfer.files; if (fil.størrelse > maxFileSize) ( dropZone.text("Filen er for stor!"); dropZone.addClass("feil"); return false; )

Nå må vi skrive en AJAX-forespørsel som sender filen vår til behandleren. For å lage en AJAX-forespørsel bruker vi XMLHttpRequest-objektet. La oss legge til to hendelsesbehandlere for XMLHttpRequest-objektet: den ene viser fremdriften for filnedlastingen, og den andre viser nedlastingsresultatet. Vi vil spesifisere filen upload.php som en behandler.

Var xhr = ny XMLHttpRequest(); xhr.upload.addEventListener("progress", uploadProgress, false); xhr.onreadystatechange = stateChange; xhr.open("POST", "/upload.php"); xhr.setRequestHeader("X-FILE-NAME", fil.navn); xhr.send(fil);

La oss nå ta en titt på nedlastingsfremdriften og nedlastingsresultatfunksjonene. Det er ikke noe komplisert med "uploadProgress"-funksjonen, bare enkel matematikk.

Funksjon uploadProgress(event) ( var prosent = parseInt(event.loaded / event.total * 100); dropZone.text("Laster: " + prosent + "%"); )

I «stateChange»-funksjonen må vi sjekke om lasteprosessen er fullført, og i så fall må vi sjekke om det har oppstått noen feil. Den vellykkede forespørselskoden er "200"; hvis koden er forskjellig fra denne, betyr det at det har oppstått en feil.

Funksjon stateChange(event) ( if (event.target.readyState == 4) ( if (event.target.status == 200) ( dropZone.text("Opplastning fullført!"); ) else ( dropZone.text(" Det har oppstått en feil!"); dropZone.addClass("error"); ) ) )

JavaScript-delen er fullført.

Serverdel Alt som gjenstår for oss er å skrive en enkel behandler som vil lagre filen på stedet vi trenger. Jeg vil ikke gå for dypt inn i å skrive handleren, men vil bare gi et lite eksempel i PHP.

Det er alt, jeg håper artikkelen var nyttig for deg.

Du kan laste ned kildefilene

Utarbeidet av: Evgeny Ryzhkov og Egor Skornyakov Publiseringsdato: 06/12/2011

Oppgave

La brukeren laste opp filer til serveren ved å dra dem, for eksempel fra skrivebordet. Dessuten ville det være mulig å dra og slippe flere filer samtidig.

Løsning

La oss se på demoeksemplet. Et eksempel finnes i arkivet. Krysset av:

  • IE 6-9
  • Firefox 3.6-4
  • Opera 11.1
  • Chrome
  • Safari 5

La meg gjøre oppmerksom på at i dette tilfellet er det sjekket!= det fungerer:

  • IE, inkludert versjon 9, støtter ikke File API (gammel implementering);
  • Firefox 3.6+ støtter alt du trenger. For eldre versjoner - gammel implementering;
  • Opera 11.1 støtter File API, men støtter ikke DnD;
  • Chrome, fra og med versjon 10, støtter alt du trenger;
  • Safari støtter alt du trenger siden versjon 6.

Hva er vitsen med det i denne saken? Brukere av vanlige nettlesere får mer praktiske nettsteder.

Hva du skal laste ned:
  • plugin (12Kb ukomprimert)
Rask start

Vi kobler sammen skriptene, og legger til typen =fil med . Hvis nettleseren ikke støtter det nødvendige settet med APIer, vil brukeren kunne laste opp bildet på gammeldags måte. Slik at han har muligheten til å legge til flere bilder, vil vi dynamisk legge til en "+"-knapp, som vil legge til input type=file-felt. For disse formålene inneholder felt-ID-en 0 for å gjøre det lettere å organisere de riktige navnene på feltene som er lagt til.

...

For nettlesere som støtter Dnd og File API, kan du fullstendig skjule eller fjerne type=file-feltene.

Hvordan det fungerer

Hvis du ikke går for mye i detalj, kan operasjonsprinsippet vises i form av et lignende diagram:

  • (DnD API) det hele starter når brukeren slipper den nedtrykte museknappen - drop-hendelsen utløses;
  • (DnD API) få et DataTransfer-objekt fra drop-hendelsen;
  • (File API) ved å kalle DataTransfer.files får vi en FileList - en liste over filer som brukeren dro til nedlastingsområdet;
  • (File API) ved å gå gjennom alle filene leser vi innholdet ved hjelp av FileReader-objektet;
  • (File API) kaller FileReader.readAsDataURL(../../../collect/js-plugins/ui/file) hver gang neste fil er vellykket lest, danner vi et data-URL-objekt. Når den er fullstendig dannet, vil onloadend-hendelsen til FileReader-objektet oppstå;
  • når vi mottok data:URL-objektet, kan vi erstatte disse dataene i src og vise dem, samt sende dataene i binær form til serveren;
  • (XMLHttpRequest 2) vi sender data asynkront, og ved å bruke nye funksjoner i den andre versjonen av XMLHttpRequest-protokollen mottar vi data om nedlastingsstatus (fremdriftshendelse), som lar oss informere brukeren.
  • Fine Uploader Plugin

    oppdatering: 18.09.12 av Andrey Kosyak.

    Ganske praktisk js-plugin for å laste opp filer til serveren. Skrevet i ren JS. Den består av en serverdel (på flere språk) og en klientdel (JS og CSS).

    IKKE bruker Flash og eventuelle rammeverk.

    Fineuploader bruker et XMLHttpRequest-objekt for å overføre filer med en fremdriftslinje for moderne nettlesere, og for enhver søppel brukes den gode gamle iframe-metoden.

    La oss bli kjent:
    • Prosjekt på GitHub
    • Innfødt demo
    • Dokumentasjon (på engelsk)

    Krysset av:

    • IE 7-9
    • Firefox 3.6+
    • Opera 10.6+
    • Chrome
    • Safari 4+
    Rask start

    Funksjonaliteten til plugin må kontrolleres utelukkende fra serveren (lokalt er greit). I eksemplet vil jeg bruke serverdelen i PHP.

    Før den første starten må du forberede bakken:

      På en lokal server er det første skriptet vil spørre om å øke verdiene til parameterne post_max_size og upload_max_filesize. Åpne php.ini-filen, finn disse parameterne og sett verdiene til >= 10M. På en ekte server vil dette elementet mest sannsynlig ikke være nødvendig.

      • hvis vi tester på en webserver, sett rettighetene til 777
      • hvis vi tester på lokalt, fjerner vi merket for "skrivebeskyttet" i mappeegenskapene (det kan fungere uten dette)
    • fra /server-mappen til pluginet tar vi php.php-filen. I den, i den første blokken med kommentarer, er det skrevet hvilke linjer som må trekkes ut fra kommentarene for å initialisere klassen. Legg til umiddelbart etter kommentarblokken:

      // tillatte filutvidelser $allowedExtensions = array(); // maksimal filstørrelse $sizeLimit = 10 * 1024 * 1024; // klasseinitialisering $uploader = ny qqFileUploader($allowedExtensions, $sizeLimit); // her må du spesifisere banen til /uploads-mappen $result = $uploader->handleUpload("../uploads/"); // returner svaret etter å ha lagret filen echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);

    Vi kobler til plugin-skriptet og stilene:

    Aktiver JavaScript for å bruke filopplasting.

    JS initialisering:

    Window.onload = function())( var uploader = new qq.FileUploader(( element: document.getElementById("file-uploader1"), handling: "php/upload.php" // bane til serversiden av plugin-modulen )); ) ;

    I denne opplæringen vil vi lage et lite AJAX-filopplastingsskjema som lar besøkende laste opp filer ved å bruke eller bruke et vanlig filvalg.

    Vi vil bruke pluginene jQuery File Upload og jQuery Knob for å vise .

    Fordi skjemaet vil kunne laste opp filer på to måter, det vil fungere selv om dra/slipp ikke støttes.

    HTML

    Som vanlig, la oss starte med HTML5-oppmerking:

    Mini Ajax filopplastingsskjema slipp her Bla gjennom

    I taggen til dokumentet vårt inkluderer vi Google Webfonts-fonter, og før vi lukker taggen - JavaScript-biblioteker: jQuery, jQuery Knob og jQuery File Upload.

    Hovedelementet på siden er #opplastingsskjemaet. Inne i den er #slipp-elementet (godtar filer ved hjelp av dra og slipp) og en liste der nedlastede filer vil vises. Markup som vil bli generert for opplastede filer:

  • Sunset.jpg 145 KB

  • Inndataelementet vil bli skjult ved hjelp av CSS. Det er nødvendig for å initialisere jQuery Knob-plugin, som vil tegne filen. Input har data-*-attributter som brukes til å oppdatere skalaen. Senere, når vi sporer lastefremdriften, vil vi oppdatere disse verdiene for å tegne skalaen på nytt. span vil inneholde en grønn hake eller et rødt kryss.

    jQuery

    Den besøkende vil ha 2 måter å laste ned filen på:

    • Dra filen inn i nettleservinduet (fungerer ikke i IE).
    • Ved å klikke på bla gjennom-knappen. Et klikk på den skjulte inngangen vil bli simulert og vinduet for valg av systemfil vises. Merk at input har en flere parameter, som lar deg velge mange filer samtidig.

    Når filene er valgt, står de i kø for senere automatisk nedlasting:

    $(function())( var ul = $("#upload ul"); $("#drop a").click(function())( // simulere å klikke på filvalgfeltet $(this).parent (). find("input").click(); )); // initialiser jQuery-pluginen File Upload $("#upload").fileupload(( // dette elementet vil akseptere filer som slippes på det dropZone: $( "#drop" ), // Funksjonen kalles når filen er i kø add: function (e, data) ( var tpl = $("

  • "); // skriv ut filnavnet og størrelsen tpl.find("p").text(data.files.name) .append(" " + formatFileSize(data.files.size) + ""); data.context = tpl.appendTo(ul); // initialisering av jQuery Knob-plugin tpl.find("input").knob(); // sporing av klikk på avbryt-ikonet tpl.find("span") .click (function())( if(tpl.hasClass("working"))( jqXHR.abort(); ) tpl.fadeOut(function())( tpl.remove(); )); )); // Last inn filen automatisk når du legger til i køen var jqXHR = data.submit(); ), progress: function(e, data)( // Beregner innlastingsprosenten var progress = parseInt(data.loaded / data.total * 100, 10); // oppdatering av skalaen data.context.find("input").val(progress).change(); if(progress == 100)( data.context.removeClass("working"); ) ), fail:function(e, data) ( // noe gikk galt data.context.addClass("feil"); ) )); $(document).on("slipp dragover", funksjon (e) ( e.preventDefault( ); )); // hjelpefunksjon som formaterer filstørrelsesfunksjonen formatFileSize(bytes) ( if (typebytes !== "nummer") ( return ""; ) if (bytes >= 1000000000) ( return (bytes / 1000000000) ).toFixed(2 ) + "GB"; ) if (bytes >= 1000000) ( return (bytes / 1000000).toFixed(2) + " MB"; ) return (bytes / 1000).toFixed(2) + " KB"; ) ));

    jQuery File Upload har sitt eget grensesnitt, men vi bruker den grunnleggende versjonen av plugin til å lage vårt eget grensesnittdesign. Og for at grensesnittet vårt skal fungere, sender vi flere parametere / tilbakeringinger til pluginet:

    • dropZone – Denne parameteren inneholder en jQuery-velger som vil akseptere slettede filer. Filer som slippes på den vil bli lagt til nedlastingskøen.
    • add – funksjonen kalles når en fil legges til i nedlastingskøen. Den vil generere markering for filene og kalle opp data.submit()-metoden.
    • fremgang – Denne funksjonen kalles opp hver 100 ms (kan endres). Det andre argumentet inneholder filstørrelsen og antall nedlastede byte. Dette lar deg spore fremgang og oppdatere skalaen.
    • fail – funksjonen kalles opp når en feil oppstår.
    PHP

    jQuery File Upload-settet inkluderer også et PHP-skript for å behandle filer på serveren, men vi vil skrive vårt eget. Prosessen med å laste ned filer vil skje på samme måte som under en vanlig nedlasting, slik at vi kan få all informasjon om dem fra den globale $_FILES-arrayen:

    Arbeider med nedlastede filer

    For å samhandle fullt ut med filene dine trenger vi bare å legge til muligheten til å manipulere dem. Først må vi legge til et stykke kode for å trekke ut informasjon om de lagrede filene (navn og størrelse) og returnere den i JSON-format.

    For å gjøre dette, oppdater upload.php-filen til dette skjemaet (den andre betingelsen er satt inn):

  • PHP scandir-funksjonen skanner opplastingsmappen og returnerer en rekke filer eller FALSE hvis mappen er tom.
  • Vi går gjennom returverdien fra scandir-funksjonen og lagrer den i $result-matrisen. Husk at vi ignorerer "." Og ".." siden scandir alltid vil returnere "." Og ".." som gyldig innhold relatert til gjeldende og forrige katalog.
  • Vi sender ut de riktige overskriftene for JSON-markering, og konverterer også PHP-arrayen til en JSON-streng ved å bruke json_encode-funksjonen.
  • Nå er det på tide å oppdatere index.php:

    Dropzone.options.myDropzone = ( init: function() ( thisDropzone = this; $.get("upload.php", function(data) ( $.each(data, function(key,value)( var mockFile = ( navn : verdi.navn, størrelse: verdi.størrelse ); thisDropzone.options.addedfile.call(thisDropzone, mockFile); thisDropzone.options.thumbnail.call(thisDropzone, mockFile, "uploads/"+value.name); )); )); ) );

    Hva har vi gjort her? La oss finne ut av det:

  • Akk, vi har lagt til Jquery-biblioteket på siden vår. Dette er egentlig ikke en nødvendighet for DropzoneJs. Vi bruker bare JQuery $.get ajax-funksjonen. Etter eget skjønn kan du implementere lignende forespørsler i vue.js eller hva du foretrekker.
  • Vi har lagt til et ID-element (my-dropzone) i skjemaet. Dette er nødvendig for å overføre konfigurasjonsverdier til Dropzone. Og for dette må vi ha en unik identifikator som peker på den. På denne måten kan vi konfigurere biblioteket ved å tilordne verdier til Dropzone.options.myDropzone.
  • La oss initialisere hoveddelen av redigeringen. Det vi har gjort her er sendt en funksjon for å lytte etter init-hendelsen til Dropzone. Denne hendelsen utløses når Dropzone initialiseres.
  • Vi mottar en rekke filer fra "upload.php" ved hjelp av ajax.
  • Lag en mockFile ved å bruke verdiene fra serveren. MockFiles er ganske enkelt JavaScript-objekter med navn og størrelsesegenskaper. Vi kaller da eksplisitt Dropbox-funksjoner og legger til ikoner for å bringe eksisterende filer inn i Dropzone-opplastingsområdet og lage miniatyrbilder av dem.
  • Hvis du gjorde alt riktig. Last opp noen bilder og last inn skjemasiden på nytt. Tidligere opplastede filer skal automatisk vises i Dropzone-området.