在imgur中图像粘贴如何在Firefox中运行?

Rom*_*man 13 javascript clipboard firefox html5 imgur

  1. 打开图像编辑程序,复制图像(不要从浏览器复制 - 我将在后面解释原因).
  2. 打开Firefox并转到http://imgur.com
  3. Ctrl+V
  4. 在上传之前复制的图像完全令人惊讶.

我知道HTML5剪贴板API,它适用于Chrome.在Chrome中,当您粘贴二进制图像数据时,浏览器会触发一个paste包含event.clipboardData.types等于的事件['Files'],因此我可以将我的图像放在剪贴板中

var index = event.clipboardData.types.indexOf('Files');
if(index !== -1) {
    var blob = event.clipboardData.items[index].getAsFile();
}
Run Code Online (Sandbox Code Playgroud)

在Firefox中,当我粘贴二进制图像数据时,浏览器也会触发粘贴事件,但它event.clipboardData.types是空的(有length === 0)并且event.clipboardData.getData('Files')显然会返回"".

顺便说一下,从浏览器复制图像也会设置一个"text/html"项,clipboardData其中包含复制的<img>元素.因此,在这些情况下,我可以通过将远程URL发送到服务器来解决问题,然后服务器将自己下载图像(如果服务器可以访问远程位置,这是不能保证的).

StackOverflow建议: 如何从Firefox中的剪贴板获取数据 (创建一个contenteditable <div>,请用户粘贴到该剪贴板然后复制内容.)

但是,imgur不这样做.这是如何运作的?

Max*_*ant 17

免责声明:在发布之前我不知道imgur上传系统,但我希望它能帮到你.这篇文章只是通过查看代码和一些HTML/JS知识来编写:)

imgur似乎对Firefox(以及一般的Gecko浏览器)使用不同的粘贴选项.实际上,upload-global-FF-paste-box在索引HTML中有一个带有ID 的div ,带有属性contenteditable="true".在主js中,我们可以找到属性的初始化$FFPasteBox:

init: function (a) {
    this._ = $.extend({
        el: {
            $computerButton: $("#gallery-upload-buttons #file-wrapper"),
            $webButton: $("#gallery-upload-buttons #url"),
            $computerButtonGlobal: $("#upload-global-file"),
            $FFPasteBox: $("#upload-global-FF-paste-box")  // <--- this line
        }
    }, a)
},
Run Code Online (Sandbox Code Playgroud)

然后,通过在global.js文件中挖掘一点,我找到了这些函数(见上文).基本上,这个过程是:

  1. 等待用户进行Ctrl-V操作
  2. 当它被触发时,使contenteditable之前看到的div成为焦点,以检索数据
  3. 等待数据已完全发送(高分辨率照片可能很长)
  4. 分析获得的base64字符串.

这是从global.js我自己评论并提取的代码:

// When a paste action is trigger, set the focus on this div and wait the data to be sent
initPasteUploadMozilla: function () {
    $(document).on("paste", _.bind(function (a) {
        $(a.target).is("input") || this.isInView() && (Imgur.Upload.Index && this.showColorBox(), this._.el.$FFPasteBox.focus(), this.waitForPasteData(this._.el.$FFPasteBox[0]))
    }, this))
},

// Listen the user, and waiting that the node is created by the paste action
waitForPasteData: function (a) {
    a.childNodes && a.childNodes.length > 0 ? this.processPaste(a) : setTimeout(this.waitForPasteData.bind(this, a), 20)
},

// Check data sent
processPaste: function (a) {
    var b = a.innerHTML,
        // Check if the thing pasted is a <img tag or a png or at least base64 stuff
        c = {
            image: -1 != b.indexOf("<img") && -1 != b.indexOf("src="),
            base64: -1 != b.indexOf("base64,"),
            png: -1 != b.indexOf("iVBORw0K")
        };
    if (c.image && c.base64 && c.png) {
        var d = b.split('<img src="');
        d = d[1].split('" alt="">');
        var b = {
            dataURL: d[0],
            file: {
                size: this.bytesizeBase64String(d[0].length)
            }
        };
        this.addBase64(b)
    } else {
        var e = $(a).find("img"),
            f = null;
        if (e.length > 0 && e.attr("src").length > 0 ? f = e.attr("src") : b.length > 0 && (f = b), null !== f && f.match(this._.urlRegex)) this.queueUrl(f);
        else if (null !== f) {
            var g = $(f).filter("a");
            g.length && g.attr("href").match(this._.urlRegex) ? this.queueUrl(g.attr("href")) : this.showError(this._.messages.urlInvalidError)
        }
    }
    a.innerHTML = ""
},
Run Code Online (Sandbox Code Playgroud)

  • 哦,所以最后它将内容粘贴到一个可信的div中.谢谢 :) (3认同)