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