Làm thế nào để hình ảnh dán từ chức năng clipboard hoạt động trong Gmail và Google Chrome 12+?


148

Tôi nhận thấy một bài đăng trên blog từ Google có đề cập đến khả năng dán hình ảnh trực tiếp từ bảng ghi tạm vào thư Gmail nếu bạn đang sử dụng phiên bản Chrome mới nhất. Tôi đã thử điều này với phiên bản Chrome của tôi (12.0.742.91 beta-m) và nó hoạt động rất tốt khi sử dụng các phím điều khiển hoặc menu ngữ cảnh.

Từ hành vi đó, tôi cần giả định rằng phiên bản mới nhất của webkit được sử dụng trong Chrome có thể xử lý hình ảnh trong sự kiện dán Javascript, nhưng tôi không thể tìm thấy bất kỳ tài liệu tham khảo nào về cải tiến như vậy. Tôi tin rằng ZeroClipboard liên kết với các sự kiện nhấn phím để kích hoạt chức năng flash của nó và như vậy sẽ không hoạt động thông qua menu ngữ cảnh (đồng thời, ZeroClipboard là trình duyệt chéo và bài đăng cho biết điều này chỉ hoạt động với Chrome).

Vậy, làm thế nào để nó hoạt động và nơi cải tiến được tạo ra cho Webkit (hoặc Chrome) cho phép chức năng?


3
Có vẻ như nó cũng hoạt động ngẫu nhiên với Firefox. Bất cứ ai cũng biết nếu điều này được cho là được hỗ trợ với Firefox?
Sébastien

Câu trả lời:


231

Tôi đã dành một chút thời gian để thử nghiệm điều này. Nó dường như sắp xếp theo thông số API Clipboard mới . Bạn có thể xác định trình xử lý sự kiện "dán" và xem event.clipboardData.items và gọi getAsFile () trên chúng để nhận Blob. Khi bạn có Blob, bạn có thể sử dụng FileReader trên đó để xem những gì trong đó. Đây là cách bạn có thể nhận url dữ liệu cho nội dung bạn vừa dán trong Chrome:

// window.addEventListener('paste', ... or
document.onpaste = function(event){
  var items = (event.clipboardData || event.originalEvent.clipboardData).items;
  console.log(JSON.stringify(items)); // will give you the mime types
  for (index in items) {
    var item = items[index];
    if (item.kind === 'file') {
      var blob = item.getAsFile();
      var reader = new FileReader();
      reader.onload = function(event){
        console.log(event.target.result)}; // data url!
      reader.readAsDataURL(blob);
    }
  }
}

Khi bạn có một url dữ liệu, bạn có thể hiển thị hình ảnh trên trang. Nếu bạn muốn tải nó lên thay vào đó, bạn có thể sử dụng readAsBinaryString hoặc bạn có thể đặt nó vào XHR bằng FormData .


6
Nắm bắt ống hút ở đây, nhưng có ý tưởng nào tại sao event.clipboardData.items dường như là 'không xác định' trong Safari 5.1 không? Hoặc thậm chí làm thế nào để có được nội dung clipboard cho một tệp / blob trong Safari? Hoạt động tuyệt vời trong Chrome. Bạn sẽ nghĩ webkit sẽ là webkit :(
Gavin Gilmour

7
@SenicaGonzalez đó là vì dữ liệu chỉ tồn tại trong suốt thời gian của sự kiện. Sau sự kiện, nó không còn nữa, vì vậy khi bạn cố gắng mở đối tượng trong thanh tra, bạn sẽ không thấy gì.
Nick Retallack

3
tôi chạy cái này trên Firefox và var blob = items [0] .getAsFile () throw TypeError: các mục không được xác định
chinna_82

2
Bạn có phiền khi làm một ví dụ về cách gửi XMLHttpRequest với dữ liệu hình ảnh đó không? Điều đó sẽ thực sự tốt đẹp: D
poitroae

1
Dưới đây là cách bạn có thể gửi bằng cách sử dụng XMLHttpRequest, tôi đã viết nó lên blog sau khi tôi triển khai nó: blog.securevideo.com/2013/11/27/ trên
JT Taylor

56

Câu trả lời của Nick dường như cần những thay đổi nhỏ để vẫn hoạt động :)

// window.addEventListener('paste', ... or
document.onpaste = function (event) {
  // use event.originalEvent.clipboard for newer chrome versions
  var items = (event.clipboardData  || event.originalEvent.clipboardData).items;
  console.log(JSON.stringify(items)); // will give you the mime types
  // find pasted image among pasted items
  var blob = null;
  for (var i = 0; i < items.length; i++) {
    if (items[i].type.indexOf("image") === 0) {
      blob = items[i].getAsFile();
    }
  }
  // load image if there is a pasted image
  if (blob !== null) {
    var reader = new FileReader();
    reader.onload = function(event) {
      console.log(event.target.result); // data url!
    };
    reader.readAsDataURL(blob);
  }
}

Ví dụ mã chạy: http://jsfiddle.net/bt7BU/225/

Vì vậy, những thay đổi đối với câu trả lời là:

var items = event.clipboardData.items;

