优雅可靠的取消粘贴事件的方法,但稍后再发送

时间:2014-11-19 00:03:36

标签: javascript events

在javascript API中粘贴当前非常糟糕的图片There's a workaround您在其中使用户将图像粘贴到contenteditable div中。然后,浏览器会创建一个<img>元素,您可以使用.getElementsByTagName方法检索该元素。

但是如果用户粘贴从资源管理器或类似程序复制的文件,这些文件不会出现在div中,但可以使用API​​进行检索。

<div id='paste' contenteditable='true'>Paste</div>

所以我有一个onpaste事件,完全能够检索粘贴的文件(任何文件类型):

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
});

实际上,粘贴事件原点是<input>,因此要将文本粘贴为HTML,我会在粘贴事件之前从输入字段中窃取焦点:

//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");
  }
});

现在在 Ctrl + V 之后,如果没有文件,其他名为input的事件最终会在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();

});

正如您可以看到图像是否粘贴在textarea中一样,它将被处理。但如果没有,粘贴事件将无法执行任何操作!

如果没有粘贴图像,我最终如何才能在textarea中发生粘贴事件?

我试图将事件保存在变量中:

var lastPaste;
paste.addEventListener('paste', function(event){
  lastPast = event;
  ...
}

然后发送它:

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;
}

它没有做任何事情。什么都没有粘贴。

1 个答案:

答案 0 :(得分:0)

您可以在“粘贴”输入中检索文字内容,并在没有图片的情况下保存。

.clipboardData.getData('text/plain')

另请注意,.clipboardData.files.clipboardData.items不同,命名.clipboardData items只会让人感到困惑,因为它们的结构不同。