ฉันจะคัดลอกไปยังคลิปบอร์ดใน JavaScript ได้อย่างไร


3320

วิธีที่ดีที่สุดในการคัดลอกข้อความไปยังคลิปบอร์ดคืออะไร? (Multi-เบราว์เซอร์)

ฉันเหนื่อย:

function copyToClipboard(text) {
    if (window.clipboardData) { // Internet Explorer
        window.clipboardData.setData("Text", text);
    } else {  
        unsafeWindow.netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  
        const clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);  
        clipboardHelper.copyString(text);
    }
}

แต่ใน Internet Explorer จะให้ข้อผิดพลาดทางไวยากรณ์ ใน Firefox มันบอกว่าunsafeWindow is not definedก็กล่าวว่า

เคล็ดลับดี ๆ ที่ไม่มีแฟลช: Trello เข้าถึงคลิปบอร์ดของผู้ใช้ได้อย่างไร


แค่อยากรู้สิ่งที่คุณต้องการคัดลอกไปยังคลิปบอร์ดที่ผู้ใช้ไม่สามารถทำเองได้?
scunliffe

233
ไม่มีอะไรพิเศษ. พวกเขาสามารถทำได้ด้วยตนเอง แต่ฉันต้องการเสนอความเป็นไปได้ในการคลิกปุ่มโดยไม่ต้องกังวลเกี่ยวกับการเลือกส่วนที่ถูกต้องของข้อความ
Santiago Corredoira

4
โพสต์บล็อกยาวนี้มีหลายวิธีในการทำเช่นนี้: การเข้าถึงคลิปบอร์ดของระบบด้วย JavaScript - Holy Grail?
Aaron Digulla

มันให้ข้อยกเว้นเบราว์เซอร์ที่ไม่ได้กำหนดใน IE เช่นเดียวกับใน FF
Jagadeesh

1
หากเราสามารถใส่ข้อความลงในคลิปบอร์ดของผู้ใช้เราสามารถทำลายคลิปบอร์ดของเขา
Frank Fang

คำตอบ:


2247

ภาพรวม

มีเบราว์เซอร์หลักสาม API สำหรับคัดลอกไปยังคลิปบอร์ด:

  1. Async Clipboard API [navigator.clipboard.writeText]
    • ส่วนที่เน้นข้อความมีอยู่ในChrome 66 (มีนาคม 2018)
    • การเข้าถึงแบบอะซิงโครนัสและใช้JavaScript สัญญาสามารถเขียนได้เพื่อให้ผู้ใช้การรักษาความปลอดภัยแจ้งเตือน (ถ้าแสดง) ไม่ขัดจังหวะ JavaScript ในหน้า
    • ข้อความสามารถคัดลอกไปยังคลิปบอร์ดโดยตรงจากตัวแปร
    • รองรับเฉพาะในหน้าที่แสดงผ่าน HTTPS
    • ใน Chrome 66 หน้าในแท็บที่ใช้งานอยู่สามารถเขียนไปยังคลิปบอร์ดได้โดยไม่ต้องขออนุญาต
  2. document.execCommand('copy')
    • เบราว์เซอร์ส่วนใหญ่รองรับสิ่งนี้ตั้งแต่ ~ เมษายน 2015 (ดูที่การสนับสนุนเบราว์เซอร์ด้านล่าง)
    • การเข้าถึงแบบซิงโครนัสคือหยุด JavaScript ในหน้าจนกว่าจะเสร็จสมบูรณ์รวมถึงการแสดงผลและการโต้ตอบกับผู้ใช้กับพรอมต์ความปลอดภัย
    • ข้อความถูกอ่านจาก DOM และวางไว้บนคลิปบอร์ด
    • ในระหว่างการทดสอบ ~ เมษายน 2558 มีการบันทึกเฉพาะ Internet Explorer เท่านั้นเนื่องจากแสดงการอนุญาตให้ใช้งานขณะที่เขียนไปยังคลิปบอร์ด
  3. การเอาชนะเหตุการณ์คัดลอก
    • ดูเอกสารคลิปบอร์ด API ในการเอาชนะเหตุการณ์การคัดลอก
    • ช่วยให้คุณสามารถแก้ไขสิ่งที่ปรากฏบนคลิปบอร์ดจากเหตุการณ์การคัดลอกใด ๆ สามารถรวมรูปแบบข้อมูลอื่นที่ไม่ใช่ข้อความธรรมดา
    • ไม่ครอบคลุมที่นี่เนื่องจากไม่สามารถตอบคำถามได้โดยตรง

บันทึกการพัฒนาทั่วไป

อย่าคาดหวังว่าคำสั่งที่เกี่ยวข้องกับคลิปบอร์ดจะทำงานในขณะที่คุณกำลังทดสอบโค้ดในคอนโซล โดยทั่วไปหน้าจะต้องมีการใช้งาน (Async Clipboard API) หรือต้องการการโต้ตอบกับผู้ใช้ (เช่นผู้ใช้คลิก) เพื่ออนุญาตให้ ( document.execCommand('copy')) เข้าถึงคลิปบอร์ดดูด้านล่างเพื่อดูรายละเอียดเพิ่มเติม

สำคัญ (บันทึกไว้ที่นี่ 2020/02/20)

โปรดทราบว่าเนื่องจากโพสต์นี้ แต่เดิมเขียนเป็นลายลักษณ์อักษรว่าเลิกใช้สิทธิ์ใน IFRAME แบบ cross-originและIFRAME "sandboxing"อื่น ๆป้องกันการสาธิต "ปุ่มเรียกใช้ข้อมูลโค้ด" และตัวอย่าง "codepen.io ตัวอย่าง" ในเบราว์เซอร์บางตัว (รวมถึง Chrome และ Microsoft Edge )

ในการพัฒนาสร้างหน้าเว็บของคุณเองให้บริการหน้านั้นผ่านการเชื่อมต่อ HTTPS เพื่อทดสอบและพัฒนา

นี่คือหน้าทดสอบ / สาธิตซึ่งแสดงให้เห็นถึงการทำงานของรหัส: https://deanmarktaylor.github.io/clipboard-test/

Async + ทางเลือก

เนื่องจากระดับการสนับสนุนเบราว์เซอร์สำหรับ Async Clipboard API ใหม่คุณอาจต้องการย้อนกลับไปยังdocument.execCommand('copy')วิธีการเพื่อให้ครอบคลุมเบราว์เซอร์ที่ดี

นี่เป็นตัวอย่างง่ายๆ (อาจใช้ไม่ได้ในเว็บไซต์นี้อ่านหมายเหตุ "สำคัญ" ด้านบน):

function fallbackCopyTextToClipboard(text) {
  var textArea = document.createElement("textarea");
  textArea.value = text;
  
  // Avoid scrolling to bottom
  textArea.style.top = "0";
  textArea.style.left = "0";
  textArea.style.position = "fixed";

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Fallback: Copying text command was ' + msg);
  } catch (err) {
    console.error('Fallback: Oops, unable to copy', err);
  }

  document.body.removeChild(textArea);
}
function copyTextToClipboard(text) {
  if (!navigator.clipboard) {
    fallbackCopyTextToClipboard(text);
    return;
  }
  navigator.clipboard.writeText(text).then(function() {
    console.log('Async: Copying to clipboard was successful!');
  }, function(err) {
    console.error('Async: Could not copy text: ', err);
  });
}

var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

(ตัวอย่าง codepen.io อาจใช้งานไม่ได้อ่านหมายเหตุ "สำคัญ" ด้านบน) โปรดทราบว่าตัวอย่างนี้ทำงานได้ไม่ดีในการแสดงตัวอย่างแบบฝังของ Stack Overflow คุณสามารถลองได้ที่นี่: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors = 1011

Async Clipboard API

โปรดทราบว่ามีความสามารถใน "ขออนุญาต" และทดสอบการเข้าถึงคลิปบอร์ดผ่าน API การอนุญาตใน Chrome 66

var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
  console.log('Async: Copying to clipboard was successful!');
}, function(err) {
  console.error('Async: Could not copy text: ', err);
});

document.execCommand (สำเนา)

ส่วนที่เหลือของโพสต์นี้จะกล่าวถึงความแตกต่างและรายละเอียดของdocument.execCommand('copy')API

สนับสนุนเบราว์เซอร์