đến

var items = (event.clipboardData  || event.originalEvent.clipboardData).items;

Ngoài ra tôi phải lấy phần tử thứ hai từ các mục đã dán (phần đầu tiên có vẻ là văn bản / html nếu bạn sao chép một hình ảnh từ một trang web khác vào bộ đệm). Vì vậy, tôi đã thay đổi

  var blob = items[0].getAsFile();

đến một vòng lặp tìm mục chứa hình ảnh (xem bên trên)

Tôi không biết làm thế nào để trả lời trực tiếp câu trả lời của Nick, hy vọng nó ổn ở đây: $ :)


1
Chúng ta nên gửi dữ liệu hình ảnh như XMLHttpRequest như thế nào?
poitroae

Đối với những người khác đang đọc bài này, câu trả lời cho câu hỏi này có thể được bao gồm ngay bây giờ: stackoverflow.com/questions/18055422/
mẹo

4
Tôi không hiểu Khi tôi dán các tệp trong trình duyệt, phần mềm clipboardData.itemsnày luôn trống trong google chrome (Firefox hoạt động). Chrome bây giờ cần tối ưu hóa gần như nhiều như IE đã từng.
Tomáš Zato - Phục hồi Monica

1
Chỉnh sửa nhỏ: if (blob! = Null) {(hoặc đặt blob = null khi khởi tạo)
Pancakeo

1
event.clipboardData.itemslàm việc tốt với tôi trên Chrome mới nhất, không chắc khi nào event.originalEvent...hữu ích?
Ruben Martinez Jr.


5

Trình duyệt web tiếp tục di chuyển về phía trước. Gần đây tôi đã tìm thấy điều này:

Đoạn mã - Truy cập hình ảnh bảng tạm bằng Javascript

và điều này:

Paste Wasteland (hoặc, tại sao sự kiện onPaste là một mớ hỗn độn)

Liên kết đầu tiên mô tả một cách để có được hình ảnh clipboard chỉ bằng JavaScript trên Firefox và Chrome. Liên kết thứ hai chứa một phần tái bút đề cập đến kỹ thuật tương tự đã được điều chỉnh cho IE (phiên bản không xác định).


Firefox thậm chí không kích hoạt Chỉnh sửa | Dán mục menu cho tôi, vì vậy tôi không thấy nó hoạt động như thế nào trong Firefox.
podperson

Một trong những liên kết đó không hoạt động tại thời điểm bình luận.
Crazywako

2

Theo như tôi biết -

Với các tính năng HTML 5 (File Api và các liên quan) - hiện có thể truy cập dữ liệu hình ảnh clipboard bằng javascript đơn giản.

Tuy nhiên, điều này không hoạt động trên IE (bất cứ điều gì ít hơn IE 10). Không biết nhiều về hỗ trợ IE10.

Đối với IE, các tùy chọn mà tôi tin là các tùy chọn 'dự phòng' đang sử dụng api AIR của Adobe hoặc sử dụng một applet đã ký


1

Wow nó thật tuyệt. Tôi chưa đi sâu vào nguồn gmail để tìm ra nó (tôi đã làm với chức năng kéo ra), nhưng tôi đoán rằng đó là một phần mở rộng của API kéo / thả mà chrome đã mở rộng. Có một bài viết hay về cách tính năng kéo vào máy tính để bàn hoạt động: http://www.thecssninja.com/javascript/gmail-dragout mà ít nhất có thể chỉ cho bạn đi đúng hướng.


0

Đây là từ một ví dụ với bản thảo angular2 hoạt động cho dự án của tôi. Hy vọng nó sẽ giúp được ai đó. Logic cũng tương tự đối với các trường hợp khác.

https://gist.github.com/sandeepsuvit/a8ba77faebba260455985504be24aef7

Đây là một thực hiện trực tiếp:

https://stackblitz.com/edit/angular-f7kcny?file=app/app.component.ts


1
Bạn có thể vui lòng giải thích quá trình bạn đã làm theo? Bạn có thể mở liên kết https://stackblitz.com/edit/angular-f7kcny?file=app/app.component.tsbằng chrome và sau đó nhấp chuột phải vào hình ảnh từ bất kỳ trang web nào. Sau đó dán nó vào hộp văn bản được cung cấp. Nó nên hoạt động theo cách đó.
Sandeep K Nair

sao chép từ hình ảnh web hoạt động. Tôi đã thử hình ảnh từ windows explorer, rằng tại sao nó không hoạt động. Bạn có biết cách xử lý hình ảnh được sao chép từ windows explorer để dán nó lên trang web không?
Trận Hawk

Tôi chưa thử tùy chọn này. Hy vọng rằng bạn có thể nhận được thông tin chi tiết từ các thư viện thay thế https://github.com/layerssss/paste.js/, https://github.com/JoelBesada/pasteboard. Có những bản demo có sẵn trên các liên kết này mà bạn có thể thử.
Sandeep K Nair

event.clipboardData trống khi tôi dán hình ảnh trên máy hệ điều hành windows. Có ai giải thích được tại sao điều này xảy ra không?
Tunç Doğan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.