HTML5 drag & drop for humans
In case you didn't know, the HTML5 drag and drop API is a total disaster! This is an attempt to make the API usable by mere mortals.
See https://instant.io.
dragclass to the drop target on hover, for easy styling!
npm install drag-drop
This package works in the browser with browserify. If you do not use a bundler, you can use the standalone script directly in a
tag.const dragDrop = require('drag-drop')dragDrop('#dropTarget', (files, pos, fileList, directories) => { console.log('Here are the dropped files', files) // Array of File objects console.log('Dropped at coordinates', pos.x, pos.y) console.log('Here is the raw FileList object if you need it:', fileList) console.log('Here is the list of directories:', directories) })
Another handy thing this does is add a
dragclass to the drop target when the user is dragging a file over the drop target. Useful for styling the drop target to make it obvious that this is a drop target!
const dragDrop = require('drag-drop')// You can pass in a DOM node or a selector string! dragDrop('#dropTarget', (files, pos, fileList, directories) => { console.log('Here are the dropped files', files) console.log('Dropped at coordinates', pos.x, pos.y) console.log('Here is the raw FileList object if you need it:', fileList) console.log('Here is the list of directories:', directories)
//
files
is an Array! files.forEach(file => { console.log(file.name) console.log(file.size) console.log(file.type) console.log(file.lastModifiedDate) console.log(file.fullPath) // not real full path due to browser security restrictions console.log(file.path) // in Electron, this contains the actual full path// convert the file to a Buffer that we can use! const reader = new FileReader() reader.addEventListener('load', e => { // e.target.result is an ArrayBuffer const arr = new Uint8Array(e.target.result) const buffer = new Buffer(arr) // do something with the buffer! }) reader.addEventListener('error', err => { console.error('FileReader error' + err) }) reader.readAsArrayBuffer(file)
}) })
If you prefer to access file data as Buffers, then just require drag-drop like this:
const dragDrop = require('drag-drop/buffer')dragDrop('#dropTarget', files => { files.forEach(file => { // file is actually a buffer! console.log(file.readUInt32LE(0)) console.log(file.toJSON()) console.log(file.toString('hex')) // etc...
// but it still has all the normal file properties! console.log(file.name) console.log(file.size) console.log(file.type) console.log(file.lastModifiedDate)
}) })
To stop listening for drag & drop events and remove the event listeners, just use the
removefunction returned by the
dragDropfunction.
const dragDrop = require('drag-drop')const remove = dragDrop('#dropTarget', files => { // ... })
// ... at some point in the future, stop listening for drag & drop events remove()
dragenter,
dragoverand
dragleaveevents
Instead of passing just an
ondropfunction as the second argument, instead pass an object with all the events you want to listen for:
const dragDrop = require('drag-drop')dragDrop('#dropTarget', { onDrop: (files, pos, fileList, directories) => { console.log('Here are the dropped files', files) console.log('Dropped at coordinates', pos.x, pos.y) console.log('Here is the raw FileList object if you need it:', fileList) console.log('Here is the list of directories:', directories) }, onDragEnter: () => {}, onDragOver: () => {}, onDragLeave: () => {} })
If the user highlights text and drags it, we capture that as a separate event. Listen for it like this:
const dragDrop = require('drag-drop')dragDrop('#dropTarget', { onDropText: (text, pos) => { console.log('Here is the dropped text:', text) console.log('Dropped at coordinates', pos.x, pos.y) } })
file://urls
Don't run your app from
file://. For security reasons, browsers do not allow you to run your app from
file://. In fact, many of the powerful storage APIs throw errors if you run the app locally from
file://.
Instead, start a local server and visit your site at
http://localhost:port.
MIT. Copyright (c) Feross Aboukhadijeh.