การdocument.execCommand('copy')สนับสนุนJavaScript เติบโตขึ้นโปรดดูลิงก์ด้านล่างสำหรับการอัปเดตเบราว์เซอร์:

ตัวอย่างง่ายๆ

(อาจไม่ทำงานในเว็บไซต์นี้อ่านหมายเหตุ "สำคัญ" ด้านบน)

var copyTextareaBtn = document.querySelector('.js-textareacopybtn');

copyTextareaBtn.addEventListener('click', function(event) {
  var copyTextarea = document.querySelector('.js-copytextarea');
  copyTextarea.focus();
  copyTextarea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }
});
<p>
  <button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
  <textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>

ตัวอย่างที่ซับซ้อน: คัดลอกไปยังคลิปบอร์ดโดยไม่แสดงอินพุต

ตัวอย่างง่ายๆข้างต้นใช้งานได้ดีหากมีtextareaหรือinputองค์ประกอบปรากฏบนหน้าจอ

ในบางกรณีคุณอาจต้องการคัดลอกข้อความไปยังคลิปบอร์ดโดยไม่แสดงองค์ประกอบinput/ textareaนี่คือตัวอย่างหนึ่งของวิธีการแก้ไขปัญหานี้ (โดยทั่วไปแทรกองค์ประกอบคัดลอกไปยังคลิปบอร์ดลบองค์ประกอบ):

ทดสอบกับ Google Chrome 44, Firefox 42.0a1 และ Internet Explorer 11.0.8600.17814

(อาจไม่ทำงานในเว็บไซต์นี้อ่านหมายเหตุ "สำคัญ" ด้านบน)

function copyTextToClipboard(text) {
  var textArea = document.createElement("textarea");

  //
  // *** This styling is an extra step which is likely not required. ***
  //
  // Why is it here? To ensure:
  // 1. the element is able to have focus and selection.
  // 2. if element was to flash render it has minimal visual impact.
  // 3. less flakyness with selection and copying which **might** occur if
  //    the textarea element is not visible.
  //
  // The likelihood is the element won't even render, not even a
  // flash, so some of these are just precautions. However in
  // Internet Explorer the element is visible whilst the popup
  // box asking the user for permission for the web page to
  // copy to the clipboard.
  //

  // Place in top-left corner of screen regardless of scroll position.
  textArea.style.position = 'fixed';
  textArea.style.top = 0;
  textArea.style.left = 0;

  // Ensure it has a small width and height. Setting to 1px / 1em
  // doesn't work as this gives a negative w/h on some browsers.
  textArea.style.width = '2em';
  textArea.style.height = '2em';

  // We don't need padding, reducing the size if it does flash render.
  textArea.style.padding = 0;

  // Clean up any borders.
  textArea.style.border = 'none';
  textArea.style.outline = 'none';
  textArea.style.boxShadow = 'none';

  // Avoid flash of white box if rendered for any reason.
  textArea.style.background = 'transparent';


  textArea.value = text;

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }

  document.body.removeChild(textArea);
}


var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

หมายเหตุเพิ่มเติม

ใช้งานได้เฉพาะเมื่อผู้ใช้ดำเนินการ

ทั้งหมด document.execCommand('copy')โทรจะต้องเกิดขึ้นเป็นผลโดยตรงจากการกระทำของผู้ใช้เช่นตัวจัดการเหตุการณ์คลิก นี่เป็นมาตรการหนึ่งในการป้องกันไม่ให้ยุ่งกับคลิปบอร์ดของผู้ใช้เมื่อพวกเขาไม่คาดหวัง

ดูโพสต์ของ Google Developers ที่นี่สำหรับข้อมูลเพิ่มเติม

API คลิปบอร์ด

หมายเหตุรายละเอียดร่าง API ของคลิปบอร์ดแบบเต็มสามารถดูได้ที่นี่: https://w3c.github.io/clipboard-apis/

รองรับหรือไม่

  • document.queryCommandSupported('copy')ควรกลับมาtrueหากคำสั่ง "ได้รับการสนับสนุนโดยเบราว์เซอร์"
  • และdocument.queryCommandEnabled('copy')กลับมาtrueถ้าdocument.execCommand('copy')จะประสบความสำเร็จถ้าเรียกว่าตอนนี้ การตรวจสอบเพื่อให้แน่ใจว่าคำสั่งถูกเรียกใช้จากเธรดที่ผู้ใช้เริ่มต้นและตรงตามข้อกำหนดอื่น

อย่างไรก็ตามเป็นตัวอย่างของปัญหาความเข้ากันได้ของเบราว์เซอร์ Google Chrome ตั้งแต่ ~ เมษายนถึง ~ ตุลาคม 2015 จะถูกส่งกลับtrueจากdocument.queryCommandSupported('copy')ถ้ามีการเรียกคำสั่งจากเธรดที่ผู้ใช้เป็นผู้เริ่มต้น

หมายเหตุรายละเอียดความเข้ากันได้ด้านล่าง

รายละเอียดความเข้ากันได้ของเบราว์เซอร์

ในขณะที่โทรง่าย ๆ ที่จะdocument.execCommand('copy')ห่อในtry/catchบล็อกที่เรียกว่าเป็นผลมาจากการคลิกของผู้ใช้จะช่วยให้คุณสามารถใช้งานร่วมกันได้มากที่สุดในรายการต่อไปนี้มีข้อแนะนำบางประการ:

โทรไปdocument.execCommand, document.queryCommandSupportedหรือdocument.queryCommandEnabledควรจะห่อในtry/ catchบล็อก

falseที่แตกต่างกันการใช้งานเบราว์เซอร์และรุ่นเบราว์เซอร์โยนประเภทที่แตกต่างกันยกเว้นเมื่อเรียกแทนที่จะกลับ

การใช้งานเบราว์เซอร์ที่แตกต่างกันยังคงอยู่ในฟลักซ์และคลิปบอร์ด APIยังอยู่ในร่างดังนั้นอย่าลืมทำการทดสอบ


41
วิธีการคัดลอกโดยตรงจาก .ie ข้อมูลตัวแปร: var str = "word";?
jscripter

10
@BubuDaba สร้างดัมมี่ที่ถูกซ่อน<textarea>ด้วย JS ผนวกเข้ากับdocument.bodyตั้งค่าให้ตัวแปรและใช้งานได้ตามลำดับจากcopyTextareaนั้นลบมันทันทีหลังจากคัดลอกเนื้อหา
SeinopSys

3
มีอะไรสำหรับ Safari หรือตัวบ่งชี้ใด ๆ ที่จะนำมาใช้ใน Safari?
www139

3
รุ่นเดียวที่ฉันพบว่าใช้งานได้กับเบราว์เซอร์ทั้งหมด ฉันพบว่าเมื่อใช้สิ่งนี้ใน Boostrap Modal ฉันต้องผนวกพื้นที่ข้อความกับคำกริยา ฉันจะให้ +1000 ถ้าฉันสามารถให้ทางออกของคุณ !!! ขอขอบคุณ!
แพทริค

3
@AyaSalama ประเด็นสำคัญคือการกระทำ "คัดลอก" ไม่สามารถเกิดขึ้นได้เว้นแต่จะปรากฏต่อเบราว์เซอร์ที่ผู้ใช้กำลังดำเนินการ ผู้ใช้จะไม่สามารถดำเนินการได้หากองค์ประกอบมีสไตล์ด้วย "จอแสดงผล: ไม่มี" เนื่องจากพวกเขาจะไม่สามารถมองเห็นหรือมีปฏิสัมพันธ์กับมัน
Dean Taylor

1256

การคัดลอกไปยังคลิปบอร์ดอัตโนมัติอาจเป็นอันตรายดังนั้นเบราว์เซอร์ส่วนใหญ่ (ยกเว้น IE) ทำให้เป็นเรื่องยากมาก ส่วนตัวผมใช้เคล็ดลับง่ายๆดังต่อไปนี้:

function copyToClipboard(text) {
  window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
}

ผู้ใช้จะถูกนำเสนอพร้อมกล่องข้อความซึ่งจะคัดลอกข้อความที่เลือกไว้แล้ว ตอนนี้ก็เพียงพอแล้วที่จะกดCtrl+ CและEnter(เพื่อปิดกล่อง) - และ voila!

