รูปภาพวางจากฟังก์ชั่นคลิปบอร์ดทำงานใน Gmail และ Google Chrome 12+ อย่างไร


148

ฉันสังเกตเห็นโพสต์บล็อกจาก Googleที่กล่าวถึงความสามารถในการวางรูปภาพโดยตรงจากคลิปบอร์ดลงในข้อความ Gmail หากคุณใช้ Chrome เวอร์ชันล่าสุด ฉันลองสิ่งนี้กับ Chrome รุ่นที่ฉันใช้ (12.0.742.91 beta-m) และใช้งานได้ดีโดยใช้ปุ่มควบคุมหรือเมนูบริบท

จากพฤติกรรมดังกล่าวฉันต้องสมมติว่า webkit เวอร์ชันล่าสุดที่ใช้ใน Chrome สามารถจัดการกับรูปภาพในเหตุการณ์การวาง Javascript ได้ แต่ฉันไม่สามารถค้นหาการอ้างอิงถึงการปรับปรุงดังกล่าวได้ ฉันเชื่อว่าZeroClipboardเชื่อมโยงกับกิจกรรมการกดปุ่มเพื่อเรียกใช้ฟังก์ชันการทำงานของแฟลชและจะไม่ทำงานผ่านเมนูบริบท (เช่นกัน ZeroClipboard ข้ามเบราว์เซอร์และโพสต์บอกว่าใช้งานได้กับ Chrome เท่านั้น)

ดังนั้นสิ่งนี้ทำงานอย่างไรและการเพิ่มประสิทธิภาพให้กับ Webkit (หรือ Chrome) ที่ใช้งานได้อย่างไร


3
ดูเหมือนว่าจะทำงานแบบสุ่มกับ Firefox เช่นกัน มีใครรู้ไหมว่าควรได้รับการสนับสนุนจาก Firefox หรือไม่
Sébastien

คำตอบ:


231

ฉันใช้เวลาในการทดลองกับสิ่งนี้ ดูเหมือนว่าจะเป็นไปตามข้อมูลจำเพาะคลิปบอร์ด APIใหม่ คุณสามารถกำหนดตัวจัดการเหตุการณ์ "วาง" และดูที่ event.clipboardData.items และเรียกใช้ getAsFile () บนตัวจัดการเหล่านั้นเพื่อรับ Blob เมื่อคุณมี Blob แล้วคุณสามารถใช้FileReaderเพื่อดูว่ามีอะไรอยู่ในนั้น นี่คือวิธีที่คุณจะได้รับ URL ข้อมูลสำหรับสิ่งที่คุณเพิ่งวางใน 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);
    }
  }
}

เมื่อคุณมี URL ข้อมูลแล้วคุณสามารถแสดงภาพในหน้านั้นได้ หากคุณต้องการอัปโหลดไปแทนคุณสามารถใช้ readAsBinaryString หรือคุณอาจจะใส่ลงใน XHR ใช้FormData


6
จับที่ฟางที่นี่ แต่มีความคิดใด ๆ ว่าเหตุใด event.clipboardData.items ดูเหมือนจะ 'ไม่ได้กำหนด' ใน Safari 5.1 หรือวิธีการรับเนื้อหาของคลิปบอร์ดสำหรับไฟล์ / blob ใน Safari? ใช้งานได้ดีใน Chrome คุณคิดว่า webkit จะเป็น webkit :(
Gavin Gilmour

7
@SenicaGonzalez นั่นเป็นเพราะข้อมูลมีอยู่ในช่วงเวลาของเหตุการณ์เท่านั้น หลังจากเหตุการณ์มันหายไปดังนั้นเมื่อคุณพยายามพลิกเปิดวัตถุในตัวตรวจสอบคุณจะไม่เห็นอะไรเลย
Nick Retallack

3
ฉันเรียกใช้สิ่งนี้บน Firefox และ var blob = items [0] .getAsFile () โยน TypeError: รายการไม่ได้กำหนด
chinna_82

2
คุณจะลองทำตัวอย่างวิธีส่ง XMLHttpRequest กับข้อมูลภาพนั้นได้ไหม นั่นคงจะดีจริง ๆ : D
poitroae

1
นี่คือวิธีที่คุณสามารถส่งโดยใช้ XMLHttpRequest ฉันเขียนมันลงในบล็อกหลังจากที่ฉันติดตั้งแล้ว: blog.securevideo.com/2013/11/27/ …
JT Taylor

56

คำตอบโดย Nick ดูเหมือนจะต้องมีการเปลี่ยนแปลงเล็กน้อยเพื่อยังคงทำงาน :)

// 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);
  }
}

ตัวอย่างรหัสเรียกใช้: http://jsfiddle.net/bt7BU/225/

ดังนั้นการเปลี่ยนแปลงคำตอบของชื่อเล่นคือ:

var items = event.clipboardData.items;

ถึง

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

นอกจากนี้ฉันยังต้องนำองค์ประกอบที่สองจากรายการวาง (อันแรกดูเหมือนจะเป็นข้อความ / html ถ้าคุณคัดลอกภาพจากหน้าเว็บอื่นลงในบัฟเฟอร์) ดังนั้นฉันจึงเปลี่ยน

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

ไปยังลูปเพื่อค้นหารายการที่มีรูปภาพ (ดูด้านบน)

ฉันไม่รู้วิธีตอบโดยตรงกับคำตอบของ Nick หวังว่าจะใช้ได้ที่นี่: $ :)


