Does HTML / Javascript support dragging and dropping an image onto a web page?

Does HTML5 / Javascript support dragging and dropping an image onto a web page?

i.e.

Can I create a web page that allows the user to drag an image from another site directly to the placeholder on my site (on all clients), and then use another button to upload this image to the server?

+4
source share
1 answer

I can’t say exactly how all browsers did / did / behaved in such a case, but I saw that when you drag an image from a web page and drop it onto the web page (the same or different), the browsers will not create from it a file (or Blob), but only its markup.

, - , .. , , .

src.

, , :

  • : , FormData multipart. , <img> src blobURI, .
  • -: DataTransfer text/html. , <img>. , . , , ( ), URI .

var dropzone = document.getElementById('dropzone'),
  send_btn = document.getElementById('send'),
  res = document.getElementById('res'),
  imgList = [];

dropzone.ondragover = function ondragover(e) {
  e.preventDefault();
  dropzone.classList.add('dragover');
};
dropzone.ondrop = function ondrop(e) {
  e.preventDefault();
  dropzone.classList.remove('dragover');
  // try to get images from this dropevent
  var imageObjects = retrieveImageData(e.dataTransfer);
  if (!imageObjects) return;
  imageObjects.forEach(function appendToDoc(imgObj) {
    res.appendChild(imgObj.element);
  });
  // store it
  imgList = imgList.concat(imageObjects);
  if (imageObjects.length)
    send_btn.disabled = false;
};
dropzone.ondragexit = function(ondragexit) {
  dropzone.classList.remove('dragover');
};

function retrieveImageData(dT) {
  // first try to get Files
  var files = getFiles(dT);
  if (files.length) {
    return files;
  }
  // if none, try to get HTMLImage or SVGImage
  var elems = getHTMLMarkup(dT);
  if (elems && elems.length) {
    return elems;
  }
  // we could also try to getData('text/plain') hoping for an url
  // but this might not be such a good idea...
  console.warn('unable to retrieve any image in dropped data');
}

function getFiles(dT) {
  // quite simple: won't traverse folders
  var files = [],
    imgObj;
  if (dT.files && dT.files.length) {
    for (var i = 0; i < dT.files.length; i++) {
      // only image Files
      if (dT.files[i].type.indexOf('image/') === 0) {
        imgObj = {
          type: 'file',
          element: new Image(),
          file: dT.files[i]
        };
        imgObj.element.onerror = onIMGError;
        imgObj.element.src = URL.createObjectURL(imgObj.file);
        files.push(imgObj);
      }
    }
  }
  return files;
}

function getHTMLMarkup(dT) {
  var markup = dT.getData('text/html');
  if (markup) {
    var doc = new DOMParser().parseFromString(markup, 'text/html');
    var imgs = doc && doc.querySelectorAll('img,image') ||  [];
    imgs.forEach(toImageObject);
    return Array.prototype.map.call(imgs, toImageObject);
  }

  function toImageObject(element) {
    var img;
    if (element instanceof SVGImageElement) {
      img = new Image();
      img.src = element.getAttributeNS('http://www.w3.org/1999/xlink', 'href') ||
        element.getAttribute('href');
    } else {
      img = document.adoptNode(element);
    }
    img.onerror = onIMGError;
    return {
      type: 'element',
      element: img
    };
  }
}
// Once we got everything, time to retrieve our objects
send_btn.onclick = function sendData() {
  var fD = new FormData();
  // send Files data directly
  var files = imgList.filter(function isFile(obj) {
    return obj.type === 'file';
  });
  files.forEach(function appendToFD(obj) {
    fD.append('files[]', obj.file);
  });
  // for elems, we will need to grab the data from the server
  var elems = imgList.filter(function isElem(obj) {
    return obj.type === "element";
  });
  var urls = elems.map(function grabURL(obj) {
    return obj.element.src;
  });
  if (urls.length)
    fD.append('urls', JSON.stringify(urls));

  sendFormData(fD);
};

function sendFormData(fD) {
  var xhr = new XMLHttpRequest();
  xhr.open('POST', 'your_url');
  // you would normally send it
  //xhr.send(fD);

  // but here we will just log the formData content
  var files = fD.getAll('files[]');
  console.log('files: ', files);
  var urls = fD.get('urls');
  console.log('urls', urls);
}
// in case we can't load it
function onIMGError() {
  var img = this;
  var index = -1;
  imgList.forEach(function search(obj, i) {
    if (index < 0 && obj && obj.element === img)
      index = i;
  });
  // remove from our list
  if (index > -1) {
    imgList.splice(index, 1);
    if (img.parentNode) img.parentNode.removeChild(img);
  }
}
#dropzone {
  width: 300px;
  height: 150px;
  border: 1px solid black;
}

#dropzone.dragover {
  background: rgba(0, 0, 0, .5);
}

#res {
  border: 1px solid black;
}
<div id="dropzone">drop here</div>
<button id="send" disabled>log saved objects</button>
<div id="res">results:<br></div>
Hide result

, contenteditable <img>. , , , .

+3

Source: https://habr.com/ru/post/1694715/


All Articles