ขณะนี้การดำเนินการคัดลอกคลิปบอร์ดนั้นปลอดภัยเนื่องจากผู้ใช้ทำด้วยตนเอง (แต่ในทางตรงไปตรงมา) แน่นอนทำงานได้ในเบราว์เซอร์ทั้งหมด

<button id="demo" onclick="copyToClipboard(document.getElementById('demo').innerHTML)">This is what I want to copy</button>

<script>
  function copyToClipboard(text) {
    window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
</script>


91
ฉลาด แต่สนับสนุนเพียงบรรทัดเดียวเท่านั้น
Aram Kocharyan

61
เป็นเรื่องเล็กน้อยที่จะเปลี่ยนฟังก์ชั่น "พรอมต์" เป็นโมดอลที่กำหนดเองเนื้อของเล่ห์เหลี่ยมคือใช้ฟิลด์เนื้อหาที่แก้ไขได้และเลือกข้อความล่วงหน้าและไม่ทำลาย UI ของเบราว์เซอร์โดยบังคับให้ผู้ใช้ ดำเนินการเอง A ++
Jon z

110
ยังไม่ใช้ javascript เพื่อคัดลอกไปยังคลิปบอร์ด ^ _ ^
RozzA

23
ถ้าข้อความของคุณมีมากกว่า 2000 ตัวอักษรก็จะถูกตัดออก แต่สำหรับตัวอย่างข้อความที่มีขนาดเล็กใช้งานได้ดี
RasTheDestroyer

445
แปลกที่สิ่งนี้ได้รับการโหวตขึ้น 457 ขณะที่ไม่ตอบคำถาม: คัดลอกไปยังคลิปบอร์ดใน Javascript !
stevenvh

298

วิธีการต่อไปนี้ใช้งานได้ใน Chrome, Firefox, Internet Explorer และ Edge และในเวอร์ชันล่าสุดของ Safari (เพิ่มการรองรับการคัดลอกในเวอร์ชัน 10 ซึ่งเปิดตัวในเดือนตุลาคม 2559)

  • สร้าง textarea และตั้งเนื้อหาเป็นข้อความที่คุณต้องการคัดลอกไปยังคลิปบอร์ด
  • ผนวก textarea เข้ากับ DOM
  • เลือกข้อความใน textarea
  • โทร document.execCommand ("คัดลอก")
  • ลบ textarea จาก dom

หมายเหตุ: คุณจะไม่เห็น textarea เนื่องจากมีการเพิ่มและลบภายในการเรียกใช้รหัส Javascript แบบซิงโครนัสแบบเดียวกัน

บางสิ่งที่ต้องระวังหากคุณใช้ตัวเอง:

  • เพื่อเหตุผลด้านความปลอดภัยสามารถเรียกได้จากตัวจัดการเหตุการณ์เช่นคลิก (เช่นเดียวกับการเปิดหน้าต่าง)
  • Internet Explorer จะแสดงกล่องโต้ตอบการอนุญาตในครั้งแรกที่มีการอัปเดตคลิปบอร์ด
  • Internet Explorer และ Edge จะเลื่อนเมื่อมีการโฟกัสข้อความ
  • execCommand () อาจมีการโยนในบางกรณี
  • บรรทัดใหม่และแท็บสามารถถูกกลืนได้จนกว่าคุณจะใช้ textarea (บทความส่วนใหญ่ดูเหมือนจะแนะนำให้ใช้ div)
  • ข้อความจะปรากฏให้เห็นในขณะที่แสดงกล่องโต้ตอบของ Internet Explorer คุณต้องซ่อนหรือใช้คลิปบอร์ดข้อมูลของ Internet Explorer ที่เฉพาะเจาะจง
  • ในผู้ดูแลระบบ Internet Explorer สามารถปิดการใช้งานคลิปบอร์ด API

ฟังก์ชั่นด้านล่างควรจัดการกับปัญหาต่าง ๆ ต่อไปนี้อย่างหมดจดที่สุด กรุณาแสดงความคิดเห็นหากคุณพบปัญหาใด ๆ หรือมีข้อเสนอแนะสำหรับการปรับปรุง

// Copies a string to the clipboard. Must be called from within an
// event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+,
// Firefox 42+, Safari 10+, Edge and Internet Explorer 10+.
// Internet Explorer: The clipboard feature may be disabled by
// an administrator. By default a prompt is shown the first
// time the clipboard is used (per session).
function copyToClipboard(text) {
    if (window.clipboardData && window.clipboardData.setData) {
        // Internet Explorer-specific code path to prevent textarea being shown while dialog is visible.
        return clipboardData.setData("Text", text);

    }
    else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
        var textarea = document.createElement("textarea");
        textarea.textContent = text;
        textarea.style.position = "fixed";  // Prevent scrolling to bottom of page in Microsoft Edge.
        document.body.appendChild(textarea);
        textarea.select();
        try {
            return document.execCommand("copy");  // Security exception may be thrown by some browsers.
        }
        catch (ex) {
            console.warn("Copy to clipboard failed.", ex);
            return false;
        }
        finally {
            document.body.removeChild(textarea);
        }
    }
}

https://jsfiddle.net/fx6a6n6x/


9
คำตอบที่ดี: การสนับสนุนข้ามเบราว์เซอร์การจัดการข้อผิดพลาด + ทำความสะอาด ณ วันนี้การสนับสนุนใหม่สำหรับ queryCommandSupported การคัดลอกไปยังคลิปบอร์ดเป็นไปได้ใน Javascript และควรเป็นคำตอบที่ยอมรับได้แทนที่จะเป็น window.prompt ที่น่าอึดอัดใจ ("คัดลอกไปยังคลิปบอร์ด: Ctrl + C, Enter", ข้อความ) window.clipboardData ได้รับการสนับสนุนใน IE9 ดังนั้นคุณควรเพิ่ม IE9 ในรายการสนับสนุนเบราว์เซอร์และฉันคิดว่าบางที IE8 และรุ่นก่อนหน้านี้ด้วย แต่จำเป็นต้องตรวจสอบ
user627283

ใช่. IE 8/9 น่าจะโอเค แอพของเราไม่รองรับ ดังนั้นฉันจึงไม่ได้ทดสอบ IE หยุดการสนับสนุนในเดือนมกราคมดังนั้นฉันจึงไม่ต้องกังวลเกินไป หวังว่าการสนับสนุนของ Safari จะมาถึงในไม่ช้า ฉันแน่ใจว่ามันอยู่ในเรดาร์ของพวกเขา
Greg Lowe

4
@SantiagoCorredoira: ในปี 2559 นี้สมควรที่จะได้รับคำตอบที่ยอมรับ โปรดพิจารณาการมอบหมาย BGT (เครื่องหมายสีเขียวขนาดใหญ่) อีกครั้ง
Lawrence Dol

3
@Noitidart I ทดสอบแล้วและทำงานได้อย่างสมบูรณ์แบบสำหรับ firefox 54, chrome 60 และเบราว์เซอร์ edge แม้เมื่อโฟกัสไม่ได้อยู่ในเอกสาร html ข้อผิดพลาดที่คุณอาจมีเฉพาะกับรุ่น FF 55
Tosin John

2
@Noitidart มันยังคงทำงานได้อย่างสมบูรณ์แบบที่นี่โดยมุ่งเน้นไปที่เครื่องมือ dev ไม่ได้หยุด และตามปกติแล้วผู้ใช้แอปพลิเคชันเว็บปกติจะทำอะไรกับเครื่องมือของนักพัฒนา
Tosin John

97

นี่คือสิ่งที่ฉันจะทำ ...

function copy(text) {
    var input = document.createElement('input');
    input.setAttribute('value', text);
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input);
    return result;
 }

@korayem: โปรดทราบว่าการใช้inputฟิลด์html จะไม่คำนึงถึงตัวแบ่งบรรทัด\nและจะทำให้ข้อความใด ๆ เป็นบรรทัดเดียว

ตามที่ @nikksan กล่าวไว้ในความคิดเห็นการใช้textareaจะแก้ไขปัญหาดังต่อไปนี้:

function copy(text) {
    var input = document.createElement('textarea');
    input.innerHTML = text;
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input);
    return result;
}

@nikksan วิธีการคัดลอกสตริงด้วย\n?
sof-03

2
@ sof-03 ใช้ textarea แทนการป้อนข้อมูลและเพิ่ม\r\nสำหรับการแบ่งบรรทัด
nikksan

