2013-03-06 112 views
16

我试图让用户将图像粘贴到div。问题是我需要它在Firefox中工作。从剪贴板获取粘贴图像Firefox

从我读过的内容来看,自从版本13(我认为)以来,Firefox不允许JavaScript访问剪贴板,并且其中不存在event.clipboard。我知道可以这样做,因为Gmail和Yahoo甚至可以在Firefox中使用它。

我只是希望它在任何可能的情况下工作,使用jQuery,JavaScript,HTML5,只要它在最新的Firefox中工作并不重要。 (尽管没有Flash)。

+0

[剪贴板功能中的粘贴图像如何在Gmail和Google Chrome 12+中工作?](http://stackoverflow.com/questions/6333814/how-does-the-paste-image-from- clipboard-functional-work-in-gmail-and-google-c) – epascarello 2013-03-06 17:32:22

+6

@epascarello这不是真的重复,因为我尝试过,它在firefox中不起作用,正如我在post中所说的event.clipboard不存在在Firefox中,但无论如何谢谢 – trebor 2013-03-06 19:20:46

+2

我创建了一个简单的统一界面试图在不同的浏览器下做到这一点,也许你应该尝试https://github.com/Puffant/paste.js – 2014-02-10 10:02:08

回答

14

我使用this question代码为我的跨浏览器粘贴实现..它工作在我测试了所有的浏览器(向下滚动的实际解决方案/代码)。应该注意,在粘贴事件完成执行后,event.clipboardData会立即到期。

我继续前进,四重检查了它在Firefox 19中的工作情况(我没有13可用,但听起来像这个问题是关于新版本功能的降级)。

下面就是答案,从Nico Burns报价:

解决方案

在IE6 +,FF 3.5+测试,歌剧,铬,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或提取的字符串中时完成。


在你可能会想之前保存的选择,事后恢复它(Set cursor position on contentEditable <div>)真正sitution。然后,您可以在用户启动粘贴操作时将粘贴的数据插入光标所在的位置。

P.S.此代码的组合,IE < = 8和jsfiddle似乎不起作用,但它在if-< = 8中工作,在非jsfiddle环境中。

+0

它的工作,你是一个生活救星非常感谢你和抱歉,因此将其标记为正确答案 – trebor 2013-03-11 13:10:04

+0

嗨,我想更改此代码的剪贴板图像我可以吗? – altandogan 2013-04-18 06:57:25

+0

@ user990513上面的代码已经将客户端剪贴板图像保存到变量中。请进一步澄清,如果我误解了你的问题 – 2013-04-18 22:56:18