JavaScript获取粘贴事件的剪贴板数据(跨浏览器)
Web应用程序如何检测粘贴事件并检索要粘贴的数据?
在将文本粘贴到富文本编辑器之前,我想删除HTML内容。
之后粘贴的文本清理工作,但问题是,所有以前的格式丢失。 例如,我可以在编辑器中编写一个句子并将其设置为粗体,但是当我粘贴新文本时,所有格式都将丢失。 我只想清理粘贴的文本,并保持以前的格式不变。
理想的情况下,解决scheme应该适用于所有现代浏览器(例如MSIE,Gecko,Chrome和Safari)。
请注意,MSIE有clipboardData.getData()
,但我找不到其他浏览器的类似function。
自写这个答案以来情况已经改变了:现在,Firefox已经增加了对版本22的支持,现在所有的主stream浏览器都支持在粘贴事件中访问剪贴板数据。 以尼科·伯恩斯的答案为例。
在过去,这通常不可能以跨浏览器的方式进行。 理想的做法是能够通过paste
事件获取粘贴的内容, 这在最近的浏览器中是可能的,但在一些较旧的浏览器中是不可能的(特别是Firefox <22)。
当你需要支持旧版本的浏览器时,你可以做的事情非常多,并且可以在Firefox2 +,IE5.5+和WebKit浏览器(如Safari或Chrome)上运行。 TinyMCE和CKEditor的最新版本都使用这种技术:
- 使用按键事件处理程序检测ctrl-v / shift-ins事件
- 在该处理程序中,保存当前的用户select,在屏幕外添加一个textarea元素(比如在左边-1000px)到文档中,closures
designMode
并调用textarea上的focus()
,从而移动插入符号并有效地redirect粘贴 - 在事件处理程序中设置一个非常简短的计时器(比如1毫秒),以调用另一个存储textarea值的函数,从文档中移除textarea,重新打开
designMode
,恢复用户select并粘贴文本。
请注意,这只适用于键盘粘贴事件,不适用于上下文或编辑菜单。 在粘贴事件触发时,将脱字符redirect到textarea(至less在某些浏览器中)为时已晚。
如果您需要支持Firefox 2,请注意,您需要将textarea放在父文档中,而不是所见即所得编辑器中的iframe文档。
解决scheme#1(仅限纯文本,需要Firefox 22+)
适用于IE6 +,FF 22+,Chrome,Safari,Edge(仅在IE9 +中testing,但应该适用于较低版本)
如果您需要粘贴HTML或Firefox <= 22的支持,请参阅解决scheme2。
HTML
<div id='editableDiv' contenteditable='true'>Paste</div>
JavaScript的
function handlePaste (e) { var clipboardData, pastedData; // Stop data actually being pasted into div e.stopPropagation(); e.preventDefault(); // Get pasted data via clipboard API clipboardData = e.clipboardData || window.clipboardData; pastedData = clipboardData.getData('Text'); // Do whatever with pasteddata alert(pastedData); } document.getElementById('editableDiv').addEventListener('paste', handlePaste);
JSFiddle: https ://jsfiddle.net/swL8ftLs/12/
请注意,此解决scheme使用参数“文本”的getData
函数,这是非标准的。 不过,它在编写本文时适用于所有浏览器。
解决scheme2(HTML和适用于Firefox <= 22)
testingIE6 +,FF 3.5 +,Chrome,Safari,Edge
HTML
<div id='div' contenteditable='true'>Paste</div>
JavaScript的
var editableDiv = document.getElementById('editableDiv'); function handlepaste (e) { var types, pastedData, savedContent; // Browsers that support the 'text/html' type in the Clipboard API (Chrome, Firefox 22+) if (e && e.clipboardData && e.clipboardData.types && e.clipboardData.getData) { // Check for 'text/html' in types list. See abligh's answer below for deatils on // why the DOMStringList bit is needed. We cannot fall back to 'text/plain' as // Safari/Edge don't advertise HTML data even if it is available types = e.clipboardData.types; if (((types instanceof DOMStringList) && types.contains("text/html")) || (types.indexOf && types.indexOf('text/html') !== -1)) { // Extract data and pass it to callback pastedData = e.clipboardData.getData('text/html'); processPaste(editableDiv, pastedData); // Stop the data from actually being pasted e.stopPropagation(); e.preventDefault(); return false; } } // Everything else: Move existing element contents to a DocumentFragment for safekeeping savedContent = document.createDocumentFragment(); while(editableDiv.childNodes.length > 0) { savedContent.appendChild(editableDiv.childNodes[0]); } // Then wait for browser to paste content into it and cleanup waitForPastedData(editableDiv, savedContent); return true; } function waitForPastedData (elem, savedContent) { // If data has been processes by browser, process it if (elem.childNodes && elem.childNodes.length > 0) { // Retrieve pasted content via innerHTML // (Alternatively loop through elem.childNodes or elem.getElementsByTagName here) var pastedData = elem.innerHTML; // Restore saved content elem.innerHTML = ""; elem.appendChild(savedContent); // Call callback processPaste(elem, pastedData); } // Else wait 20ms and try again else { setTimeout(function () { waitForPastedData(elem, savedContent) }, 20); } } function processPaste (elem, pastedData) { // Do whatever with gathered data; alert(pastedData); elem.focus(); } // Modern browsers. Note: 3rd argument is required for Firefox <= 6 if (editableDiv.addEventListener) { editableDiv.addEventListener('paste', handlepaste, false); } // IE <= 8 else { editableDiv.attachEvent('onpaste', handlepaste); }
JSFiddle: https ://jsfiddle.net/nicoburns/wrqmuabo/23/
说明
div
的onpaste
事件附加了handlePaste
函数,并传递了一个参数:paste事件的event
对象。 我们特别感兴趣的是这个事件的clipboardData
属性,它允许剪贴板在非ie浏览器中访问。 在IE中相当于window.clipboardData
,虽然这有一个略有不同的API。
参见下面的资源部分。
handlepaste
function:
这个function有两个分支。
第一个检查是否存在event.clipboardData
并检查其属性是否包含“text / html”( types
可能是使用contains
方法检查的DOMStringList
,或使用indexOf
方法检查的string)。 如果所有这些条件都满足了,那么我们按照解决scheme#1进行操作,除了使用“text / html”而不是“text / plain”。 这目前在Chrome和Firefox 22 +。
如果这个方法不被支持(所有其他的浏览器),那么我们
- 将元素的内容保存到
DocumentFragment
- 清空元素
- 调用
waitForPastedData
函数
waitforpastedata
函数:
这个函数首先轮询粘贴的数据(每20ms一次),这是必要的,因为它不会马上出现。 当数据出现时:
- 将可编辑的div(现在是粘贴的数据)的innerHTML保存到variables中
- 恢复保存在DocumentFragment中的内容
- 用检索的数据调用“processPaste”函数
processpaste
function:
用粘贴的数据做任意事情 在这种情况下,我们只是提醒数据,你可以做任何你喜欢的事情。 您可能想要通过某种数据清理过程来运行粘贴的数据。
保存和恢复光标位置
在真实的情况下,你可能想要保存之前的select,然后恢复( 在contentEditable <div>上设置光标位置 )。 然后,您可以在用户启动粘贴操作时,将粘贴的数据插入光标所在的位置。
资源:
- MDN粘贴事件: https : //developer.mozilla.org/en-US/docs/Web/Events/paste
- MSDN剪贴板: https : //msdn.microsoft.com/en-us/library/ms535220(v= vs.85).aspx
- MDN DocumentFragment: https : //developer.mozilla.org/en/docs/Web/API/DocumentFragment
- MDN DomStringList: https : //developer.mozilla.org/en/docs/Web/API/DOMStringList
感谢Tim Downbuild议使用DocumentFragment,并且在Firefox中捕获错误,因为使用了DOMStringList,而不是用于clipboardData.types的string
简单的版本: (jQuery)
$(document).on('paste','[contenteditable]',function(e) { e.preventDefault(); var text = (e.originalEvent || e).clipboardData.getData('text/plain'); window.document.execCommand('insertText', false, text); });
使用 clipboardData
演示: http : //jsbin.com/vokovividu/edit?js,output
IE边缘,火狐,铬,Safari,歌剧testing。
现场演示
在Chrome / FF / IE11上testing
有一个Chrome / IE的烦恼是这些浏览器为每一个新行添加<div>
元素。 这里有一个关于这个的post,可以通过设置contenteditable元素来display:inline-block
select一些高亮的HTML并粘贴在这里:
function onPaste(e){ var content; e.preventDefault(); if( e.clipboardData ){ content = e.clipboardData.getData('text/plain'); document.execCommand('insertText', false, content); return false; } else if( window.clipboardData ){ content = window.clipboardData.getData('Text'); if (window.getSelection) window.getSelection().getRangeAt(0).insertNode( document.createTextNode(content) ); } } /////// EVENT BINDING ///////// document.querySelector('[contenteditable]').addEventListener('paste', onPaste);
[contenteditable]{ /* chroem bug: https://stackoverflow.com/a/24689420/104380 */ display:inline-block; width: calc(100% - 40px); min-height:120px; margin:10px; padding:10px; border:1px dashed green; } /* mark HTML inside the "contenteditable" (Shouldn't be any OFC!)' */ [contenteditable] *{ background-color:red; }
<div contenteditable></div>
我已经为蒂姆·唐斯(Tim Downs)的build议写了一个关于屏幕textarea的概念certificate。 代码如下:
<html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> <script language="JavaScript"> $(document).ready(function() { var ctrlDown = false; var ctrlKey = 17, vKey = 86, cKey = 67; $(document).keydown(function(e) { if (e.keyCode == ctrlKey) ctrlDown = true; }).keyup(function(e) { if (e.keyCode == ctrlKey) ctrlDown = false; }); $(".capture-paste").keydown(function(e) { if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)){ $("#area").css("display","block"); $("#area").focus(); } }); $(".capture-paste").keyup(function(e) { if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)){ $("#area").blur(); //do your sanitation check or whatever stuff here $("#paste-output").text($("#area").val()); $("#area").val(""); $("#area").css("display","none"); } }); }); </script> </head> <body class="capture-paste"> <div id="paste-output"></div> <div> <textarea id="area" style="display: none; position: absolute; left: -99em;"></textarea> </div> </body> </html>
只需将整个代码复制并粘贴到一个html文件中,然后尝试从剪贴板上的任意位置粘贴(使用ctrl-v)文本。
我已经在IE9和Firefox,Chrome和Opera的新版本中进行了testing。 工作得很好。 也可以使用他喜欢的任何组合键来激活这个function。 当然,不要忘记包含jQuery源代码。
随意使用此代码,如果您有一些改进或问题,请将其发回。 另外请注意,我不是Javascript开发人员,所以我可能错过了一些东西(=>做你自己的testing)。
基于l2aelba anwser。 这在FF,Safari,Chrome,IE(8,9,10和11)
$("#editText").on("paste", function (e) { e.preventDefault(); var text; var clp = (e.originalEvent || e).clipboardData; if (clp === undefined || clp === null) { text = window.clipboardData.getData("text") || ""; if (text !== "") { if (window.getSelection) { var newNode = document.createElement("span"); newNode.innerHTML = text; window.getSelection().getRangeAt(0).insertNode(newNode); } else { document.selection.createRange().pasteHTML(text); } } } else { text = clp.getData('text/plain') || ""; if (text !== "") { document.execCommand('insertText', false, text); } } });
这一个不使用任何setTimeout()。
我已经使用这个伟大的文章来实现跨浏览器的支持。
$(document).on("focus", "input[type=text],textarea", function (e) { var t = e.target; if (!$(t).data("EventListenerSet")) { //get length of field before paste var keyup = function () { $(this).data("lastLength", $(this).val().length); }; $(t).data("lastLength", $(t).val().length); //catch paste event var paste = function () { $(this).data("paste", 1);//Opera 11.11+ }; //process modified data, if paste occured var func = function () { if ($(this).data("paste")) { alert(this.value.substr($(this).data("lastLength"))); $(this).data("paste", 0); this.value = this.value.substr(0, $(this).data("lastLength")); $(t).data("lastLength", $(t).val().length); } }; if (window.addEventListener) { t.addEventListener('keyup', keyup, false); t.addEventListener('paste', paste, false); t.addEventListener('input', func, false); } else {//IE t.attachEvent('onkeyup', function () { keyup.call(t); }); t.attachEvent('onpaste', function () { paste.call(t); }); t.attachEvent('onpropertychange', function () { func.call(t); }); } $(t).data("EventListenerSet", 1); } });
这个代码在paste: demo之前被扩展为select句柄
为了清除粘贴的文本并用 粘贴的文本 replace当前select的文本,事情是非常简单的:
<div id='div' contenteditable='true' onpaste='handlepaste(this, event)'>Paste</div>
JS:
function handlepaste(el, e) { document.execCommand('insertText', false, e.clipboardData.getData('text/plain')); e.preventDefault(); }
我的解决scheme是添加事件监听器来粘贴事件,如果你粘贴到文本input。 由于粘贴事件发生在input变化中的文本之前,所以在我的粘贴处理程序中,我创build了一个延迟函数,在这个函数中,我检查在粘贴时发生的input框中的变化:
onPaste: function() { var oThis = this; setTimeout(function() { // Defer until onPaste() is done console.log('paste', oThis.input.value); // Manipulate pasted input }, 1); }
这应该适用于支持onpaste事件和变异观察者的所有浏览器。
这个解决scheme仅仅是获取文本的一个步骤,它实际上允许您在粘贴内容之前编辑粘贴的内容。
它通过使用contenteditable,onpaste事件(由所有主stream浏览器支持)en突变观察者(由Chrome,Firefox和IE11 +支持)
步骤1
用contenteditable创build一个HTML元素
<div contenteditable="true" id="target_paste_element"></div>
第2步
在您的Javascript代码中添加以下事件
document.getElementById("target_paste_element").addEventListener("paste", pasteEventVerifierEditor.bind(window, pasteCallBack), false);
我们需要绑定pasteCallBack,因为突变观察者将被asynchronous调用。
步骤3
将下面的函数添加到您的代码中
function pasteEventVerifierEditor(callback, e) { //is fired on a paste event. //pastes content into another contenteditable div, mutation observer observes this, content get pasted, dom tree is copied and can be referenced through call back. //create temp div //save the caret position. savedCaret = saveSelection(document.getElementById("target_paste_element")); var tempDiv = document.createElement("div"); tempDiv.id = "id_tempDiv_paste_editor"; //tempDiv.style.display = "none"; document.body.appendChild(tempDiv); tempDiv.contentEditable = "true"; tempDiv.focus(); //we have to wait for the change to occur. //attach a mutation observer if (window['MutationObserver']) { //this is new functionality //observer is present in firefox/chrome and IE11 // select the target node // create an observer instance tempDiv.observer = new MutationObserver(pasteMutationObserver.bind(window, callback)); // configuration of the observer: var config = { attributes: false, childList: true, characterData: true, subtree: true }; // pass in the target node, as well as the observer options tempDiv.observer.observe(tempDiv, config); } } function pasteMutationObserver(callback) { document.getElementById("id_tempDiv_paste_editor").observer.disconnect(); delete document.getElementById("id_tempDiv_paste_editor").observer; if (callback) { //return the copied dom tree to the supplied callback. //copy to avoid closures. callback.apply(document.getElementById("id_tempDiv_paste_editor").cloneNode(true)); } document.body.removeChild(document.getElementById("id_tempDiv_paste_editor")); } function pasteCallBack() { //paste the content into the element. restoreSelection(document.getElementById("target_paste_element"), savedCaret); delete savedCaret; pasteHtmlAtCaret(this.innerHTML, false, true); } saveSelection = function(containerEl) { if (containerEl == document.activeElement) { var range = window.getSelection().getRangeAt(0); var preSelectionRange = range.cloneRange(); preSelectionRange.selectNodeContents(containerEl); preSelectionRange.setEnd(range.startContainer, range.startOffset); var start = preSelectionRange.toString().length; return { start: start, end: start + range.toString().length }; } }; restoreSelection = function(containerEl, savedSel) { containerEl.focus(); var charIndex = 0, range = document.createRange(); range.setStart(containerEl, 0); range.collapse(true); var nodeStack = [containerEl], node, foundStart = false, stop = false; while (!stop && (node = nodeStack.pop())) { if (node.nodeType == 3) { var nextCharIndex = charIndex + node.length; if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) { range.setStart(node, savedSel.start - charIndex); foundStart = true; } if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) { range.setEnd(node, savedSel.end - charIndex); stop = true; } charIndex = nextCharIndex; } else { var i = node.childNodes.length; while (i--) { nodeStack.push(node.childNodes[i]); } } } var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } function pasteHtmlAtCaret(html, returnInNode, selectPastedContent) { //function written by Tim Down var sel, range; if (window.getSelection) { // IE9 and non-IE sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { range = sel.getRangeAt(0); range.deleteContents(); // Range.createContextualFragment() would be useful here but is // only relatively recently standardized and is not supported in // some browsers (IE9, for one) var el = document.createElement("div"); el.innerHTML = html; var frag = document.createDocumentFragment(), node, lastNode; while ( (node = el.firstChild) ) { lastNode = frag.appendChild(node); } var firstNode = frag.firstChild; range.insertNode(frag); // Preserve the selection if (lastNode) { range = range.cloneRange(); if (returnInNode) { range.setStart(lastNode, 0); //this part is edited, set caret inside pasted node. } else { range.setStartAfter(lastNode); } if (selectPastedContent) { range.setStartBefore(firstNode); } else { range.collapse(true); } sel.removeAllRanges(); sel.addRange(range); } } } else if ( (sel = document.selection) && sel.type != "Control") { // IE < 9 var originalRange = sel.createRange(); originalRange.collapse(true); sel.createRange().pasteHTML(html); if (selectPastedContent) { range = sel.createRange(); range.setEndPoint("StartToStart", originalRange); range.select(); } }
}
代码的作用是:
- 有人用ctrl-v,contextmenu或其他方法触发粘贴事件
- 在粘贴事件中,会创build一个带有contenteditable的新元素(具有contenteditable的元素具有提升的权限)
- 目标元素的插入符号位置被保存。
- 重点是设置新元素
- 内容被粘贴到新元素中并呈现在DOM中。
- 突变观察者捕捉到了这一点(它注册了对dom树和内容的所有改变)。 然后引发突变事件。
- 粘贴的内容的dom被克隆到一个variables,并返回到callback。 临时元素被销毁。
- callback接收克隆的DOM。 脱字符被恢复。 您可以在将其附加到目标之前进行编辑。 元件。 在这个例子中,我使用Tim Downs函数来保存/恢复插入符号并将HTML粘贴到元素中。
非常感谢蒂姆下来看到这个post的答案:
在粘贴事件的文件上获取粘贴的内容
对于Nico的回答,这个时间太长了,我不认为Firefox的工作原理(根据评论),并且在Safari上并不适合我。
首先,您现在似乎可以直接从剪贴板中读取。 而不是像下面的代码:
if (/text\/plain/.test(e.clipboardData.types)) { // shouldn't this be writing to elem.value for text/plain anyway? elem.innerHTML = e.clipboardData.getData('text/plain'); }
使用:
types = e.clipboardData.types; if (((types instanceof DOMStringList) && types.contains("text/plain")) || (/text\/plain/.test(types))) { // shouldn't this be writing to elem.value for text/plain anyway? elem.innerHTML = e.clipboardData.getData('text/plain'); }
因为Firefox有一个types
字段,它是一个没有实现test
的DOMStringList
。
接下来的Firefox将不允许粘贴,除非焦点在contenteditable=true
字段中。
最后,Firefox将不允许可靠地粘贴,除非焦点在textarea
(或者可能是input),而不仅仅是contenteditable=true
而且还包括:
- 不
display:none
- 不
visibility:hidden
- 不是零大小
我试图隐藏文本字段,所以我可以做一个JS VNC模拟器粘贴工作(即它是去远程客户端,并没有真正的textarea
等粘贴)。 我发现试图隐藏上面的文本字段给出了有时它工作的症状,但是通常在第二次粘贴时(或者当字段被清除以防止粘贴相同的数据两次时)失败,因为字段失去焦点并且不能正确地重新获得尽pipefocus()
。 我提出的解决scheme是把它放在z-order: -1000
,使其display:none
,使其为1px的1px,并将所有的颜色设置为透明。 呸。
在Safari上,你的第二部分适用,即你需要有一个不display:none
的textarea
display:none
。
首先想到的是谷歌封闭库的pastehandler http://closure-library.googlecode.com/svn/trunk/closure/goog/demos/pastehandler.html
这对我工作:
function onPasteMe(currentData, maxLen) { // validate max length of pasted text var totalCharacterCount = window.clipboardData.getData('Text').length; } <input type="text" onPaste="return onPasteMe(this, 50);" />
这个解决scheme是取代html标签,它很简单,跨浏览器; 检查这个jsfiddle: http : //jsfiddle.net/tomwan/cbp1u2cx/1/ ,核心代码:
var $plainText = $("#plainText"); var $linkOnly = $("#linkOnly"); var $html = $("#html"); $plainText.on('paste', function (e) { window.setTimeout(function () { $plainText.html(removeAllTags(replaceStyleAttr($plainText.html()))); }, 0); }); $linkOnly.on('paste', function (e) { window.setTimeout(function () { $linkOnly.html(removeTagsExcludeA(replaceStyleAttr($linkOnly.html()))); }, 0); }); function replaceStyleAttr (str) { return str.replace(/(<[\w\W]*?)(style)([\w\W]*?>)/g, function (a, b, c, d) { return b + 'style_replace' + d; }); } function removeTagsExcludeA (str) { return str.replace(/<\/?((?!a)(\w+))\s*[\w\W]*?>/g, ''); } function removeAllTags (str) { return str.replace(/<\/?(\w+)\s*[\w\W]*?>/g, ''); }
注意:你应该在背面做一些关于xssfilter的工作,因为这个解决scheme不能过滤像“<< >>”
你可以这样做:
使用这个jQuery插件来粘贴事件前后:
$.fn.pasteEvents = function( delay ) { if (delay == undefined) delay = 20; return $(this).each(function() { var $el = $(this); $el.on("paste", function() { $el.trigger("prepaste"); setTimeout(function() { $el.trigger("postpaste"); }, delay); }); }); };
现在你可以使用这个插件了:
$('#txt').on("prepaste", function() { $(this).find("*").each(function(){ var tmp=new Date.getTime(); $(this).data("uid",tmp); }); }).pasteEvents(); $('#txt').on("postpaste", function() { $(this).find("*").each(function(){ if(!$(this).data("uid")){ $(this).removeClass(); $(this).removeAttr("style id"); } }); }).pasteEvents();
释
首先为所有现有元素设置一个uid作为数据属性。
然后比较所有节点POST PASTE事件。 所以通过比较你可以识别新插入的元素,因为他们会有一个uid,那么只需从新创build的元素中删除style / class / id属性,这样就可以保留旧的格式。
$('#dom').on('paste',function (e){ setTimeout(function(){ console.log(e.currentTarget.value); },0); });
只要让浏览器像往常一样在其内容可编辑div中粘贴,然后将用于自定义文本样式的任何span元素与文本自身进行粘贴。 这似乎在Internet Explorer和我试过的其他浏览器工作正常…
$('[contenteditable]').on('paste', function (e) { setTimeout(function () { $(e.target).children('span').each(function () { $(this).replaceWith($(this).text()); }); }, 0); });
这个解决scheme假定你正在运行jQuery ,并且你不想在你的任何内容可编辑的div中进行文本格式化 。
好的一面是它非常简单。
function myFunct( e ){ e.preventDefault(); var pastedText = undefined; if( window.clipboardData && window.clipboardData.getData ){ pastedText = window.clipboardData.getData('Text'); } else if( e.clipboardData && e.clipboardData.getData ){ pastedText = e.clipboardData.getData('text/plain'); } //work with text } document.onpaste = myFunct;
This is an existing code posted above but I have updated it for IE's, the bug was when the existing text is selected and pasted will not delete the selected content. This has been fixed by the below code
selRange.deleteContents();
See complete code below
$('[contenteditable]').on('paste', function (e) { e.preventDefault(); if (window.clipboardData) { content = window.clipboardData.getData('Text'); if (window.getSelection) { var selObj = window.getSelection(); var selRange = selObj.getRangeAt(0); selRange.deleteContents(); selRange.insertNode(document.createTextNode(content)); } } else if (e.originalEvent.clipboardData) { content = (e.originalEvent || e).clipboardData.getData('text/plain'); document.execCommand('insertText', false, content); } });