1
ไม่ทำงานใน Microsoft Edge 42.17134.1.0 บน Win10x64
Honsa Stunna

3
ฉันคัดลอกคำตอบของคุณแล้ว มันทำงานได้ในโครเมี่ยมและนั่นคือทั้งหมดที่ฉันต้องการ
user875234

นี่เป็นทางออกที่ง่ายที่สุดที่ทำงานร่วมกับ Firefox v68.0.2 (64- บิต)
Arya

88

หากคุณต้องการโซลูชันที่เรียบง่ายจริงๆ (ใช้เวลาน้อยกว่า 5 นาทีในการรวม) และดูดีทันทีที่ออกจากกล่องClippyเป็นทางเลือกที่ดีสำหรับโซลูชันที่ซับซ้อนมากขึ้น

มันถูกเขียนโดยผู้ร่วมก่อตั้งของ GitHub ตัวอย่าง Flash ฝังโค้ดด้านล่าง:

<object
   classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
   width="110"
   height="14"
   id="clippy">
  <param name="movie" value="/flash/clippy.swf"/>
  <param name="allowScriptAccess" value="always"/>
  <param name="quality" value="high"/>
  <param name="scale" value="noscale"/>
  <param NAME="FlashVars" value="text=#{text}"/>
  <param name="bgcolor" value="#{bgcolor}"/>
  <embed
     src="/flash/clippy.swf"
     width="110"
     height="14"
     name="clippy"
     quality="high"
     allowScriptAccess="always"
     type="application/x-shockwave-flash"
     pluginspage="http://www.macromedia.com/go/getflashplayer"
     FlashVars="text=#{text}"
     bgcolor="#{bgcolor}"/>
</object>

อย่าลืมแทนที่#{text}ด้วยข้อความที่คุณต้องการคัดลอกและ#{bgcolor}มีสี


12
สำหรับผู้ที่สนใจให้ตรวจสอบ Clippy ที่ใช้ใน GitHub เมื่อคัดลอก URL สำหรับ repo
Radek

66
FYI การใช้ Clippy บน GitHub นั้นถูกแทนที่ด้วย ZeroClipboard
James M. Greene

219
OP ต้องการโซลูชันใน JavaScript ไม่กะพริบ
มอนแทนา

21
@MT โดย "javascript" บางคนหมายถึง "ในเบราว์เซอร์ไคลเอนต์" ดังนั้นในขณะที่ JS-only อาจเป็นข้อกำหนด แต่หลายคนที่มีโอกาสได้รับคำตอบนี้กำลังมองหา JS หรือสนับสนุนอย่างกว้างขวางจริงๆ - ลูกค้าที่มีเทคโนโลยี Flash ไม่สามารถใช้งานได้กับทุกแพลตฟอร์ม แต่สำหรับฟีเจอร์ขัดเงาเช่นการรองรับคลิปบอร์ดมันควรจะเพิ่มถ้ามันช่วยปรับปรุง UX ผ่านกล่องโต้ตอบป๊อปอัพ
Dave Dopson

13
ถึงตอนนี้การใช้ Flash หมายถึงการมีสิ่งต่าง ๆ ที่ไม่ได้ผลกับผู้เยี่ยมชมไซต์ที่ไม่สามารถยอมรับได้กับเกือบทุกคนที่ทำการพัฒนาเว็บไซต์
jinglesthula

86

การอ่านและแก้ไขคลิปบอร์ดจากหน้าเว็บจะเพิ่มความปลอดภัยและความเป็นส่วนตัว อย่างไรก็ตามใน Internet Explorer เป็นไปได้ที่จะทำ ฉันพบตัวอย่างข้อมูลนี้ :

    <script type="text/javascript">
        function select_all(obj) {
            var text_val=eval(obj);
            text_val.focus();
            text_val.select();
            r = text_val.createTextRange();
            if (!r.execCommand) return; // feature detection
            r.execCommand('copy');
        }
    </script>
    <input value="http://www.sajithmr.com"
     onclick="select_all(this)" name="url" type="text" />


7
การใช้แฟลชสำหรับการทำสำเนาอย่างง่ายดูเหมือนว่าเกินความจริงดีใจที่มีวิธีการแบบ JS ที่สะอาดในการทำเช่นนี้ และเนื่องจากเราอยู่ในองค์กร env IE ก็ใช้ได้ ขอบคุณ Bandi!
Eddie

5
ได้โปรดอธิบายสิ่งที่execCommand(\\’copy\\’);ถ้าไม่คัดลอกไปยังคลิปบอร์ดสำหรับ IE? @mrBorna
RozzA

20
อย่าใช้if(!document.all)แต่if(!r.execCommand)เกรงว่าจะมีคนอื่นใช้! Document.all ไม่เกี่ยวข้องกับสิ่งนี้อย่างแน่นอน
m93a

1
ผู้ชายนี่คือสิ่งที่ฉันชอบเกี่ยวกับรหัสที่เรียบง่ายและสะอาดตามันทำงานได้เกือบตลอดไปด้วยการบำรุงรักษาเล็กน้อย มันทำเพื่อฉันมันทำงานได้อย่างสวยงาม
ซามูเอล Ramzan

1
ไม่ทำงานใน chrome, firefox หรือ MS Edge ล่าสุด :(
Jonathan Marzullo

69

ฉันเพิ่งเขียนโพสต์บล็อกทางเทคนิคเกี่ยวกับปัญหานี้มาก (ฉันทำงานที่ Lucidchart และเมื่อเร็ว ๆ นี้เราได้ทำการยกเครื่องบนคลิปบอร์ดของเรา)

การคัดลอกข้อความธรรมดาไปยังคลิปบอร์ดนั้นค่อนข้างง่ายสมมติว่าคุณต้องการทำในระหว่างการคัดลอกระบบ (ผู้ใช้กดCtrlCหรือใช้เมนูของเบราว์เซอร์)

var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 
           || navigator.userAgent.toLowerCase().indexOf("trident") != -1);

document.addEventListener('copy', function(e) {
    var textToPutOnClipboard = "This is some text";
    if (isIe) {
        window.clipboardData.setData('Text', textToPutOnClipboard);    
    } else {
        e.clipboardData.setData('text/plain', textToPutOnClipboard);
    }
    e.preventDefault();
});

การวางข้อความไว้บนคลิปบอร์ดไม่ใช่ระหว่างการคัดลอกเหตุการณ์ระบบนั้นยากกว่ามาก ดูเหมือนว่าบางส่วนของวิธีการอ้างอิงคำตอบอื่น ๆ ที่จะทำผ่าน Flash ซึ่งเป็นวิธีข้ามเบราว์เซอร์เดียวที่จะทำ (เท่าที่ฉันเข้าใจ)

นอกจากนั้นยังมีตัวเลือกบางตัวบนพื้นฐานของเบราว์เซอร์

นี่เป็นวิธีที่ง่ายที่สุดใน IE ซึ่งคุณสามารถเข้าถึงวัตถุคลิปบอร์ดข้อมูลได้ทุกเวลาจาก JavaScript ผ่านทาง:

window.clipboardData

(เมื่อคุณพยายามทำสิ่งนี้นอกระบบตัดคัดลอกหรือวางเหตุการณ์อย่างไรก็ตาม IE จะแจ้งให้ผู้ใช้อนุญาตการอนุญาตให้ใช้คลิปบอร์ดของเว็บแอปพลิเคชัน)

ใน Chrome คุณสามารถสร้างส่วนขยาย Chrome ที่จะให้สิทธิ์คลิปบอร์ดแก่คุณ(นี่คือสิ่งที่เราทำเพื่อ Lucidchart) จากนั้นสำหรับผู้ใช้ที่ติดตั้งส่วนขยายของคุณคุณจะต้องเริ่มการทำงานของระบบด้วยตนเอง:

document.execCommand('copy');

ดูเหมือนว่า Firefox จะมีตัวเลือกบางอย่างที่อนุญาตให้ผู้ใช้อนุญาตให้บางไซต์เข้าถึงคลิปบอร์ดได้ แต่ฉันไม่ได้ลองใช้สิ่งเหล่านี้เป็นการส่วนตัว


