web应用程序如何检测粘贴事件并检索要粘贴的数据?
我想在文本粘贴到富文本编辑器之前删除HTML内容。
在粘贴后清理文本是有效的,但问题是所有以前的格式都会丢失。例如,我可以在编辑器中编写一个句子并将其加粗,但当我粘贴新文本时,所有格式都会丢失。我只想清除粘贴的文本,并保留以前的任何格式不变。
理想情况下,解决方案应该可以跨所有现代浏览器(例如,MSIE、Gecko、Chrome和Safari)工作。
注意,MSIE有clipboardData.getData(),但我找不到其他浏览器的类似功能。
这个解决方案是替换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, '');
}
注意:你应该在后面做一些关于XSS过滤器的工作,因为这个解决方案不能过滤像'<<>>'这样的字符串
这是上面发布的一个现有代码,但我已经为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);
}
});
现场演示
在Chrome / FF / IE11上测试
有一个Chrome/IE的烦恼是这些浏览器为每一行添加<div>元素。这里有一篇关于这个的文章,它可以通过设置contentteditable元素为display:inline-block来修复
选择一些突出显示的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>
我写了一个小的概念证明蒂姆唐斯提议这里与屏幕文本区域。下面是代码:
<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开发人员,所以我可能错过了一些东西(=>做你自己的测试)。