根据execCommand
下面介绍的示例,我有一个基本的编辑器。有三种方法可以在execCommand
区域内粘贴文本:
- Ctrl+V
- 右键单击->粘贴
- 右键单击->作为纯文本粘贴
我想只粘贴没有任何HTML标记的纯文本。如何强制前两个动作粘贴纯文本?
可能的解决方案:我能想到的方法是为(Ctrl+ V)的keyup事件设置侦听器,并在粘贴之前剥离HTML标记。
- 这是最好的解决方案吗?
- 避免粘贴任何HTML标记是否安全?
- 如何将侦听器添加到右键单击->粘贴?
根据execCommand
下面介绍的示例,我有一个基本的编辑器。有三种方法可以在execCommand
区域内粘贴文本:
我想只粘贴没有任何HTML标记的纯文本。如何强制前两个动作粘贴纯文本?
可能的解决方案:我能想到的方法是为(Ctrl+ V)的keyup事件设置侦听器,并在粘贴之前剥离HTML标记。
Answers:
它将拦截该paste
事件,取消paste
,并手动插入剪贴板的文本表示形式:
http : //jsfiddle.net/HBEzc/。这应该是最可靠的:
不过,我不确定是否支持跨浏览器。
editor.addEventListener("paste", function(e) {
// cancel paste
e.preventDefault();
// get text representation of clipboard
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
// insert text manually
document.execCommand("insertHTML", false, text);
});
text
包含HTML(例如,如果您将HTML代码复制为纯文本),则它将实际将其粘贴为HTML。这是一个解决方案,但不是很漂亮:jsfiddle.net/HBEzc/3。
var text = (event.originalEvent || event).clipboardData.getData('text/plain');
提供了更多的跨浏览器兼容性
<div></div>
内容,则将内容添加为contenteditable元素的子元素。我是这样修复的:document.execCommand("insertText", false, text);
insertHTML
并且insertText
不能在IE11中工作,但是document.execCommand('paste', false, text);
可以正常工作。尽管那似乎在其他浏览器> _>中似乎不起作用。
我在这里无法获得在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);
}
});
类似于pimvdb的解决方案。但它适用于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);
}
});
content
变量分配。我发现使用getData('Text')
跨浏览器的作品,因此您可以像这样进行一次分配:var content = ((e.originalEvent || e).clipboardData || window.clipboardData).getData('Text');
然后,只需要对跨浏览器的粘贴/插入命令使用逻辑。
document.selection.createRange().pasteHTML(content)
...只是在IE11上进行了测试,因此无法正常工作。
document.execCommand('insertText', false, content)
从IE11和Edge开始不起作用。另外,最新版本的Chrome现在支持document.execCommand('paste', false, content)
,这更加简单。他们可能会过时insertText
。
当然,这个问题已经回答了,主题很老,但是我想提供解决方案,因为它很干净:
这是在我的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);
}
else部分来自另一个我找不到的SO-post ...
所有发布的答案似乎都无法跨浏览器正常工作,或者解决方案过于复杂:
insertText
IE不支持该命令paste
命令会导致IE11中的堆栈溢出错误适用于我(IE11,Edge,Chrome和FF)的内容如下:
$("div[contenteditable=true]").off('paste').on('paste', function(e) {
e.preventDefault();
var text = e.originalEvent.clipboardData ? e.originalEvent.clipboardData.getData('text/plain') : window.clipboardData.getData('Text');
_insertText(text);
});
function _insertText(text) {
// use insertText command if supported
if (document.queryCommandSupported('insertText')) {
document.execCommand('insertText', false, text);
}
// or insert the text content at the caret's current position
// replacing eventually selected content
else {
var range = document.getSelection().getRangeAt(0);
range.deleteContents();
var textNode = document.createTextNode(text);
range.insertNode(textNode);
range.selectNodeContents(textNode);
range.collapse(false);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<textarea name="t1"></textarea>
<div style="border: 1px solid;" contenteditable="true">Edit me!</div>
<input />
</body>
注意,自定义粘贴处理程序仅对于contenteditable
节点是必需的/起作用。由于textarea
普通input
字段都不支持粘贴HTML内容,因此此处无需执行任何操作。
.originalEvent
事件处理程序(第3行)的约束才能使其正常工作。因此完整行如下所示:const text = ev.clipboardData ? ev.clipboardData.getData('text/plain') : window.clipboardData.getData('Text');
。适用于最新的Chrome,Safari,Firefox。
Firefox不允许您访问剪贴板数据,因此您需要进行“黑客攻击”才能使其正常工作。我无法找到完整的解决方案,但是您可以通过创建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错误,因此我决定以经典方式进行操作,它的工作原理就像一个魅力:
$('#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);
});
带有我符号的代码可以在这里找到: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中测试。
在IE11中,execCommand不能正常运行。我使用下面的IE11代码
<div class="wmd-input" id="wmd-input-md" contenteditable=true>
是我的div框。
我从window.clipboardData中读取剪贴板数据,并修改div的textContent并给出插入符号。
我给出设置插入符号的超时时间,因为如果不设置超时,则插入符号将进入div的结尾。
并且您应该通过以下方式在IE11中阅读剪贴板数据。如果不这样做,换行符将无法正确处理,因此插入符号会出错。
var tempDiv = document.createElement("div");
tempDiv.textContent = window.clipboardData.getData("text");
var text = tempDiv.textContent;
在IE11和chrome上测试。在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);
经过搜索和尝试,我找到了某种最佳解决方案
要记住什么是重要的
// /\x0D/g return key ASCII
window.document.execCommand('insertHTML', false, text.replace('/\x0D/g', "\\n"))
and give the css style white-space: pre-line //for displaying
var contenteditable = document.querySelector('[contenteditable]')
contenteditable.addEventListener('paste', function(e){
let text = ''
contenteditable.classList.remove('empty')
e.preventDefault()
text = (e.originalEvent || e).clipboardData.getData('text/plain')
e.clipboardData.setData('text/plain', '')
window.document.execCommand('insertHTML', false, text.replace('/\x0D/g', "\\n"))// /\x0D/g return ASCII
})
#input{
width: 100%;
height: 100px;
border: 1px solid black;
white-space: pre-line;
}
<div id="input"contenteditable="true">
<p>
</p>
</div>
确定,因为每个人都在尝试处理剪贴板数据,检查按键事件并使用execCommand。
我想到了
码
handlePastEvent=()=>{
document.querySelector("#new-task-content-1").addEventListener("paste",function(e)
{
setTimeout(function(){
document.querySelector("#new-task-content-1").innerHTML=document.querySelector("#new-task-content-1").innerText.trim();
},1);
});
}
handlePastEvent();
<div contenteditable="true" id="new-task-content-1">You cann't paste HTML here</div>