Skip to content

How to implement file upload with drag and drop in vanilla JS

I wrote about the Drag and Drop API concepts in the past.

Now I want to show how I implemented a simple file upload with drag and drop on a site I’m building.

Identify an HTML element you want people to drag their files to:

<div  class="dropzone"  ondragover=`dragOverHandler(event)`  ondragleave=`dragLeaveHandler(event)`  ondrop=`dropHandler(event)`  > ... </div>

ondragover is fired when people are dragging a file on the element. We can use this to add some style, for example a dashed border.

ondragleave is the opposite, when we exit the drop area.

I used this JS to add a dragging_over class to the element, and style it with CSS:

function dragOverHandler(event) {  event.preventDefault();  const dropzone = document.querySelector('#dropzone');  dropzone.classList.add('dragging_over'); }  function dragLeaveHandler(event) {  event.preventDefault();  const dropzone = document.querySelector('#dropzone');  dropzone.classList.remove('dragging_over'); }
#dropzone.dragging_over {  border: 2px dashed #fff;  background-color: #666; }

ondrop is fired when the file (or multiple files!) is dropped on the area.

That’s where the action happens.

I gather the files, check they’re images (I only want images in this example), and POST the data to /api/upload:

async function dropHandler(event) {  event.preventDefault()   const endpoint = `/api/upload`   if (event.dataTransfer.items) {  const formData = new FormData()  formData.append('action', 'upload')   for (let item of event.dataTransfer.items) {  if (item.kind === 'file') {  const file = item.getAsFile()  if (file) {   //I only want images  if (!file.type.match('image.*')) {  alert('only images supported')  return  }  formData.append('files', file)  }  }  }   try {  const response = await fetch(endpoint, {  method: 'POST',  body: formData,  })   if (response.ok) {  console.log('File upload successful')  } else {  console.error('File upload failed', response)  }  } catch (error) {  console.error('Error uploading file', error)  }  } }

How to handle that server-side depends on your server.

With Astro I got the data using:

const formData = await Astro.request.formData()  console.log(formData.getAll('files'))

→ Get my JavaScript Beginner's Handbook

I wrote 20 books to help you become a better developer:

  • JavaScript Handbook
  • TypeScript Handbook
  • CSS Handbook
  • Node.js Handbook
  • Astro Handbook
  • HTML Handbook
  • Next.js Pages Router Handbook
  • Alpine.js Handbook
  • HTMX Handbook
  • React Handbook
  • SQL Handbook
  • Git Cheat Sheet
  • Laravel Handbook
  • Express Handbook
  • Swift Handbook
  • Go Handbook
  • PHP Handbook
  • Python Handbook
  • Linux/Mac CLI Commands Handbook
  • C Handbook
...download them all now!

Related posts about platform: