2014-01-27 25 views
13
  1. 打開圖像編輯程序,複製圖像(不要從瀏覽器中複製 - 我會解釋爲什麼以後)
  2. 打開Firefox,然後轉到http://imgur.com
  3. 按下Ctrl鍵+V
  4. 外觀與在圖像大吃一驚的是,你正在上傳之前複製。

我瞭解HTML5剪貼板API,這對Chrome非常適用。在Chrome中,當您粘貼二進制圖像數據,瀏覽器觸發包含event.clipboardData.types一個paste事件等於['Files'],我能因此得到我的形象在剪貼板在imgur中粘貼圖像如何在Firefox中工作?

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

在Firefox中,當我粘貼的二進制圖像數據,瀏覽器也會觸發一個粘貼事件,但是event.clipboardData.types爲空(具有length === 0)和event.clipboardData.getData('Files')明顯返回""

順便說一下,從瀏覽器複製圖像還會在clipboardData中設置一個「text/html」項目,該項目包含複製的<img>元素。所以在這種情況下,我可以通過發送遠程URL到服務器來解決這個問題,然後服務器會自己下載鏡像(如果服務器可以訪問遠程位置,這並不能保證)。

StackOverflow的建議是: How to obtain data from clipboard in Firefox (創建CONTENTEDITABLE <div>,要求用戶粘貼到,然後複製內容。)

然而,imgur沒有做到這一點。這是如何運作的?

回答

18

聲明:在發佈之前我不知道imgur上傳系統,但我希望它能幫助你。這篇文章只是通過查看代碼和一些HTML/JS知識來編寫:)

imgur似乎對Firefox(以及一般的Gecko瀏覽器)使用了不同的粘貼選項。確實,索引HTML中有一個upload-global-FF-paste-box 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) 
}, 

然後,通過在global.js文件挖一點,我發現這些功能(見上文)。基本上,這個過程是:

  1. 等待用戶做出按Ctrl-V行動
  2. 當它的發射,使之前在焦點看過contenteditable格,檢索數據
  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 = "" 
}, 
+3

哦,所以它到底是內容粘貼到一個CONTENTEDITABLE股利。謝謝 :) – Roman

相關問題