Pasting of images currently quite sucks in javascript API. There's a workaround in which you make the user paste the image in contenteditable div. The browser then creates a <img>
element which you can retrieve using .getElementsByTagName
method.
But if user pastes files copied from Explorer or similar program, these don't appear in div but can be retrieved using API.
<div id='paste' contenteditable='true'>Paste</div>
So I have one onpaste
event which is fully capable of retrieving pasted file (of any file type):
paste.addEventListener('paste', function(event){
var items = (event.clipboardData || event.originalEvent.clipboardData);
/**Try to get a file**/
var files = items.items || items.files;
if(files.length>0) {
//Read the file
applyFile(files[0].getAsFile? files[0].getAsFile():files[0]);
//Do not input any text
event.preventDefault();
event.cancelBubble = true;
return false;
}
//No files = try to paste text in HTML div
});
In fact, the paste event origin is a <input>
, so to get the text pasted as HTML, I steal focus from input field before paste event:
//When pasting, focus on the PASTE element
input.addEventListener("keydown", function(e) {
if(e.keyCode==86&&e.ctrlKey) {
paste.focus();
console.log("Focusing the div");
}
});
Now after Ctrl + V, if there's no file other event called input
will eventually dispatch on the div:
paste.addEventListener('input', function(event){
//An array of pasted images
var images = this.getElementsByTagName("img");
if(images.length!=0) {
//Do something
...
}
//Clear the div (image references will be lost!)
this.innerHTML = "";
//Focus back on the input
input.focus();
});
As you can see if an image is pasted in the textarea it will be processed. But if not, the paste event will not do anything!
How can I eventually let the paste event happen in the textarea if no images were pasted?
I tried to save the event in variable:
var lastPaste;
paste.addEventListener('paste', function(event){
lastPast = event;
...
}
And then dispatch it:
paste.addEventListener('input', function(event){
...
//Focus back on the input
input.focus();
//The paste event now must be dispatched in textarea:
input.dispatchEvent(lastPaste);
lastPaste = null;
}
It doesn't do anything. Nothing is pasted.