Christian Heilmann

⚡️Fun with browsers: how to get an image into the current page

Friday, March 20th, 2020 at 10:13 pm

Having been a web developer for as long as I have can get you tainted. You always assume things to break in one way or another or some clever new web API not getting the support it needs for ages. As it turns out, the speed with which browsers adapt to standards has become increasingly faster. That’s why it is important to keep up to date and give yourself simple challenges to see if tasks that in the past were a huge hassle have now become easier.

That’s what I did today. I gave myself the task to build an interface to make it as easy as possible for a user to add an image into the document. I wanted to support:

  • Image upload
  • Drag and Drop
  • Copy and Paste

Looking at Stackoverflow for some solutions is a huge disappointment as many solutions either are woefully outdated. Looking through the specs and at Can I use, I found it is excitingly short code you need to accomplish all of the above.

This Codepen shows the final outcome and works swimmingly here on Edge, Firefox, Safari and Chrome.

And the full code is not that much.

In the HTML we need to have a container element that is a drop target (I made this cover the whole document in CSS).

    <div id="container">
      <h1>Getting an image into the browser</h1>
      <p>Drag and Drop and image, paste it, or use the upload bar below</p>
      <div>
          <input id="getfile" type="file" />
          <label for="getfile">Upload an image</label>
      </div>
      <div id="imagecontainer"></div>
      <output></output>
    </div>

The JavaScript needs to reference those and set the appropriate event handlers. The rest is looking at the URL standards.

(function(){
const fileinput = document.querySelector('#getfile');
const output = document.querySelector('output');
const imagecontainer = document.querySelector('#imagecontainer');
 
/* Show the image once we have it */
const loadImage = (file, name) => {
  if (name) {
    output.innerText = 'Filename: ' + name;
  }
  var img = new Image();
  img.src = file;
  img.onload = function() {
    imagecontainer.appendChild(img);
  };
}
 
/* Image from Clipboard */
const getClipboardImage = (ev) => {
  let items = ev.clipboardData.items;
  for (var i = 0; i < items.length; i++) {
    if (items[i].type.indexOf('image') !== -1) {
      var blob = items[i].getAsFile();
      loadImage(window.URL.createObjectURL(blob));
      break;
    }
  }
}
window.addEventListener('paste', getClipboardImage, false);
 
/* Image from Drag and Drop */
const imageFromDrop = (e) => {
  var file = e.dataTransfer.files[0];
  loadImage(window.URL.createObjectURL(file), file.name);
  e.preventDefault();
}
container.addEventListener('drop', imageFromDrop, false);
// Override the normal drag and drop behaviour
container.addEventListener('dragover', (ev) => {
  ev.preventDefault();
}, false);
 
/* Image from Upload */
const imageFromUpload = (e) => {
  var file = e.target.files[0];
  loadImage(window.URL.createObjectURL(file), file.name);
  e.preventDefault();
}
fileinput.addEventListener('change', imageFromUpload, false);
 
})();

We live in exciting times for web developers, don’t let yourself be bogged down by slowness of the past. I’m still having fun with it.

Share on Twitter