2
ไม่ได้กล่าวถึงในโพสต์บล็อก (ฉันหวังว่าจะอัปเดตในอนาคตอันใกล้) เป็นความสามารถในการทริกเกอร์ตัดและคัดลอกโดยใช้ execCommand รองรับ IE10 +, Chrome 43+ และ Opera29 + อ่านเกี่ยวกับที่นี่ updates.html5rocks.com/2015/04/cut-and-copy- คำสั่ง
Richard Shurtz

ปัญหาเกี่ยวกับสิ่งนี้คือมันไฮแจ็คเหตุการณ์การคัดลอกปกติอื่น ๆ
Brock Adams

NB! การสูดดมเบราว์เซอร์นี้ไม่ดี อย่าดมกลิ่นคุณสมบัติ คุณกำลังทำให้เป็นเรื่องยากสำหรับ IE ที่จะอัปเดต
odinho - Velmont

51

clipboard.jsเป็นยูทิลิตี้ขนาดเล็กที่ไม่ใช่ Flash ที่อนุญาตให้คัดลอกข้อความหรือข้อมูล HTML ไปยังคลิปบอร์ด มันใช้งานง่ายมากเพียงแค่รวม. js และใช้สิ่งนี้:

<button id='markup-copy'>Copy Button</button>

<script>
document.getElementById('markup-copy').addEventListener('click', function() {
  clipboard.copy({
    'text/plain': 'Markup text. Paste me into a rich text editor.',
    'text/html': '<i>here</i> is some <b>rich text</b>'
  }).then(
    function(){console.log('success'); },
    function(err){console.log('failure', err);
  });

});
</script>

clipboard.js ก็ใช้GitHubเช่นกัน

หมายเหตุ:นี่เลิกใช้แล้วตอนนี้ โยกย้ายไปที่นี่


ไลบรารีนี้ถูกใช้โดย angular.io สำหรับ Tour of Hero และ fallback ในโหมดที่เหมาะสมสำหรับเบราว์เซอร์ที่ไม่สนับสนุน execCommand โดยการแสดงข้อความที่เลือกไว้ล่วงหน้าที่ผู้ใช้มีเพียงเพื่อคัดลอก
John-Philip

1
ดูเหมือน clipboard.js ถูกแทนที่หรือถูกแยก แต่ดูเหมือนว่าจะมีชีวิตอยู่และได้รับการบำรุงรักษาอย่างแข็งขันที่npmjs.com/package/clipboard
Joao

35

ZeroClipboard เป็นโซลูชันข้ามเบราว์เซอร์ที่ดีที่สุดที่ฉันเคยพบ:

<div id="copy" data-clipboard-text="Copy Me!">Click to copy</div>    
<script src="ZeroClipboard.js"></script>
<script>
  var clip = new ZeroClipboard( document.getElementById('copy') );
</script>

หากคุณต้องการการสนับสนุนที่ไม่ใช่แฟลชสำหรับ iOS คุณเพียงแค่เพิ่มการถอยกลับ:

clip.on( 'noflash', function ( client, args ) {
    $("#copy").click(function(){            
        var txt = $(this).attr('data-clipboard-text');
        prompt ("Copy link, then click OK.", txt);
    });
});  

http://zeroclipboard.org/

https://github.com/zeroclipboard/ZeroClipboard


25
ข้ามเบราว์เซอร์พร้อม Flash หรือไม่ ไม่ทำงานใน iOS และ Android 4.4
Raptor

1
ดูคำตอบที่อัปเดต วิธีนี้ช่วยให้ขั้นตอนน้อยลงสำหรับผู้ใช้แฟลชและถอยกลับสำหรับคนอื่น ๆ
Justin

8
มันมีรหัสพันล้านบรรทัด มันเยาะเย้ยอย่างแน่นอน ดีกว่าที่จะไม่ทำมันเลยรวมทั้งสัตว์ประหลาดในโครงการด้วย
vsync

2
มีรุ่นง่าย ๆgist.github.com/JamesMGreene/8698897ที่มี 20K ที่ไม่มีระฆังและนกหวีดทั้งหมดในรุ่น 74k ไม่ใหญ่มาก ฉันเดาว่าผู้ใช้ส่วนใหญ่ไม่เป็นไรด้วยมิลลิวินาทีพิเศษที่มีการดาวน์โหลดไฟล์ 74k หรือ 20k เพื่อคัดลอก / วางเป็นการคลิกครั้งเดียวแทนที่จะเป็นสองคลิก
Justin

@ จัสตินฉันไม่สามารถทำงานในพื้นที่แม้ว่าฉันจะคัดลอกและวางตัวอย่าง (ฉันทำการเปลี่ยนแปลงขั้นต่ำเช่นค่าของsrcในแท็กสคริปต์) ฉันรู้สึกว่าเอกสารของพวกเขาสวย แต่ไม่มีประสิทธิภาพ
Gui Imamura

29

ในปี 2018 นี่เป็นวิธีที่คุณสามารถทำได้:

async copySomething(text?) {
  try {
    const toCopy = text || location.href;
    await navigator.clipboard.writeText(toCopy);
    console.log('Text or Page URL copied');
  }
  catch (err) {
    console.error('Failed to copy: ', err);
  }
}

มันถูกใช้ในโค้ด Angular 6+ ของฉันเช่น:

<button mat-menu-item (click)="copySomething()">
    <span>Copy link</span>
</button>

ถ้าฉันผ่านเป็นสตริงมันจะคัดลอก หากไม่มีอะไรจะคัดลอก URL ของหน้า

ยิมนาสติกเพิ่มเติมไปยังสิ่งที่คลิปบอร์ดสามารถทำได้เช่นกัน ดูข้อมูลเพิ่มเติมได้ที่นี่:

เลิกบล็อกการเข้าถึงคลิปบอร์ด


คุณได้เชื่อมโยงกับ localhost
Joe Warner

2
โปรดทราบว่าวิธีนี้ใช้ไม่ได้กับ Safari (เวอร์ชัน 11.1.2)
arjun27

1
@ arjun27 หวังว่าสักวันหนึ่ง Apple จะตามทัน แม้ว่าcaniuse.com/#feat=clipboardนี้จะแสดงเวอร์ชันข้างต้นที่คุณกล่าวถึงว่าได้รับการสนับสนุนบางส่วน
KhopPhi

2
ฉันได้รับสำหรับการทำงานทั้ง readText, WRITETEXT สัญญาในการปฏิเสธรัฐ
ramin

3
ตามลิงค์ที่ให้ไว้ "navigator.clipboard รองรับเฉพาะหน้าที่แสดงผ่าน HTTPS"
TimH - Codidact

26

จากหนึ่งในโครงการที่ฉันได้ทำไปแล้วปลั๊กอินของ jQuery copy-to-clipboard ที่ใช้ไลบรารี่ Zero Clipboard

จะใช้งานง่ายกว่าปลั๊กอิน Zero Clipboard ธรรมดาหากคุณเป็นผู้ใช้ jQuery ที่หนักหน่วง


6
92kb ไม่ได้ใหญ่ขนาดนั้นเลยใช้งานได้อย่างรวดเร็ว & คุณสามารถใช้text()แทนได้innerHTML()ถ้าคุณชอบ ..
RozzA

17
@John: innerHTMLได้รับการสนับสนุนข้ามเบราว์เซอร์เป็นเวลานานแล้ว เพียงเพราะ Microsoft มาพร้อมกับความคิดมันไม่ได้ทำให้มันไม่น่าเชื่อถือหรือเป็นกรรมสิทธิ์ ในที่สุดมันก็ถูกเพิ่มลงในสเป็คอย่างเป็นทางการในที่สุด (หลังจากผู้ขายเบราว์เซอร์รายใหญ่ทุกรายได้เพิ่มการสนับสนุนแล้ว ... ถอนหายใจ )
James M. Greene

19
@John คุณบ่นเกี่ยวกับ jQuery ว่าไม่เป็นจาวาสคริปต์เพียงพอในคำตอบที่ใช้ Flash;)
Max Nanasy

4
innerHTML ดีกว่าทางเลือกในกรณีส่วนใหญ่ ลงจากม้าสูงของคุณ! มันเร็วกว่ามีประสิทธิภาพมากขึ้นและไม่ต้องการการแสดงผลหน้าซ้ำ
โคจรรอบอีเดน

4
@RozzA 92KBใหญ่มาก จนกระทั่งLTE matures GPRSเป็นมาตรฐานข้อมูลมือถือ WW1 KB/sและมันเริ่มต้นที่ ทำคณิตศาสตร์ด้วยตัวเอง
Tino

