Come creare un Image Uploader HTML5 con DropzoneJS

Qualche tempo fa, ho scritto un paio di tutorial su come progettare e codificare un controllo per il caricamento di file usando il plugin BlueQuery-Upload di file jQuery. Entrambi gli articoli, insieme a uno sul trascinamento di file nel browser utilizzando il binding di eventi jQuery , hanno generato il maggior interesse dei miei mille e più pezzi fino ad ora. Oggi sono entusiasta di annunciare che mi sono imbattuto in una libreria JavaScript che combina entrambe queste funzionalità ambite in un unico pacchetto facile da usare. chiamato DropzoneJS, è una libreria open source che fornisce upload di file drag-drop con anteprime di immagini. Non è solo leggero, completamente personalizzabile, ma non dipende da nessun’altra libreria (come jQuery). Hanno una demo sulla loro pagina principale. Nel tutorial di oggi, impareremo come ricrearlo.

Fare riferimento alla libreria

La libreria DropzoneJS è costituita da un file .js e un file .css facoltativo. Entrambi sono disponibili per il download dal repository Github . (Ci sono alcuni file aggiuntivi da usare anche con i componenti e con RequireJS .) Puoi scaricare i file da lì o fare quello che fanno i ragazzi fantastici e collegarti a un host fidato come cdnjs .

- Prosegue dopo la pubblicità -
1
2
3
4
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;"><Head></font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
  <script src = "https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.3.0/dropzone.js"> </ script></font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
  <link rel = "stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.3.0/dropzone.css" /></font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
</ Head></font></font><font></font>

Il markup HTML

Il modo più semplice per usare DropzoneJS è creare un elemento form con la classe “dropzone”. Questo è tutto; mentre il nostro modulo ha un DIV in più con le istruzioni, la libreria dropzoneJS creerà per te l’area selezionabile e presenterà un controllo di upload di fallback per i browser più vecchi.

- Prosegue dopo la pubblicità -
1
2
3
4
5
6
7
8
9
10
11
12
<h1>DropzoneJS File Upload Demo</h1><font></font>
<SECTION><font></font>
  <DIV id="dropzone"><font></font>
    <FORM class="dropzone needsclick" id="demo-upload" action="/upload"><font></font>
      <DIV class="dz-message needsclick">   <font></font>
        Drop files here or click to upload.<BR><font></font>
        <SPAN class="note needsclick">(This is just a demo dropzone. Selected<font></font>
        files are <STRONG>not</STRONG> actually uploaded.)</SPAN><font></font>
      </DIV><font></font>
    </FORM><font></font>
  </DIV><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
</ Section></font></font><font></font>

Simulazione del componente server

Dropzone non fornisce l’implementazione lato server della gestione dei file, ma invia i file al server esattamente come un modulo con la codifica “multipart / form-data”.

- Prosegue dopo la pubblicità -

Come dice il messaggio, il componente dropzone segnala il successo anche se i file non vengono caricati. L’aspetto del caricamento dei file è ottenuto dalla creazione programmatica della dropzone insieme all’inclusione di alcuni elementi HTML duplicati.

Iniziamo con l’istanziazione della classe dropzone. Il costruttore Dropzone (maiuscolo ‘D’) prende l’ID del componente di destinazione e un oggetto di opzioni. Quest’ultimo può anche essere utilizzato per sovrascrivere i metodi:

- Prosegue dopo la pubblicità -
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;">// Classe Dropzone:</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
var dropzone = new Dropzone ('# demo-upload', {</font></font><font></font>
  previewTemplate: document.querySelector('#preview-template').innerHTML,<font></font>
  parallelUploads: 2,<font></font>
  thumbnailHeight: 120,<font></font>
  thumbnailWidth: 120,<font></font>
  maxFilesize: 3,<font></font>
  filesizeBase: 1000,<font></font>
  thumbnail: function(file, dataUrl) {<font></font>
    if (file.previewElement) {<font></font>
      file.previewElement.classList.remove("dz-file-preview");<font></font>
      var images = file.previewElement.querySelectorAll("[data-dz-thumbnail]");<font></font>
      for (var i = 0; i < images.length; i++) {<font></font>
        var thumbnailElement = images[i];<font></font>
        thumbnailElement.alt = file.name;<font></font>
        thumbnailElement.src = dataUrl;<font></font>
      }<font></font>
      setTimeout(function() { file.previewElement.classList.add("dz-image-preview"); }, 1);<font></font>
    }<font></font>
  }<font></font>
<font></font>
});<font></font>

