据我所知,自从Firefox 13版本以来JavaScript无法访问剪贴板,并且其中不存在
event.clipboard
。我知道这是可以实现的,因为即使在Firefox中,Gmail和Yahoo也可以允许用户这样操作。我只想让它以任何方式都能正常工作,使用jQuery、JavaScript、HTML5都可以,只要它能在最新的Firefox中工作就行(不使用Flash)。
event.clipboard
。我知道这是可以实现的,因为即使在Firefox中,Gmail和Yahoo也可以允许用户这样操作。我使用了这个问题中的代码来实现跨浏览器粘贴功能。它在我测试过的所有浏览器中都可以运行(请向下滚动查看实际解决方案/代码)。需要注意的是,在粘贴事件完成执行后,event.clipboardData
会立即过期。
我已经四重检查过,在Firefox 19版本中也可以正常工作(我没有13版本可用,但似乎这个问题是关于新版本中某个功能退化的)。
在IE6+、FF 3.5+、近期版本的Opera、Chrome和Safari中测试通过。
function handlepaste (elem, e) {
var savedcontent = elem.innerHTML;
if (e && e.clipboardData && e.clipboardData.getData) {// Webkit - get data from clipboard, put into editdiv, cleanup, then cancel event
if (/text\/html/.test(e.clipboardData.types)) {
elem.innerHTML = e.clipboardData.getData('text/html');
}
else if (/text\/plain/.test(e.clipboardData.types)) {
elem.innerHTML = e.clipboardData.getData('text/plain');
}
else {
elem.innerHTML = "";
}
waitforpastedata(elem, savedcontent);
if (e.preventDefault) {
e.stopPropagation();
e.preventDefault();
}
return false;
}
else {// Everything else - empty editdiv and allow browser to paste content into it, then cleanup
elem.innerHTML = "";
waitforpastedata(elem, savedcontent);
return true;
}
}
function waitforpastedata (elem, savedcontent) {
if (elem.childNodes && elem.childNodes.length > 0) {
processpaste(elem, savedcontent);
}
else {
that = {
e: elem,
s: savedcontent
}
that.callself = function () {
waitforpastedata(that.e, that.s)
}
setTimeout(that.callself,20);
}
}
function processpaste (elem, savedcontent) {
pasteddata = elem.innerHTML;
//^^Alternatively loop through dom (elem.childNodes or elem.getElementsByTagName) here
elem.innerHTML = savedcontent;
// Do whatever with gathered data;
alert(pasteddata);
}
<div id='div' contenteditable='true' onpaste='handlepaste(this, event)'>Paste</div>
在onpaste
事件中,将handlepaste
函数附加到它上面,并传递两个参数:this
(即对事件所附加的元素的引用)和event
,它是事件对象。
handlepaste
函数:
第一行只是把可编辑div的内容保存到一个变量中,以便在最后恢复。
if
检查浏览器是否为WebKit浏览器(Chrome或Safari),如果是,则将可编辑div的内容设置为正在粘贴的数据。然后取消事件,以防止WebKit粘贴两次。这是因为WebKit很棘手,如果您仅清除div,则不会粘贴任何内容。
如果不是WebKit浏览器,则只需清除可编辑div。
然后调用waitforpastedata
函数。
waitforpastedata
函数:
这是必要的,因为粘贴的数据不会立即出现,因此如果您立即调用processpaste
,则它将没有任何要处理的数据。
它所做的是检查可编辑div是否有任何内容,如果有,则调用processpaste
,否则它将设置一个计时器,以便在20毫秒后再次调用自身并重新检查。
processpaste
函数:
此函数将可编辑div的innerHTML(现在是粘贴的数据)保存到变量中,将可编辑div的innerHTML恢复为其原始值,然后警告粘贴的数据。显然,在实际使用场景中,您可能希望除了警告数据之外做一些其他事情,您可以从这里开始做任何您想做的事情。
您可能还希望通过某种数据消毒过程运行已粘贴的数据。这可以在可编辑div中或提取的字符串中进行。
在实际情况下,您可能想在保存选择之前和之后进行恢复(在contentEditable <div>上设置光标位置)。然后,可以将粘贴的数据插入用户启动粘贴操作时光标所在的位置。
P.S. 这段代码、IE <= 8和jsfiddle的组合似乎不起作用,但在非jsfiddle环境中的ie <= 8中有效。
input
事件替代了Timeout
,应用在div上。 - Tomáš Zato