23

ขณะนี้ Chrome 42+ และ Firefox 41+ รองรับคำสั่งdocument.execCommand ('copy') ดังนั้นฉันจึงสร้างฟังก์ชั่นสองสามอย่างสำหรับความสามารถในการคัดลอกไปยังคลิปบอร์ดข้ามเบราว์เซอร์โดยใช้การรวมกันของคำตอบเก่าของTim Downและคำตอบของ Google Developer :

function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // IE
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
        textRange.execCommand("Copy");
    } 
    else if (window.getSelection && document.createRange) {
        // Non-Internet Explorer
        var range = document.createRange();
        range.selectNodeContents(el);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copy command was ' + msg);
        }
        catch (err) {
            console.log('Oops, unable to copy');
        }
    }
} // end function selectElementContents(el)

function make_copy_button(el) {
    var copy_btn = document.createElement('input');
    copy_btn.type = "button";
    el.parentNode.insertBefore(copy_btn, el.nextSibling);
    copy_btn.onclick = function() {
        selectElementContents(el);
    };

    if (document.queryCommandSupported("copy") || parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 42) {
        // Copy works with Internet Explorer 4+, Chrome 42+, Firefox 41+, Opera 29+
        copy_btn.value = "Copy to Clipboard";
    }
    else {
        // Select only for Safari and older Chrome, Firefox and Opera
        copy_btn.value = "Select All (then press Ctrl + C to Copy)";
    }
}
/* Note: document.queryCommandSupported("copy") should return "true" on browsers that support copy
    but there was a bug in Chrome versions 42 to 47 that makes it return "false".  So in those
    versions of Chrome feature detection does not work!
    See https://code.google.com/p/chromium/issues/detail?id=476508
*/

make_copy_button(document.getElementById("markup"));
<pre id="markup">
  Text that can be copied or selected with cross browser support.
</pre>


ขอบคุณที่สรุปสิ่งนี้! คุณมีข้อผิดพลาดเล็กน้อยในรหัสของคุณ: คุณกำหนดตัวแปร "ช่วง" สองครั้ง (var range = document.createRange ())
Christian Engel

1
คุณถูกต้อง @ChristianEngel ฉันได้ลบอันที่สอง ฉันไม่รู้ว่ามันมีอยู่ในนั้นได้อย่างไร
เจฟฟ์เบเกอร์

23

ฉันใช้สิ่งนี้สำเร็จมาก ( โดยไม่มี jQuery หรือกรอบงานอื่น ๆ )

function copyToClp(txt){
    txt = document.createTextNode(txt);
    var m = document;
    var w = window;
    var b = m.body;
    b.appendChild(txt);
    if (b.createTextRange) {
        var d = b.createTextRange();
        d.moveToElementText(txt);
        d.select();
        m.execCommand('copy');
    } 
    else {
        var d = m.createRange();
        var g = w.getSelection;
        d.selectNodeContents(txt);
        g().removeAllRanges();
        g().addRange(d);
        m.execCommand('copy');
        g().removeAllRanges();
    }
    txt.remove();
}

คำเตือน

แท็บถูกแปลงเป็นช่องว่าง (อย่างน้อยใน Chrome)


ช่องว่างหายไปในวิธีการนี้
Bikram

1
โครเมียม. แท็บถูกแปลงเป็นหนึ่งช่องว่าง
Bikram

22

ฉันพบวิธีแก้ไขปัญหาต่อไปนี้:

เมื่อกดปุ่มตัวจัดการจะสร้างแท็ก "ล่วงหน้า" เราตั้งค่าเนื้อหาให้คัดลอกไปที่แท็กนี้จากนั้นทำการเลือกบนแท็กนี้และคืนค่าจริงในตัวจัดการ สิ่งนี้เรียกตัวจัดการมาตรฐานของโครเมี่ยมและคัดลอกข้อความที่เลือก

และหากคุณต้องการคุณอาจตั้งค่าการหมดเวลาสำหรับฟังก์ชั่นสำหรับการกู้คืนการเลือกก่อนหน้า การใช้งานของฉันใน Mootools:

   function EnybyClipboard() {
     this.saveSelection = false;
     this.callback = false;
     this.pastedText = false;

     this.restoreSelection = function() {
       if (this.saveSelection) {
         window.getSelection().removeAllRanges();
         for (var i = 0; i < this.saveSelection.length; i++) {
           window.getSelection().addRange(this.saveSelection[i]);
         }
         this.saveSelection = false;
       }
     };

     this.copyText = function(text) {
       var div = $('special_copy');
       if (!div) {
         div = new Element('pre', {
           'id': 'special_copy',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
       }
       div.set('text', text);
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         setTimeout(this.restoreSelection.bind(this), 100);
       } else return alert('Copy not work. :(');
     };

     this.getPastedText = function() {
       if (!this.pastedText) alert('Nothing to paste. :(');
       return this.pastedText;
     };

     this.pasteText = function(callback) {
       var div = $('special_paste');
       if (!div) {
         div = new Element('textarea', {
           'id': 'special_paste',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
         div.addEvent('keyup', function() {
           if (this.callback) {
             this.pastedText = $('special_paste').get('value');
             this.callback.call(null, this.pastedText);
             this.callback = false;
             this.pastedText = false;
             setTimeout(this.restoreSelection.bind(this), 100);
           }
         }.bind(this));
       }
       div.set('value', '');
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         div.focus();
         this.callback = callback;
       } else return alert('Fail to paste. :(');
     };
   }

การใช้งาน:

enyby_clip = new EnybyClipboard(); //init 

enyby_clip.copyText('some_text'); // place this in CTRL+C handler and return true;

enyby_clip.pasteText(function callback(pasted_text) {
        alert(pasted_text);
}); // place this in CTRL+V handler and return true;

เมื่อวางมันจะสร้าง textarea และทำงานในลักษณะเดียวกัน

PS อาจเป็นโซลูชันนี้สามารถใช้สำหรับการสร้างโซลูชันข้ามเบราว์เซอร์อย่างสมบูรณ์โดยไม่ใช้แฟลช มันใช้งานได้ใน FF และ Chrome


2
มีใครลองบ้างไหม? ดูเหมือนสิ่งที่ดีในกรณีที่ใช้งานได้จริงกับเบราว์เซอร์ที่หลากหลาย!
ไมเคิล

1
jsfiddle.net/H2FHC Demo: fiddle.jshell.net/H2FHC/showโปรดเปิดแล้วกด Ctrl + V หรือ Ctrl + C ใน FF 19.0 ส้อมได้อย่างสมบูรณ์แบบ ใน Chrome 25.0.1364.97 m ด้วย โอเปร่า 12.14 - ตกลง Safari 5.1.7 สำหรับ Windows - OK IE - FAIL
Enyby

สำหรับ IE ต้องเรียกใช้การมุ่งเน้นองค์ประกอบภายในหน้า ดูfiddle.jshell.net/H2FHC/3/showและfiddle.jshell.net/H2FHC/3ทำงานใน IE 9/10 IE 6/7 ต้องการกระบวนการสร้างการเลือกในวิธีอื่นเนื่องจากไม่รองรับ document.createRange
Enyby

21

วิธีอื่นจะคัดลอกข้อความธรรมดาไปยังคลิปบอร์ด ในการคัดลอก HTML (เช่นคุณสามารถวางผลลงในตัวแก้ไข WSIWYG) คุณสามารถทำต่อไปนี้ในIE เท่านั้น วิธีนี้แตกต่างจากวิธีอื่น ๆ อย่างแท้จริงเนื่องจากเบราว์เซอร์เลือกเนื้อหาอย่างชัดเจน

// create an editable DIV and append the HTML content you want copied
var editableDiv = document.createElement("div");
with (editableDiv) {
    contentEditable = true;
}     
editableDiv.appendChild(someContentElement);          

// select the editable content and copy it to the clipboard
var r = document.body.createTextRange();
r.moveToElementText(editableDiv);
r.select();  
r.execCommand("Copy");

// deselect, so the browser doesn't leave the element visibly selected
r.moveToElementText(someHiddenDiv);
r.select();   

ดูโซลูชัน HTML ที่สมบูรณ์เพิ่มเติมได้ที่นี่stackoverflow.com/questions/34191780/…
kofifus

21

ฉันรวบรวมสิ่งที่ฉันคิดว่าดีที่สุด

  • ใช้ cssText เพื่อหลีกเลี่ยงข้อยกเว้นใน Internet Explorer ซึ่งต่างกับสไตล์โดยตรง
  • กู้คืนสิ่งที่เลือกถ้ามี
  • ตั้งค่าแบบอ่านอย่างเดียวเพื่อไม่ให้คีย์บอร์ดปรากฏขึ้นบนอุปกรณ์พกพา
  • มีวิธีแก้ปัญหาสำหรับ iOS เพื่อให้ใช้งานได้จริงเพราะปกติจะบล็อก execCommand

นี่มันคือ:

const copyToClipboard = (function initClipboardText() {
  const textarea = document.createElement('textarea');

  // Move it off screen.
  textarea.style.cssText = 'position: absolute; left: -99999em';

  // Set to readonly to prevent mobile devices opening a keyboard when
  // text is .select()'ed.
  textarea.setAttribute('readonly', true);

  document.body.appendChild(textarea);

  return function setClipboardText(text) {
    textarea.value = text;

    // Check if there is any content selected previously.
    const selected = document.getSelection().rangeCount > 0 ?
      document.getSelection().getRangeAt(0) : false;

    // iOS Safari blocks programmtic execCommand copying normally, without this hack.
    // /programming/34045777/copy-to-clipboard-using-javascript-in-ios
    if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
      const editable = textarea.contentEditable;
      textarea.contentEditable = true;
      const range = document.createRange();
      range.selectNodeContents(textarea);
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
      textarea.setSelectionRange(0, 999999);
      textarea.contentEditable = editable;
    }
    else {
      textarea.select();
    }

    try {
      const result = document.execCommand('copy');

      // Restore previous selection.
      if (selected) {
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(selected);
      }

      return result;
    }
    catch (err) {
      console.error(err);
      return false;
    }
  };
})();

การใช้งาน: copyToClipboard('some text')


13

ในฐานะของ Flash 10 คุณสามารถคัดลอกไปยังคลิปบอร์ดได้หากการกระทำนั้นมาจากการโต้ตอบของผู้ใช้กับวัตถุ Flash ( อ่านส่วนที่เกี่ยวข้องจากการประกาศ Flash 10 ของ Adobe )

การแก้ปัญหาคือการใช้วัตถุแฟลชด้านบนปุ่มคัดลอกหรือองค์ประกอบใด ๆ ที่เริ่มต้นการคัดลอก ปัจจุบัน Zero Clipboard เป็นห้องสมุดที่ดีที่สุดในการติดตั้ง นักพัฒนาซอฟต์แวร์ที่มีประสบการณ์อาจต้องการสร้างห้องสมุดของตนเอง


12

  <!DOCTYPE html>

  <style>
    #t {
      width: 1px
      height: 1px
      border: none
    }
    #t:focus {
      outline: none
    }
  </style>

  <script>
    function copy(text) {
      var t = document.getElementById('t')
      t.innerHTML = text
      t.select()
      try {
        var successful = document.execCommand('copy')
        var msg = successful ? 'successfully' : 'unsuccessfully'
        console.log('text coppied ' + msg)
      } catch (err) {
        console.log('Unable to copy text')
      }
      t.innerHTML = ''
    }
  </script>

  <textarea id=t></textarea>

  <button onclick="copy('hello world')">
    Click me
  </button>


