本文介绍了从剪贴板 Firefox 获取粘贴的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试允许用户将图像粘贴到 div 中.问题是我需要它在 Firefox 中工作.

据我所知,Firefox 自 13 版(我认为)不允许 JavaScript 访问剪贴板,并且其中不存在 event.clipboard.我知道这是可以做到的,因为 Gmail 和 Yahoo 即使在 Firefox 中也允许这样做.

我只是想让它以任何可能的方式工作,使用 jQuery、JavaScript、HTML5,只要它在最新的 Firefox 中工作都没有关系.(虽然没有 Flash).

解决方案

我使用了 这个问题 用于我的跨浏览器粘贴实现......它适用于我测试过的所有浏览器(向下滚动以获得实际的解决方案/代码).需要注意的是,event.clipboardData 在粘贴事件执行完成后立即过期.

我继续进行了四重检查,这在 Firefox 19 版中确实有效(我没有 13 版,但听起来这个问题是关于新版本中某个功能的降级).

下面是答案,引用自Nico Burns:

解决方案

在 IE6+、FF 3.5+、Opera、Chrome、Safari 的最新版本中测试.

function handlepaste (elem, e) {var savedcontent = elem.innerHTML;if (e && e.clipboardData && e.clipboardData.getData) {//Webkit - 从剪贴板获取数据,放入editdiv,清理,然后取消事件如果 (/text/html/.test(e.clipboardData.types)) {elem.innerHTML = e.clipboardData.getData('text/html');}否则 if (/text/plain/.test(e.clipboardData.types)) {elem.innerHTML = e.clipboardData.getData('text/plain');}别的 {elem.innerHTML = "";}等待粘贴数据(元素,已保存的内容);如果(e.preventDefault){e.stopPropagation();e.preventDefault();}返回假;}else {//其他所有内容 - 清空 editdiv 并允许浏览器将内容粘贴到其中,然后进行清理elem.innerHTML = "";等待粘贴数据(元素,已保存的内容);返回真;}}功能等待粘贴数据(元素,已保存的内容){如果 (elem.childNodes && elem.childNodes.length > 0) {处理粘贴(元素,已保存的内容);}别的 {那 = {e: 元素,s:保存的内容}that.callself = 函数 () {waitforpastedata(that.e, that.s)}setTimeout(that.callself,20);}}函数处理粘贴(元素,已保存的内容){粘贴数据 = elem.innerHTML;//^^ 或者在这里循环遍历 dom(elem.childNodes 或 elem.getElementsByTagName)elem.innerHTML = 保存的内容;//对收集的数据做任何事情;警报(粘贴数据);}
<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

上设置光标位置.然后,您可以在用户启动粘贴操作时光标所在的位置插入粘贴的数据.

附言这段代码的组合,IE <= 8 和 jsfiddle 似乎不起作用,但它在 ie 中起作用

I'm trying to allow the user to paste an image into a div. The problem is that I need it work in Firefox.

From what I've read, Firefox since version 13 (I think) doesn't allow JavaScript access to the clipboard, and event.clipboard doesn't exist in it. I know it can be done because Gmail and Yahoo alow it even in Firefox.

I just want it to work in anyway posible, be with jQuery, JavaScript, HTML5, it doesn't matter as long as it works in the latest Firefox. (No Flash though).

解决方案

I used the code from this question for my cross-browser paste implementation.. it works in all browsers I have tested (scroll down for the actual solution/code). It should be noted that event.clipboardData expires immediately after the paste event has completed execution.

I went ahead and quadruple checked that this does work in Firefox version 19 (I don't have 13 available, but it sounds like this question was about degradation of a feature in newer versions).

Below is the answer, quoted from Nico Burns:

Solution

Tested in IE6+, FF 3.5+, recent-ish versions of 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>

Explanation

The onpaste event has the handlepaste function attached to it, and passed two arguments: this (i.e. a reference to the element that the event is attached to) and event which is the event object.


The handlepaste function:

The first line simply saves the content of the editable div to a variable so it can be restored again at the end.

The if checks whether the browser is an webkit browser (chrome or safari), and if it is it sets contents of the editable div to the data being pasted. It then cancels the event to prevent webkit pasting anything twice. This is because webkit is awkward, and won't paste anything if you simply clear the div.

If it is not a webkit browser then it simply clears the editable div.

It then calls the waitforpastedata function


The waitforpastedata function:

This is necessary because the pasted data doesn't appear straight away, so if you just called processpaste straight away then it wouldn't have any data to process.

What it does is check if the editable div has any content, if it does then calls processpaste, otherwise it sets a timer to call itself and check again in 20 milliseconds.


The processpaste function:

This function saved the innerHTML of the editable div (which is now the pasted data) to a variable, restores the innerHTML of the editable div back to its original value, and the alert the pasted data. Obviously in a real usage scenario you would probably want to something other than just alert data, you can do whatever you like with it from here.

You will probably also want to run the pasted data through some kind of data sanitising process. This can be done either while it is still in the editable div, or on the extracted string.


In a real sitution you would probably want to save the selection before, and restore it afterwards (Set cursor position on contentEditable <div>). You could then insert the pasted data at the position the cursor was in when the user initiated the paste action.

P.S. The combination of this code, IE <= 8 and jsfiddle doesn't seem to work, but it does work in ie <= 8 in a non-jsfiddle environment.

这篇关于从剪贴板 Firefox 获取粘贴的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 01:09