1
เราควรส่งข้อมูลรูปภาพเป็น XMLHttpRequest อย่างไร
poitroae

สำหรับผู้อื่นที่อ่านข้อความนี้อาจมีคำตอบสำหรับคำถามนี้ไว้ในตอนนี้: stackoverflow.com/questions/18055422/ … :)
robintibor

4
ฉันไม่เข้าใจ เมื่อฉันวางไฟล์ในเบราว์เซอร์clipboardData.itemsจะว่างเปล่าเสมอใน google chrome (Firefox ใช้งานได้) ตอนนี้โครเมียมต้องการการปรับให้เหมาะสมเกือบเท่ากับ IE
Tomáš Zato - Reinstate Monica

1
แก้ไข
เล็กน้อย

1
event.clipboardData.itemsทำงานได้ดีสำหรับฉันใน Chrome ล่าสุดไม่แน่ใจว่าเมื่อevent.originalEvent...มีประโยชน์หรือไม่
รูเบนมาร์ติเนซจูเนียร์


5

เว็บเบราว์เซอร์เดินหน้าต่อไป ฉันเพิ่งพบสิ่งนี้:

ข้อมูลโค้ด - การเข้าถึงรูปภาพของคลิปบอร์ดด้วย Javascript

และนี่:

The Paste Wasteland (หรือเหตุใดเหตุการณ์ onPaste จึงไม่เป็นระเบียบ)

ลิงก์แรกอธิบายวิธีรับภาพคลิปบอร์ดโดยใช้ JavaScript เฉพาะใน Firefox และ Chrome ลิงค์ที่สองมี postscript ที่กล่าวถึงเทคนิคเดียวกันนั้นได้ปรับให้เข้ากับ IE (เวอร์ชันที่ไม่รู้จัก)


Firefox ไม่แม้แต่เปิดใช้งานการแก้ไข | วางรายการเมนูสำหรับฉันดังนั้นฉันจึงไม่เห็นวิธีการทำงานใน Firefox เลย
podperson

ลิงก์เหล่านั้นอย่างใดอย่างหนึ่งไม่ทำงานในเวลาที่แสดงความคิดเห็น
Crazywako

2

เท่าที่ฉันรู้ -

ด้วยคุณสมบัติ HTML 5 (File Api และที่เกี่ยวข้อง) - การเข้าถึงข้อมูลรูปภาพคลิปบอร์ดทำได้ด้วยจาวาสคริปต์ธรรมดา

อย่างไรก็ตามสิ่งนี้ล้มเหลวในการทำงานบน IE (อะไรที่น้อยกว่า IE 10) ไม่ทราบมากเกี่ยวกับการรองรับ IE10

สำหรับ IE ตัวเลือกที่ฉันเชื่อว่าเป็นตัวเลือก 'ทางเลือก' อาจใช้ Adobe AIR ของ Adobe หรือใช้แอปเพล็ตที่ลงนามแล้ว


1

ว้าวมันเยี่ยมมาก ฉันยังไม่ได้ดำดิ่งลงในแหล่ง gmail เพื่อหาทาง (ฉันทำกับฟังก์ชั่นการลากออก) แต่ฉันเดาว่ามันเป็นส่วนเสริมของ API การลาก / วางที่ Chrome ได้ขยายออกไปแล้ว มีการเขียนที่ดีเกี่ยวกับวิธีการทำงานของคุณลักษณะการลากไปยังเดสก์ท็อป: http://www.thecssninja.com/javascript/gmail-dragoutซึ่งอย่างน้อยอาจชี้คุณไปในทิศทางที่ถูกต้อง


0

นี่คือจากตัวอย่างที่มี angular2 typescript ที่เหมาะกับโครงการของฉัน หวังว่าจะช่วยใครซักคน ลอจิกเหมือนกันสำหรับกรณีอื่นเช่นกัน

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

นี่คือการดำเนินการสด:

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


1
คุณช่วยอธิบายกระบวนการที่คุณทำตามได้ไหม? คุณสามารถเปิดลิงค์https://stackblitz.com/edit/angular-f7kcny?file=app/app.component.tsใน chrome แล้วคลิกขวาที่ภาพจากเว็บไซต์ใด ๆ จากนั้นวางลงในกล่องข้อความที่ให้ไว้ มันควรจะทำงานอย่างนั้น
Sandeep K Nair

คัดลอกจากงานภาพบนเว็บ ฉันลองรูปภาพจาก windows explorer ว่าทำไมมันไม่ทำงาน คุณรู้วิธีจัดการกับภาพที่คัดลอกมาจาก windows explorer เพื่อวางลงบนเว็บเพจหรือไม่
Battle Hawk

ฉันยังไม่ได้ลองตัวเลือกนี้ หวังว่าคุณจะได้รับข้อมูลเชิงลึกจากห้องสมุดเหล่านี้แทน,https://github.com/layerssss/paste.js/ https://github.com/JoelBesada/pasteboardมีการสาธิตในลิงก์เหล่านี้ซึ่งคุณสามารถทดลองใช้ได้
Sandeep K Nair

event.clipboardData ว่างเปล่าเมื่อฉันวางภาพบนระบบปฏิบัติการ windows ทุกคนสามารถอธิบายได้ว่าทำไมสิ่งนี้ถึงเกิดขึ้น
TunçDoğan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.