คำตอบที่ดีที่สุด: D คุณสามารถปรับปรุงด้วยสิ่งนี้: #t {position: absolute; ซ้าย: 0; ดัชนี z: -900; ความกว้าง: 0px; ความสูง: 0px; เส้นขอบ: ไม่มี; } ดังนั้นมันจะถูกซ่อนไว้อย่างสมบูรณ์! แต่ขอบคุณจริงๆ!
Federico Navarrete

#t {ปรับขนาด: ไม่มี;}
SmartManoj

คำอธิบายจะอยู่ในลำดับ
ปีเตอร์มอร์เทนเซ่น

12

ฉันพบวิธีแก้ไขปัญหาต่อไปนี้:

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

jQuery('#copy').on('click', function () {
    copyToClipboard();
});

function copyToClipboard() {
    var target = jQuery('#hidden_text');

    // Make it visible, so can be focused
    target.attr('type', 'text');
    target.focus();
    // Select all the text
    target[0].setSelectionRange(0, target.val().length);

    // Copy the selection
    var succeed;
    try {
        succeed = document.execCommand("copy");
    }
    catch (e) {
        succeed = false;
    }

    // Hide input again
    target.attr('type', 'hidden');

    return succeed;
}

11

คัดลอกข้อความจากอินพุต HTML ไปยังคลิปบอร์ด:

 function myFunction() {
   /* Get the text field */
   var copyText = document.getElementById("myInput");

   /* Select the text field */
   copyText.select();

   /* Copy the text inside the text field */
   document.execCommand("Copy");

   /* Alert the copied text */
   alert("Copied the text: " + copyText.value);
 }
 <!-- The text field -->
 <input type="text" value="Hello Friend" id="myInput">

 <!-- The button used to copy the text -->
<button onclick="myFunction()">Copy text</button>

หมายเหตุ: วิธีการไม่ได้รับการสนับสนุนใน Internet Explorer 9 และก่อนหน้านี้document.execCommand()

ที่มา : W3Schools - คัดลอกข้อความไปยังคลิปบอร์ด


11

มีคำตอบมากมายอยู่แล้ว แต่ต้องการเพิ่ม (jQuery) ใช้งานได้ดีบนเบราว์เซอร์ใด ๆ รวมถึงมือถือ (เช่นแจ้งเตือนเกี่ยวกับความปลอดภัย แต่เมื่อคุณยอมรับมันก็ใช้ได้ดี)

function appCopyToClipBoard(sText)
{
    var oText = false,
        bResult = false;
    try
    {
        oText = document.createElement("textarea");
        $(oText).addClass('clipboardCopier').val(sText).insertAfter('body').focus();
        oText.select();
        document.execCommand("Copy");
        bResult = true;
    }
    catch(e) {
    }

    $(oText).remove();
    return bResult;
}

ในรหัสของคุณ:

if (!appCopyToClipBoard('Hai there! This is copied to the clipboard.'))
{
    alert('Sorry, copy to clipboard failed.');
}

9

นี่เป็นการผสมผสานระหว่างคำตอบอื่น ๆ

var copyToClipboard = function(textToCopy){
    $("body")
        .append($('<textarea name="fname" class="textToCopyInput"/>' )
        .val(textToCopy))
        .find(".textToCopyInput")
        .select();
      try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        alert('Text copied to clipboard!');
      } catch (err) {
          window.prompt("To copy the text to clipboard: Ctrl+C, Enter", textToCopy);
      }
     $(".textToCopyInput").remove();
}

มันใช้ jQuery แต่ก็ไม่จำเป็นต้องแน่นอน คุณสามารถเปลี่ยนได้ถ้าคุณต้องการ ฉันเพิ่งมี jQuery เพื่อกำจัดของฉัน คุณสามารถเพิ่ม CSS เพื่อให้แน่ใจว่าข้อมูลไม่แสดง ยกตัวอย่างเช่น:

.textToCopyInput{opacity: 0; position: absolute;}

หรือแน่นอนคุณสามารถทำสไตล์อินไลน์ได้

