我如何在 JavaScript 中複製到剪貼簿?
我如何將文字複製到剪貼簿(多瀏覽器)?
相關:Trello 如何存取使用者的剪貼簿?
答案#1
概覽
有三個主要的瀏覽器 API 用於複製到剪貼簿:
非同步剪貼簿 API
[navigator.clipboard.writeText]- Chrome 66(2018 年 3 月)中提供以文字為主的部分
- 存取是非同步的並使用 JavaScript 的 Promise,可以以這種方式撰寫,使安全使用者提示(如果顯示)不會中斷頁面中的 JavaScript。
- 文字可以直接從變數複製到剪貼簿。
- 僅支持透過 HTTPS 提供的頁面。
- 在 Chrome 66 中,非活動標籤頁可以在不出現權限提示的情況下寫入剪貼簿。
document.execCommand('copy')(已棄用) 👎- 截至約 2015 年 4 月,大多數瀏覽器已支持此功能(請參見下方的瀏覽器支持)。
- 存取是同步的,即在完成之前會停止頁面中的 JavaScript,包括顯示和使用者與任何安全提示的互動。
- 文字從 DOM 讀取並放到剪貼簿上。
- 在大約 2015 年 4 月的測試期間,只有 Internet Explorer 在寫入剪貼簿時顯示權限提示。
覆蓋複製事件
- 請參閱剪貼簿 API 文件中有關覆寫複製事件的部分。
- 允許您修改從任何複製事件出現的剪貼簿內容,還可以包括除了純文字以外的其他資料格式。
- 此處未涵蓋,因為它並未直接回答問題。
一般開發筆記
在控制台測試程式碼時,不要期望與剪貼簿相關的指令能正常運作。一般來說,需要頁面處於活躍狀態(非同步剪貼簿 API)或需要使用者互動(例如使用者點擊)來允許 (document.execCommand('copy')) 存取剪貼簿,詳情請見下文。
重要(於此記錄於 2020/02/20)
請注意,由於這篇文章最初撰寫時跨來源 IFRAME 的權限已被棄用,以及其他 IFRAME 「沙盒化」功能,導致嵌入的範例「執行程式碼片段」按鈕和「codepen.io 範例」在某些瀏覽器(包括 Chrome 和 Microsoft Edge)中無法正常運作。
要開發自己的網頁,請通過 HTTPS 連接提供該網頁以進行測試和開發。
這裡有一個測試/示範頁面,展示了代碼的運作情況:https://deanmarktaylor.github.io/clipboard-test/
異步 + 回退
由於新 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
非同步剪貼簿 API
- MDN 參考
- Chrome 66 公告文章(2018 年 3 月)
- 參考非同步剪貼簿 API 草案文件
請注意,在 Chrome 66 中可以透過權限 API 使用「請求權限」功能並測試對剪貼簿的存取權限。
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('copy')
這篇文章的其餘部分將深入探討 document.execCommand('copy') API 的細微差別和細節。
瀏覽器支援
JavaScript (已棄用) 👎document.execCommand('copy') 的支援已增加,請參考以下連結以了解瀏覽器更新:
- Internet Explorer 10 以上(雖然本文檔指出從 Internet Explorer 5.5 以上就有所支持)。
- Google Chrome 43 以上(約 2015 年 4 月)
- Mozilla Firefox 41+(預計出貨時間 ~2015年9月)
- Opera 29+(基於 Chromium 42,大約 2015 年 4 月)
簡單的例子
(可能無法在此網站嵌入使用,請閱讀上方的「重要」說明)
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 the 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 the 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 the 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')如果document.execCommand('copy')現在被呼叫會成功,則返回true。檢查以確保該命令是從使用者啟動的線程呼叫且其他要求已滿足。
然而,作為瀏覽器相容性問題的例子,Google Chrome 在大約 2015 年四月至十月期間,只有當命令從使用者啟動的執行緒呼叫時,document.queryCommandSupported('copy') 才會返回 true。
請注意以下的相容性細節。
瀏覽器相容性詳情
雖然將 document.execCommand('copy') 包裝在 try/catch 區塊中,並在用戶點擊時調用,能獲得最廣泛的兼容性,但使用以下方法有一些限制:
任何對 document.execCommand、document.queryCommandSupported 或 document.queryCommandEnabled 的呼叫都應該包裹在 try/catch 區塊中。
不同的瀏覽器實作和瀏覽器版本在被呼叫時會拋出不同類型的例外,而不是返回 false。
不同的瀏覽器實作仍在變動中,Clipboard API 仍處於草案階段,因此記得進行測試。
答案#2
自動複製到剪貼板可能很危險,因此大多數瀏覽器(除了 Internet Explorer)都讓這件事變得非常困難。就我個人而言,我使用以下簡單的技巧:
function copyToClipboard(text) {
window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
}
使用者會看到提示框,其中要複製的文字已經被選取。現在只需要按下 Ctrl+C 以及 Enter(關閉框)——就完成了!
現在剪貼簿複製操作是安全的,因為使用者是手動執行的(但方法相當簡單直接)。當然,它在所有瀏覽器中都能使用。
<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>答案#3
以下方法適用於 Chrome、Firefox、Internet Explorer 和 Edge,以及 Safari 的最新版本(在 2016 年 10 月發布的第 10 版中新增了複製支持)。
- 建立一個文字區域,並將其內容設為你想複製到剪貼簿的文字。
- 將文本區附加到 DOM。
- 選取文字區域中的文字。
- 呼叫 document.execCommand("copy")
- 從 DOM 中移除 textarea。
注意:你不會看到這個文字區域,因為它是在同一次同步的 Javascript 代碼調用中被添加和移除的。
如果你自己實作這個,有些事情需要注意:
- 出於安全原因,這只能從事件處理程序中調用,例如點擊(就像打開窗口一樣)。
- Internet Explorer 在剪貼簿首次更新時會顯示一個權限對話方塊。
- 當文字區域被聚焦時,Internet Explorer 和 Edge 將會滾動。
- execCommand() 在某些情況下可能會拋出錯誤。
- 換行和縮排可能會被吞掉,除非你使用 textarea。(大多數文章似乎建議使用 div)
- 當顯示 Internet Explorer 對話框時,文本區域將可見,你需要將其隱藏,或者使用 Internet Explorer 特定的 clipboardData API。
- 在 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 window.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 prompt("Copy to clipboard: Ctrl+C, Enter", text);
}
finally {
document.body.removeChild(textarea);
}
}
}
https://jsfiddle.net/fx6a6n6x/
答案#4
這是我對那件事的看法…
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: 請注意,使用 html input 欄位不會保留換行 \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;
}
答案#5
從網頁讀取和修改剪貼簿會引發安全和隱私疑慮。然而,在 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" />答案#6
此文章被標記為過時,因為內容已經不再更新。目前不接受新的互動。
如果你想要一個非常簡單的解決方案(整合起來不到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} 替換為顏色。
答案#7
我最近寫了一篇關於這個問題的技術部落格文章(我在 Lucidchart 工作,我們最近對剪貼簿進行了全面改造)。
將純文字複製到剪貼簿相對簡單,假設你嘗試在系統複製事件期間進行(使用者按下 Ctrl+C 或使用瀏覽器的選單)。
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 來完成的方法,這是迄今為止我所理解的唯一跨瀏覽器的方法。
除此之外,還有一些基於不同瀏覽器的選項。
這在 Internet Explorer 中是最簡單的,您可以隨時透過 JavaScript 訪問 clipboardData 對象,如下所示:
window.clipboardData
(然而,當你試圖在系統剪下、複製或貼上事件之外進行此操作時,Internet Explorer 將提示使用者授予網頁應用程式剪貼簿權限。)
在 Chrome 中,你可以建立一個 Chrome 擴充功能,讓你獲得剪貼簿的權限(這就是我們為 Lucidchart 所做的)。然後,對於安裝了你的擴充功能的使用者,你只需要自己觸發系統事件即可:
document.execCommand('copy');
看起來 Firefox 有一些選項允許使用者給予某些網站存取剪貼簿的權限,但我本人還沒有嘗試過這些選項。
答案#8
我喜歡這個:
<input onclick="this.select();" type='text' value='copy me' />
如果使用者不知道如何在他們的作業系統中複製文字,那麼他們很可能也不知道如何貼上。所以只要自動選取文字,其餘的讓使用者自己處理即可。
答案#9
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 上。
注意:這已經被棄用。請遷移到這裡。
答案#10
我非常成功地使用這個(不使用 jQuery 或任何其他框架)。
function copyToClp(txt){
var m = document;
txt = m.createTextNode(txt);
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 中是如此)。
答案#11
在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。
更多關於剪貼簿操作的技巧也可以進行。更多資訊請見此處:
解除剪貼簿存取限制
答案#12
在 JavaScript/TypeScript 中使用此命令的最佳且簡單的方法
navigator.clipboard.writeText(textExample);
只需將你想複製到剪貼簿的值傳遞到 textExample
答案#13
我不願意再對這個問題添加另一個答案,但為了幫助像我這樣的新手,並且因為這是 Google 的首要結果,我還是會這麼做。
在 2022 年,複製文字到剪貼簿你使用 一行。
navigator.clipboard.writeText(textToCopy);
這會返回一個 Promise,如果複製成功則解決,如果失敗則拒絕。
一個完整可運作的函數如下:
async function copyTextToClipboard(textToCopy) {
try {
await navigator.clipboard.writeText(textToCopy);
console.log('copied to clipboard')
} catch (error) {
console.log('failed to copy to clipboard. error=' + error);
}
}
警告!如果在測試時打開了 Chrome 開發者工具,測試將會失敗,因為瀏覽器為了啟用剪貼簿,需要你將視窗設為焦點。這是為了防止隨意的網站更改你的剪貼簿,如果你不希望它這樣做。開發者工具會搶佔這個焦點,所以關閉開發者工具後,你的測試就會正常運作。
如果你想把其他東西(圖片等)複製到剪貼簿,請查看這些文件。
https://developer.mozilla.org/zh-TW/docs/Web/API/Clipboard_API
這在瀏覽器中已經有很好的支援,你可以使用它。如果你擔心 Firefox,使用 Permissions Query 來顯示或隱藏按鈕,前提是瀏覽器支援它。https://developer.mozilla.org/en-US/docs/Web/API/Permissions/query
答案#14
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 的非 Flash 支持,你只需添加一個備用方案:
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
答案#15
由於 Chrome 42 以上版本和 Firefox 41 以上版本現在支援 document.execCommand('copy') 指令,我結合 Tim Down 的舊答案和 Google 開發者的答案,創建了幾個函數來實現跨瀏覽器的複製到剪貼簿功能:
function selectElementContents(el) {
// Copy textarea, pre, div, etc.
if (document.body.createTextRange) {
// Internet Explorer
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>答案#16
我已經整理出了我認為最好的那一個。
- 使用 cssText 以避免在 Internet Explorer 中直接使用 style 時發生例外。
- 如果先前有選取,則恢復選取
- 設為唯讀,以便在行動裝置上鍵盤不會彈出
- 對 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 programmatic execCommand copying normally, without this hack.
// https://stackoverflow.com/questions/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')
答案#17
其他方法將純文字複製到剪貼簿。要複製 HTML(即,您可以將結果粘貼到所見即所得編輯器中),您只能在 Internet Explorer 中進行以下操作。這與其他方法本質上不同,因為瀏覽器實際上會明顯地選取內容。
// 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();
答案#18
我找到以下解決方案:
按鍵按下事件處理程式會創建一個 "pre" 標籤。我們將要複製的內容設置到這個標籤,然後在這個標籤上進行選擇,並在處理程式中返回 true。這將調用 Chrome 的標準處理程式並複製選中的文本。
如果你需要,你可以為恢復先前選擇的函數設定超時。我在 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 did 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('Failed to paste. :(');
};
}
用法:
enyby_clip = new EnybyClipboard(); // Init
enyby_clip.copyText('some_text'); // Place this in the 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;
在粘貼時,它會創建一個文本區,並以相同的方式運作。
附註:也許這個解決方案可以用於創建一個完整的跨瀏覽器解決方案而不使用 Flash。它在 Firefox 和 Chrome 中都能運行。
答案#19
此程式碼於 2021 年 5 月測試過。可用於 Chrome、IE、Edge。下面的 'message' 參數是你想要複製的字串值。
<script type="text/javascript">
function copyToClipboard(message) {
var textArea = document.createElement("textarea");
textArea.value = message;
textArea.style.opacity = "0";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
alert('Copying text command was ' + msg);
} catch (err) {
alert('Unable to copy value , error : ' + err.message);
}
document.body.removeChild(textArea);
}
</script>
答案#20
這可以立即工作,使用最新的剪貼簿 API,並需要使用者互動:
copy.addEventListener("pointerdown", () => navigator.clipboard.writeText("Hello World!"))<button id="copy">Copy Hello World!</button>答案#21
將 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>注意: document.execCommand() 方法在 Internet Explorer 9 及更早版本中不受支援。
來源:W3Schools - 複製文字到剪貼簿
答案#22
複製文字欄位內文字的最佳方法。使用 navigator.clipboard.writeText。
<input type="text" value="Hello World" id="myId">
<button onclick="myFunction()" >Copy text</button>
<script>
function myFunction() {
var copyText = document.getElementById("myId");
copyText.select();
copyText.setSelectionRange(0, 99999);
navigator.clipboard.writeText(copyText.value);
}
</script>
答案#23
我在從(類似 Excel 的東西)建立自訂網格編輯時遇到相同的問題,還有與 Excel 的相容性。我必須支援選取多個儲存格、複製和貼上。
解決方案:創建一個多行文字輸入框,將用於插入數據供用戶複製(對我來說是當用戶選擇單元格時),對其設置焦點(例如,當用戶按下 Ctrl 時)並選擇整個文本。
所以,當使用者按下 Ctrl+C 時,他/她會複製所選取的儲存格。在測試時,我只是將文字區域調整為一個像素(我沒有測試它在 display:none 時是否可行)。它在所有瀏覽器上都運作良好,且對使用者而言是透明的。
貼上 - 你可以像這樣做(取決於你的目標不同) - 保持焦點在文本區,並使用 onpaste 捕捉貼上事件(在我的專案中,我使用單元格內的文本區進行編輯)。
我不能貼出範例(商業專案),但你應該明白意思。
