web应用程序如何检测粘贴事件并检索要粘贴的数据?
我想在文本粘贴到富文本编辑器之前删除HTML内容。
在粘贴后清理文本是有效的,但问题是所有以前的格式都会丢失。例如,我可以在编辑器中编写一个句子并将其加粗,但当我粘贴新文本时,所有格式都会丢失。我只想清除粘贴的文本,并保留以前的任何格式不变。
理想情况下,解决方案应该可以跨所有现代浏览器(例如,MSIE、Gecko、Chrome和Safari)工作。
注意,MSIE有clipboardData.getData(),但我找不到其他浏览器的类似功能。
为了在IE11和Chrome上都支持纯文本的复制和粘贴,我使用了以下函数。
它有两个if语句来区分IE和chome,并执行适当的代码。在第一部分中,代码从剪贴板中读取文本,在第二部分中,它将文本粘贴到光标位置,替换当前所选文本。
特别是,对于IE上的粘贴,代码获取选择范围,删除所选文本,将文本从剪贴板插入到一个新的html文本节点中,重新配置范围以在光标位置加上文本长度处插入文本节点。
代码如下:
editable.addEventListener("paste", function(e) {
e.preventDefault();
// Get text from the clipboard.
var text = '';
if (e.clipboardData || (e.originalEvent && e.originalEvent.clipboardData)) {
text = (e.originalEvent || e).clipboardData.getData('text/plain');
} else if (window.clipboardData) {
text = window.clipboardData.getData('Text');
}
// bool to indicate if the user agent is internet explorer
let isIE = /Trident/.test(navigator.userAgent);
if (document.queryCommandSupported('insertText') && !isIE) {
// Chrome etc.
document.execCommand('insertText', false, text);
} else {
// IE.
// delete content from selection.
var sel = window.getSelection();
var range = sel.getRangeAt(0);
document.execCommand("delete");
// paste plain text in a new node.
var newNode = document.createTextNode(text);
range.insertNode(newNode);
range.setStart(newNode, 0)
range.setEnd(newNode, newNode.childNodes.length);
sel.removeAllRanges;
sel.addRange(range);
}
}, false);
特别是为了在IE上粘贴许多答案的文本,我找到了这个说明文档。execCommand('paste', false, text);这在IE11上不起作用,因为浏览器会一次又一次地调用粘贴事件。我用range对象上的函数替换了它。
另一个问题是,在IE11上,根据版本,函数文档。execCommand('insertText', false, text);有时可用,有时不可用,所以我显式检查浏览器是否是IE,并为它执行基于范围选择的部分代码(参见其他)。
当用户通过浏览器的用户界面发起“粘贴”操作时,粘贴事件将被触发。
HTML
<div class="source" contenteditable="true">Try copying text from this box...</div>
<div class="target" contenteditable="true">...and pasting it into this one</div>
JavaScript
const target = document.querySelector('div.target');
target.addEventListener('paste', (event) => {
let paste = (event.clipboardData || window.clipboardData).getData('text');
paste = paste.toUpperCase();
const selection = window.getSelection();
if (!selection.rangeCount) return false;
selection.deleteFromDocument();
selection.getRangeAt(0).insertNode(document.createTextNode(paste));
event.preventDefault();
});
知道更多
我写了一个小的概念证明蒂姆唐斯提议这里与屏幕文本区域。下面是代码:
<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中测试了它。工作得很好。另外,用户可以使用任何他喜欢的组合键来触发这个功能。当然,不要忘记包含jQuery源代码。
请随意使用此代码,如果您有一些改进或问题,请将它们发布回来。还要注意,我不是Javascript开发人员,所以我可能错过了一些东西(=>做你自己的测试)。