.append($('<textarea name="fname" style="opacity: 0;  position: absolute;" class="textToCopyInput"/>' )

วิธีการคัดลอกโดยตรงจากข้อมูลตัวแปร. i: var str = "word"; ?

ข้อความ msg ไม่ถูกใช้งาน
Voyager

ควรใช้ '<textarea class = "textToCopyInput" /> </textarea>' ในกรณีที่textToCopyมี\n
Voyager

8

ในเบราว์เซอร์อื่นที่ไม่ใช่ IE คุณต้องใช้วัตถุแฟลชขนาดเล็กเพื่อจัดการคลิปบอร์ดเช่น


นี่ล้าสมัยแล้ว ... ตรวจสอบข้อเสนอแนะโดย GvS
Mottie

6
ข้อเสนอแนะโดย GvS ใช้แฟลชภาพยนตร์? นั่นไม่ใช่ความคิดเดียวกันหรือ
TheEmirOfGroofunkistan

8

ฉันมีปัญหาเดียวกันกับการสร้างกริดแบบกำหนดเองจาก (เช่น Excel) และความเข้ากันได้กับ Excel ฉันต้องสนับสนุนการเลือกหลายเซลล์คัดลอกและวาง

การแก้ไข: สร้าง textarea ที่คุณจะใส่ข้อมูลเพื่อให้ผู้ใช้คัดลอก (สำหรับฉันเมื่อผู้ใช้เลือกเซลล์) ตั้งโฟกัสไว้ (ตัวอย่างเช่นเมื่อผู้ใช้กด Ctrl ) และเลือกข้อความทั้งหมด

ดังนั้นเมื่อผู้ใช้กดCtrl+Cเขา / เธอจะได้รับการคัดลอกเซลล์เขา / เธอเลือก หลังจากการทดสอบปรับขนาด textarea เป็นหนึ่งพิกเซล (ฉันไม่ได้ทดสอบว่าจะใช้งานได้บนจอแสดงผล: ไม่มี) มันทำงานได้ดีบนเบราว์เซอร์ทั้งหมดและโปร่งใสต่อผู้ใช้

การวาง - คุณสามารถทำสิ่งนี้ได้เหมือนกัน (แตกต่างกับเป้าหมายของคุณ) - ให้ความสำคัญกับ textarea และจับวางเหตุการณ์โดยใช้ onpaste (ในโครงการของฉันฉันใช้ textareas ในเซลล์เพื่อแก้ไข)

ฉันไม่สามารถวางตัวอย่าง (โครงการเชิงพาณิชย์) แต่คุณเข้าใจ


7

ฉันใช้ clipboard.js

เราสามารถรับได้ในเวลา 23.00 น.:

npm install clipboard --save

และบนBower

bower install clipboard --save

การใช้งานและตัวอย่างที่https://zenorocha.github.io/clipboard.js/


ฉันกลัวว่ามันเข้ากันไม่ได้กับเนื้อหาแบบไดนามิก แต่มันเป็น ;-) ฉันคิดว่ามันเป็นทางออกที่ดีกว่าตอนนี้เก่ากว่าปี 2008
BENARD Patrick


6

นี่เป็นการขยายคำตอบของ @ Chase โดยมีข้อได้เปรียบที่จะทำงานกับองค์ประกอบ IMAGE และ TABLE ไม่ใช่เพียง DIV บน IE9

if (document.createRange) {
    // IE9 and modern browsers
    var r = document.createRange();
    r.setStartBefore(to_copy);
    r.setEndAfter(to_copy);
    r.selectNode(to_copy);
    var sel = window.getSelection();
    sel.addRange(r);
    document.execCommand('Copy');  // does nothing on FF
} else {
    // IE 8 and earlier.  This stuff won't work on IE9.
    // (unless forced into a backward compatibility mode,
    // or selecting plain divs, not img or table). 
    var r = document.body.createTextRange();
    r.moveToElementText(to_copy);
    r.select()
    r.execCommand('Copy');
}

5

ดูเหมือนว่าฉันจะอ่านคำถามผิด แต่สำหรับการอ้างอิงคุณสามารถแยกช่วงของ DOM (ไม่ไปที่คลิปบอร์ดเข้ากันได้กับเบราว์เซอร์ที่ทันสมัยทั้งหมด) และรวมเข้ากับเหตุการณ์ oncopy และ onpaste และ onbeforepaste เพื่อรับพฤติกรรมคลิปบอร์ด นี่คือรหัสเพื่อให้บรรลุสิ่งนี้:

function clipBoard(sCommand) {
  var oRange=contentDocument.createRange();
  oRange.setStart(startNode, startOffset);
  oRange.setEnd(endNode, endOffset);
/* This is where the actual selection happens.
in the above, startNode and endNode are dom nodes defining the beginning 
and end of the "selection" respectively. startOffset and endOffset are 
constants that are defined as follows:

END_TO_END: 2
END_TO_START: 3
NODE_AFTER: 1
NODE_BEFORE: 0
NODE_BEFORE_AND_AFTER: 2
NODE_INSIDE: 3
START_TO_END: 1
START_TO_START: 0

and would be used like oRange.START_TO_END */
      switch(sCommand) {
    case "cut":
          this.oFragment=oRange.extractContents();
      oRange.collapse();
      break;
    case "copy":
      this.oFragment=oRange.cloneContents();
      break;
    case "paste":
      oRange.deleteContents();
      var cloneFragment=this.oFragment.cloneNode(true)
      oRange.insertNode(cloneFragment);
      oRange.collapse();
      break;
  }
}

1
ที่จริงฉันแก้ไขรหัสแล้ว ใช้ได้กับทุกเบราว์เซอร์ แต่ไม่ได้คัดลอกไปยังคลิปบอร์ด เพียงแยก (ตัด), โคลน (คัดลอก) เนื้อหาผ่านตัวแปร ดูเหมือนว่าฉันจะลืมการใช้งาน
mrBorna

5

ความผิดฉันเอง. ใช้งานได้ใน IE เท่านั้น

นี่เป็นอีกวิธีคัดลอกข้อความ:

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>

9
สิ่งนี้ไม่ทำงานใน Chrome ปัจจุบัน (V31) หรือ FireFox (v25) ข้อผิดพลาดคือ window.clipboardData นั้นไม่ได้กำหนดไว้ ในด้านบวกมันใช้งานได้ใน IE9 ดังนั้นตราบใดที่คุณไม่สนใจเบราว์เซอร์ที่ดีและต้องการล็อคเว็บไซต์ของคุณให้ใช้เบราว์เซอร์ที่ไม่ดีนี่เป็นวิธีที่คุณจะทำได้!
แอนโธนี

2
ฉันไม่เข้าใจว่าทำไมคำตอบโง่ ๆ มากมาย w3schools.com/howto/tryit.asp?filename=tryhow_js_copy_clipboard
Martian2049

5

นี่เป็นสิ่งเดียวที่ฉันเคยทำงานหลังจากค้นหาวิธีต่าง ๆ ทั่วอินเทอร์เน็ต นี่เป็นหัวข้อที่ยุ่งเหยิง มีวิธีแก้ไขปัญหามากมายที่โพสต์ทั่วโลกและส่วนใหญ่ไม่ได้ผล สิ่งนี้ใช้ได้กับฉัน:

หมายเหตุ: รหัสนี้จะใช้ได้เฉพาะเมื่อเรียกใช้เป็นรหัสซิงโครนัสโดยตรงกับบางสิ่งเช่นวิธีการ 'onClick' ถ้าคุณโทรในการตอบสนองแบบอะซิงโครนัสกับ Ajax หรือด้วยวิธีอะซิงโครนัสอื่น ๆ มันจะไม่ทำงาน

copyToClipboard(text) {
    var copyText = document.createElement("input");
    copyText.type = "text";
    document.body.appendChild(copyText);
    copyText.style = "display: inline; width: 1px;";
    copyText.value = text;
    copyText.focus();
    document.execCommand("SelectAll");
    document.execCommand("Copy");
    copyText.remove();
}

ฉันรู้ว่ารหัสนี้จะแสดงส่วนประกอบกว้าง 1 พิกเซลอย่างเห็นได้ชัดบนหน้าจอเป็นมิลลิวินาที แต่ตัดสินใจที่จะไม่กังวลเกี่ยวกับเรื่องนี้ซึ่งเป็นสิ่งที่คนอื่นสามารถแก้ไขได้หากเป็นปัญหาจริง


5

ในการคัดลอกข้อความที่เลือก ('คัดลอกข้อความไปยัง') ไปยังคลิปบอร์ดของคุณสร้าง Bookmarklet (บุ๊กมาร์กของเบราว์เซอร์ที่เรียกใช้ JavaScript) และดำเนินการ (คลิกที่มัน) มันจะสร้าง textarea ชั่วคราว

รหัสจาก GitHub:

https://gist.github.com/stefanmaric/2abf96c740191cda3bc7a8b0fc905a7d

(function (text) {
  var node = document.createElement('textarea');
  var selection = document.getSelection();

  node.textContent = text;
  document.body.appendChild(node);

  selection.removeAllRanges();
  node.select();
  document.execCommand('copy');

  selection.removeAllRanges();
  document.body.removeChild(node);
})('Text To Copy');
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.