web应用程序如何检测粘贴事件并检索要粘贴的数据?
我想在文本粘贴到富文本编辑器之前删除HTML内容。
在粘贴后清理文本是有效的,但问题是所有以前的格式都会丢失。例如,我可以在编辑器中编写一个句子并将其加粗,但当我粘贴新文本时,所有格式都会丢失。我只想清除粘贴的文本,并保留以前的任何格式不变。
理想情况下,解决方案应该可以跨所有现代浏览器(例如,MSIE、Gecko、Chrome和Safari)工作。
注意,MSIE有clipboardData.getData(),但我找不到其他浏览器的类似功能。
你可以这样做:
使用这个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设置为data属性。
然后比较所有节点的POST PASTE事件。因此,通过比较,您可以识别新插入的元素,因为它们将有uid,然后只需从新创建的元素中删除style/class/id属性,以便您可以保留旧的格式。
简单的版本:
document.querySelector('[contenteditable]').addEventListener('paste', (e) => {
e.preventDefault();
const text = (e.originalEvent || e).clipboardData.getData('text/plain');
window.document.execCommand('insertText', false, text);
});
使用clipboardData
演示:http://jsbin.com/nozifexasu/edit?js,output
Edge, Firefox, Chrome, Safari, Opera测试。
机场当局:Document.execCommand()现已废弃。
注意:记住在服务器端也检查输入/输出(如PHP条带标签)
我写了一个小的概念证明蒂姆唐斯提议这里与屏幕文本区域。下面是代码:
<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开发人员,所以我可能错过了一些东西(=>做你自己的测试)。
这是上面发布的一个现有代码,但我已经为IE更新了它,错误是当现有的文本被选择和粘贴时,不会删除所选的内容。下面的代码已经修复了这个问题
selRange.deleteContents();
参见下面的完整代码
$('[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);
}
});
写完这篇文章后,情况发生了变化:现在Firefox在版本22中添加了支持,所有主流浏览器现在都支持在粘贴事件中访问剪贴板数据。请看Nico Burns的回答。
在过去,这在跨浏览器的方式中通常是不可能的。最理想的情况是能够通过paste事件获取粘贴的内容,这在最近的浏览器中是可能的,但在一些较老的浏览器中是不可能的(特别是Firefox < 22)。
当你需要支持旧的浏览器时,你可以做的是相当复杂的和一点hack,可以在Firefox 2+, IE 5.5+和WebKit浏览器(如Safari或Chrome)中工作。TinyMCE和CKEditor的最新版本都使用了这种技术:
Detect a ctrl-v / shift-ins event using a keypress event handler
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
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.
请注意,这将只适用于键盘粘贴事件,而不是粘贴上下文或编辑菜单。当粘贴事件触发时,将插入符号重定向到文本区域就太晚了(至少在某些浏览器中是这样)。
在不太可能的情况下,您需要支持Firefox 2,请注意您需要将文本区域放置在父文档中,而不是在该浏览器中的所见即所得编辑器iframe的文档中。