Il passo successivo consiste nel falsificare il caricamento del file, poiché il server restituisce un 404. Ciò avviene sovrascrivendo la funzione uploadFiles (). Il codice risultante è abbastanza coinvolto, ma puoi vedere dove imposta il file.status Dropzone.SUCCESS. C’è anche un sacco di lavoro per rendere il progresso del caricamento normale.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var minSteps = 6,<font></font>
    maxSteps = 60,<font></font>
    timeBetweenSteps = 100,<font></font>
    bytesPerStep = 100000;<font></font>
<font></font>
dropzone.uploadFiles = function(files) {<font></font>
  var self = this;<font></font>
<font></font>
  for (var i = 0; i < files.length; i++) {<font></font>
<font></font>
    var file = files[i];<font></font>
    totalSteps = Math.round(Math.min(maxSteps, Math.max(minSteps, file.size / bytesPerStep)));<font></font>
<font></font>
    for (var step = 0; step < totalSteps; step++) {<font></font>
      var duration = timeBetweenSteps * (step + 1);<font></font>
      setTimeout(function(file, totalSteps, step) {<font></font>
        return function() {<font></font>
          file.upload = {<font></font>
            progress: 100 * (step + 1) / totalSteps,<font></font>
            total: file.size,<font></font>
            bytesSent: (step + 1) * file.size / totalSteps<font></font>
          };<font></font>
<font></font>
          self.emit('uploadprogress', file, file.upload.progress, file.upload.bytesSent);<font></font>
          if (file.upload.progress == 100) {<font></font>
            file.status = Dropzone.SUCCESS;<font></font>
            self.emit("success", file, 'success', null);<font></font>
            self.emit("complete", file);<font></font>
            self.processQueue();<font></font>
          }<font></font>
        };<font></font>
      }(file, totalSteps, step), duration);<font></font>
    }<font></font>
  }<font></font>
}<font></font>

Questo ci porta agli elementi HTML duplicati. Questi includono un’intera massa di informazioni per le anteprime, i messaggi, così come i segni di spunta e l’errore “X”. Si noti che i segni di spunta su successo e errore vengono visualizzati utilizzando SVG.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<DIV id="preview-template" style="display: none;"><font></font>
<DIV class="dz-preview dz-file-preview"><font></font>
<DIV class="dz-image"><IMG data-dz-thumbnail=""></DIV><font></font>
<DIV class="dz-details"><font></font>
<DIV class="dz-size"><SPAN data-dz-size=""></SPAN></DIV><font></font>
<DIV class="dz-filename"><SPAN data-dz-name=""></SPAN></DIV></DIV><font></font>
<DIV class="dz-progress"><SPAN class="dz-upload"<font></font>
data-dz-uploadprogress=""></SPAN></DIV><font></font>
<DIV class="dz-error-message"><SPAN data-dz-errormessage=""></SPAN></DIV><font></font>
<div class="dz-success-mark"><font></font>
  <svg width="54px" height="54px" viewBox="0 0 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"><font></font>
    <!-- Generator: Sketch 3.2.1 (9971) - http://www.bohemiancoding.com/sketch --><font></font>
    <title>Check</title><font></font>
    <desc>Created with Sketch.</desc><font></font>
    <defs></defs><font></font>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage"><font></font>
        <path d="M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z" id="Oval-2" stroke-opacity="0.198794158" stroke="#747474" fill-opacity="0.816519475" fill="#FFFFFF" sketch:type="MSShapeGroup"></path><font></font>
    </g><font></font>
  </svg><font></font>
</div><font></font>
<div class="dz-error-mark"><font></font>
  <svg width="54px" height="54px" viewBox="0 0 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"><font></font>
      <!-- Generator: Sketch 3.2.1 (9971) - http://www.bohemiancoding.com/sketch --><font></font>
      <title>error</title><font></font>
      <desc>Created with Sketch.</desc><font></font>
      <defs></defs><font></font>
      <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage"><font></font>
          <g id="Check-+-Oval-2" sketch:type="MSLayerGroup" stroke="#747474" stroke-opacity="0.198794158" fill="#FFFFFF" fill-opacity="0.816519475"><font></font>
              <path d="M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z" id="Oval-2" sketch:type="MSShapeGroup"></path><font></font>
          </g><font></font>
      </g><font></font>
  </svg><font></font>
</div><font></font>

Conclusione

DropzoneJS è una grande libreria e non vedo l’ora di giocarci nei prossimi mesi.