Javascript命令在execCommand中作为纯文本粘贴

我有一个基于execCommand的基本编辑器,下面介绍这个示例。 有三种方法在execCommand区域内粘贴文本:

  • Ctrl + V
  • 右键点击 – >粘贴
  • 右键单击 – >粘贴为纯文本

我想只允许粘贴纯文本而不使用任何HTML标记。 我如何强制前两个动作粘贴纯文本?

可能的解决scheme:我能想到的方式是设置(Ctrl + V)的键盘事件监听器,并粘贴HTML标签。

  1. 这是最好的解决scheme吗?
  2. 是否防止粘贴任何HTML makup?
  3. 如何添加侦听器右键单击 – >粘贴?

拦截paste事件,取消粘贴,并手动插入剪贴板的文本表示forms: http : //jsfiddle.net/HBEzc/ 。 这应该是最可靠的:

  • 它捕捉各种粘贴(Ctrl + V,上下文菜单等)
  • 它允许您直接以文本方式获取剪贴板数据,所以您不必做丑陋的黑客来取代HTML

不过,我不确定是否支持跨浏览器。

 editor.addEventListener("paste", function(e) { // cancel paste e.preventDefault(); // get text representation of clipboard var text = e.clipboardData.getData("text/plain"); // insert text manually document.execCommand("insertHTML", false, text); }); 

当然,这个问题已经回答了,话题很老,但我想提供我的解决scheme,因为它很简单:

这是在我的contenteditable-div的粘贴事件里面。

 var text = ''; var that = $(this); if (e.clipboardData) text = e.clipboardData.getData('text/plain'); else if (window.clipboardData) text = window.clipboardData.getData('Text'); else if (e.originalEvent.clipboardData) text = $('<div></div>').text(e.originalEvent.clipboardData.getData('text')); if (document.queryCommandSupported('insertText')) { document.execCommand('insertHTML', false, $(text).html()); return false; } else { // IE > 7 that.find('*').each(function () { $(this).addClass('within'); }); setTimeout(function () { // nochmal alle durchlaufen that.find('*').each(function () { // wenn das element keine klasse 'within' hat, dann unwrap // http://api.jquery.com/unwrap/ $(this).not('.within').contents().unwrap(); }); }, 1); } 

其他的部分是从另一个SO的职位,我找不到了…


更新19.11.2014: 另一个SO-post

作为pimvdb的解决scheme。 但它的工作FF,Chrome和IE 9:

 editor.addEventListener("paste", function(e) { e.preventDefault(); if (e.clipboardData) { content = (e.originalEvent || e).clipboardData.getData('text/plain'); document.execCommand('insertText', false, content); } else if (window.clipboardData) { content = window.clipboardData.getData('Text'); document.selection.createRange().pasteHTML(content); } }); 

我不能在这里接受的答案在IE浏览器工作,所以我做了一些探索,来到这个答案在IE11和最新版本的Chrome和Firefox的作​​品。

 $('[contenteditable]').on('paste', function(e) { e.preventDefault(); var text = ''; if (e.clipboardData || e.originalEvent.clipboardData) { text = (e.originalEvent || e).clipboardData.getData('text/plain'); } else if (window.clipboardData) { text = window.clipboardData.getData('Text'); } if (document.queryCommandSupported('insertText')) { document.execCommand('insertText', false, text); } else { document.execCommand('paste', false, text); } }); 

Firefox不允许你访问剪贴板数据,所以你需要做一个“黑客”才能使其工作。 我一直没能find一个完整的解决scheme,但是你可以通过创build一个textarea和粘贴到ctrl + v贴来修复它:

 //Test if browser has the clipboard object if (!window.Clipboard) { /*Create a text area element to hold your pasted text Textarea is a good choice as it will make anything added to it in to plain text*/ var paster = document.createElement("textarea"); //Hide the textarea paster.style.display = "none"; document.body.appendChild(paster); //Add a new keydown event tou your editor editor.addEventListener("keydown", function(e){ function handlePaste() { //Get the text from the textarea var pastedText = paster.value; //Move the cursor back to the editor editor.focus(); //Check that there is a value. FF throws an error for insertHTML with an empty string if (pastedText !== "") document.execCommand("insertHTML", false, pastedText); //Reset the textarea paster.value = ""; } if (e.which === 86 && e.ctrlKey) { //ctrl+v => paste //Set the focus on your textarea paster.focus(); //We need to wait a bit, otherwise FF will still try to paste in the editor => settimeout window.setTimeout(handlePaste, 1); } }, false); } else //Pretty much the answer given by pimvdb above { //Add listener for paster to force paste-as-plain-text editor.addEventListener("paste", function(e){ //Get the plain text from the clipboard var plain = (!!e.clipboardData)? e.clipboardData.getData("text/plain") : window.clipboardData.getData("Text"); //Stop default paste action e.preventDefault(); //Paste plain text document.execCommand("insertHTML", false, plain); }, false); } 

我也在做一个纯文本粘贴,我开始讨厌所有的execCommand和getData错误,所以我决定用经典的方式来做,它的function就像一个魅力:

 $('#editor').bind('paste', function(){ var before = document.getElementById('editor').innerHTML; setTimeout(function(){ var after = document.getElementById('editor').innerHTML; var pos1 = -1; var pos2 = -1; for (var i=0; i<after.length; i++) { if (pos1 == -1 && before.substr(i, 1) != after.substr(i, 1)) pos1 = i; if (pos2 == -1 && before.substr(before.length-i-1, 1) != after.substr(after.length-i-1, 1)) pos2 = i; } var pasted = after.substr(pos1, after.length-pos2-pos1); var replace = pasted.replace(/<[^>]+>/g, ''); var replaced = after.substr(0, pos1)+replace+after.substr(pos1+pasted.length); document.getElementById('editor').innerHTML = replaced; }, 100); }); 

我的符号代码可以在这里find: http : //www.albertmartin.de/blog/code.php/20/plain-text-paste-with-javascript

 function PasteString() { var editor = document.getElementById("TemplateSubPage"); editor.focus(); // editor.select(); document.execCommand('Paste'); } function CopyString() { var input = document.getElementById("TemplateSubPage"); input.focus(); // input.select(); document.execCommand('Copy'); if (document.selection || document.textSelection) { document.selection.empty(); } else if (window.getSelection) { window.getSelection().removeAllRanges(); } } 

以上代码适用于IE10和IE11,现在也适用于Chrome和Safari。 未在Firefox中testing。

在IE11中,execCommand不能正常工作。 我使用IE11以下代码<div class="wmd-input" id="wmd-input-md" contenteditable=true>是我的div盒子。

我从window.clipboardData中读取剪贴板数据,并修改div的textContent并给出脱字符号。

我给超时设置插入符号,因为如果我没有设置超时,脱字符到div的结尾。

你应该用下面的方式阅读IE11中的clipboardData。 如果你不这样做,换行符处理不当,所以脱字符出错。

 var tempDiv = document.createElement("div"); tempDiv.textContent = window.clipboardData.getData("text"); var text = tempDiv.textContent; 

testingIE11和铬。 它可能无法在IE9上工作

 document.getElementById("wmd-input-md").addEventListener("paste", function (e) { if (!e.clipboardData) { //For IE11 e.preventDefault(); e.stopPropagation(); var tempDiv = document.createElement("div"); tempDiv.textContent = window.clipboardData.getData("text"); var text = tempDiv.textContent; var selection = document.getSelection(); var start = selection.anchorOffset > selection.focusOffset ? selection.focusOffset : selection.anchorOffset; var end = selection.anchorOffset > selection.focusOffset ? selection.anchorOffset : selection.focusOffset; selection.removeAllRanges(); setTimeout(function () { $(".wmd-input").text($(".wmd-input").text().substring(0, start) + text + $(".wmd-input").text().substring(end)); var range = document.createRange(); range.setStart(document.getElementsByClassName("wmd-input")[0].firstChild, start + text.length); range.setEnd(document.getElementsByClassName("wmd-input")[0].firstChild, start + text.length); selection.addRange(range); }, 1); } else { //For Chrome e.preventDefault(); var text = e.clipboardData.getData("text"); var selection = document.getSelection(); var start = selection.anchorOffset > selection.focusOffset ? selection.focusOffset : selection.anchorOffset; var end = selection.anchorOffset > selection.focusOffset ? selection.anchorOffset : selection.focusOffset; $(this).text($(this).text().substring(0, start) + text + $(this).text().substring(end)); var range = document.createRange(); range.setStart($(this)[0].firstChild, start + text.length); range.setEnd($(this)[0].firstChild, start + text.length); selection.removeAllRanges(); selection.addRange(range); } }, false); 
Interesting Posts