Currently, the process of pasting images in JavaScript API is not optimal. A workaround involves having the user paste the image into a contenteditable div, which then prompts the browser to create an <img>
element that can be retrieved using the .getElementsByTagName
method.
However, when users paste files copied from Explorer or a similar program, these files do not appear in the div but can still be retrieved using the API.
<div id='paste' contenteditable='true'>Paste</div>
I have implemented an onpaste
event that successfully retrieves pasted files 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 addition, the paste event originates from an <input>
, so to access the text pasted as HTML, I shift focus away from the input field prior to the 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");
}
});
Subsequently, after pressing Ctrl + V, if no file is present, another event known as input
will trigger within 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();
});
If an image is pasted in the textarea, it will be processed accordingly. However, if no image is pasted, the paste event will remain inactive!
The challenge lies in allowing the paste event to proceed in the textarea even when no images are pasted:
My attempt involved saving the event in a variable:
var lastPaste;
paste.addEventListener('paste', function(event){
lastPast = event;
...
}
And subsequently dispatching it:
paste.addEventListener('input', function(event){
...
//Focus back on the input
input.focus();
//The paste event must now be dispatched in the textarea:
input.dispatchEvent(lastPaste);
lastPaste = null;
}
Unfortunately, this approach does not produce the desired outcome. No content is pasted.