JavaScript 在粘贴事件中获取剪贴板数据(跨浏览器)

2022-01-29 00:00:00 clipboard javascript cross-browser

Web 应用程序如何检测粘贴事件并检索要粘贴的数据?

How can a web application detect a paste event and retrieve the data to be pasted?

我想在将文本粘贴到富文本编辑器之前删除 HTML 内容.

I would like to remove HTML content before the text is pasted into a rich text editor.

在粘贴之后清除文本是可行的,但问题是所有以前的格式都丢失了.例如,我可以在编辑器中写一个句子并将其加粗,但是当我粘贴新文本时,所有格式都丢失了.我想只清理粘贴的文本,而保留以前的任何格式.

Cleaning the text after being pasted afterwards works, but the problem is that all previous formatting is lost. For example, I can write a sentence in the editor and make it bold, but when I paste new text, all formatting is lost. I want to clean just the text that is pasted, and leave any previous formatting untouched.

理想情况下,该解决方案应适用于所有现代浏览器(例如 MSIE、Gecko、Chrome 和 Safari).

Ideally, the solution should work across all modern browsers (e.g., MSIE, Gecko, Chrome, and Safari).

请注意,MSIE 有 clipboardData.getData(),但我找不到其他浏览器的类似功能.

Note that MSIE has clipboardData.getData(), but I could not find similar functionality for other browsers.

推荐答案

写下这个答案后情况发生了变化:现在 Firefox 在 22 版中增加了支持,现在所有主流浏览器都支持在粘贴事件.有关示例,请参阅 Nico Burns 的回答.

在过去,这通常无法以跨浏览器的方式实现.理想的情况是能够通过 paste 事件 这在最近的浏览器中是可能的,但在一些较旧的浏览器中是不可能的(特别是 Firefox <22).

In the past this was not generally possible in a cross-browser way. The ideal would be to be able to get the pasted content via the paste event, which is possible in recent browsers but not in some older browsers (in particular, Firefox < 22).

当您需要支持较旧的浏览器时,您可以做的是相当复杂的事情,并且需要一些 hack 才能在 Firefox 2+、IE 5.5+ 和 WebKit 浏览器(如 Safari 或 Chrome)中运行.TinyMCE 和 CKEditor 的最新版本都使用了这种技术:

When you need to support older browsers, what you can do is quite involved and a bit of a hack that will work in Firefox 2+, IE 5.5+ and WebKit browsers such as Safari or Chrome. Recent versions of both TinyMCE and CKEditor use this technique:

  1. 使用按键事件处理程序检测 ctrl-v/shift-ins 事件
  2. 在该处理程序中,保存当前用户选择,在文档中添加一个屏幕外的 textarea 元素(比如左侧 -1000 像素),关闭 designMode 并调用 focus() 在 textarea 上,从而移动插入符号并有效地重定向粘贴
  3. 在事件处理程序中设置一个非常简短的计时器(例如 1 毫秒)以调用另一个存储 textarea 值的函数,从文档中删除 textarea,重新打开 designMode,恢复用户选择并将文本粘贴进去.
  1. Detect a ctrl-v / shift-ins event using a keypress event handler
  2. In that handler, save the current user selection, add a textarea element off-screen (say at left -1000px) to the document, turn designMode off and call focus() on the textarea, thus moving the caret and effectively redirecting the paste
  3. Set a very brief timer (say 1 millisecond) in the event handler to call another function that stores the textarea value, removes the textarea from the document, turns designMode back on, restores the user selection and pastes the text in.

请注意,这仅适用于键盘粘贴事件,不适用于从上下文或编辑菜单粘贴.当 paste 事件触发时,将插入符号重定向到 textarea 为时已晚(至少在某些浏览器中).

Note that this will only work for keyboard paste events and not pastes from the context or edit menus. By the time the paste event fires, it's too late to redirect the caret into the textarea (in some browsers, at least).

万一您需要支持 Firefox 2,请注意您需要将 textarea 放置在父文档中,而不是该浏览器中的 WYSIWYG 编辑器 iframe 文档中.

In the unlikely event that you need to support Firefox 2, note that you'll need to place the textarea in the parent document rather than the WYSIWYG editor iframe's document in that browser.

相关文章