JavaScript實現(xiàn)點擊復制功能具體代碼(JS訪問剪貼板相關)
一、具體代碼
網(wǎng)頁前端開發(fā)中有時會出現(xiàn)這樣的場景:讓用戶點擊某個按鈕,然后就能直接復制對應的文本內(nèi)容,讓用戶可以將文本內(nèi)容粘貼到想要粘貼的地方,常用于分享功能模塊中。如果想要實現(xiàn)這種效果就需要我們?nèi)ピL問用戶的剪貼板,然后把想要復制的內(nèi)容寫入其中即可,本文主要講解兩種解決方案: document.execCommand()
和 Clipboard
。
先上代碼:
?為了同時兼容新舊瀏覽器(IE?。覀円话悴扇∠旅娴姆绞剑?/p>
// 復制文本內(nèi)容 function copyContent (content) { // 復制結果 let copyResult = true // 設置想要復制的文本內(nèi)容 const text = content || '讓我們一起快樂的敲代碼吧~'; // 判斷是否支持clipboard方式 if (!!window.navigator.clipboard) { // 利用clipboard將文本寫入剪貼板(這是一個異步promise) window.navigator.clipboard.writeText(text).then((res) => { console.log('復制成功'); // 返回復制操作的最終結果 return copyResult; }).catch((err) => { copyResult = false console.log('復制失敗', err); // 返回復制操作的最終結果 return copyResult; }) } else { // 不支持clipboard方式 則采用document.execCommand()方式 // 創(chuàng)建一個input元素 let inputDom = document.createElement('textarea'); // 設置為只讀 防止移動端手機上彈出軟鍵盤 inputDom.setAttribute('readonly', 'readonly'); // 給input元素賦值 inputDom.value = text; // 將創(chuàng)建的input添加到body document.body.appendChild(inputDom); // 選中input元素的內(nèi)容 inputDom.select(); // 執(zhí)行瀏覽器復制命令 // 復制命令會將當前選中的內(nèi)容復制到剪切板中(這里就是創(chuàng)建的input標簽中的內(nèi)容) // Input要在正常的編輯狀態(tài)下原生復制方法才會生效 const result = document.execCommand('copy') // 判斷是否復制成功 if (result) { console.log('復制成功'); } else { console.log('復制失敗'); copyResult = false } // 復制操作后再將構造的標簽 移除 document.body.removeChild(inputDom); // 返回復制操作的最終結果 return copyResult; } }
二、剪貼板
? 剪貼板是用于短期數(shù)據(jù)存儲或者轉移的數(shù)據(jù)緩存區(qū),數(shù)據(jù)轉移可以發(fā)生在不同的文檔或應用程序之間。剪貼板常常實現(xiàn)為一個匿名的、臨時的數(shù)據(jù)緩存,有時也叫做粘貼緩存,可由絕大部分位于已定義應用程序接口的環(huán)境中的程序訪問。
三、Clipboard
1、簡介
? Clipboard
API 提供了響應剪貼板命令和異步讀寫系統(tǒng)剪貼板的能力,該API是用來取代 document.execCommand()
這種剪貼板訪問方式的。但是該API需要通過 PerMissions
API獲取用戶授予的權限( "clipboard-read"
或 "clipboard-write"
)之后,才能訪問剪貼板,如果用戶拒絕授予相應權限,則無法訪問剪貼板,調(diào)用 Clipboard
對象的方法就會失敗。而且該API僅在一些安全上下文環(huán)境中可用(HTTPS、localhost、127.0.0.1等),我們可以通過 window.isSecureContext
的返回值來判斷當前環(huán)境是否為安全上下文環(huán)境。
? 我們可以通過 window.navigator.permissions.query({name: "clipboard-read"})
和 window.navigator.permissions.query({name: "clipboard-write"})
來判斷當前網(wǎng)頁是否擁有讀寫剪貼板的權限(Firefox不支持!)。
? 該API在 Window.navigator
接口上添加了只讀屬性 clipboard
,該屬性返回一個可以讀寫剪切板內(nèi)容的 Clipboard
對象,我們前端大多是通過 window.navigator.clipboard
來訪問剪貼板。
? 由于該API是一個較新的API,而且涉及的安全問題和技術復雜性太多,所以瀏覽器兼容性相對差一點(不支持IE):
瀏覽器兼容性(Navigator.clipboard):
2、Clipboard
? 該接口實現(xiàn)了 Clipboard
API,用于讀寫系統(tǒng)剪貼板上的文本和數(shù)據(jù)的接口,前端規(guī)范稱其為異步剪貼板API(Async Clipboard API),因為該API下的所有方法都是異步的,它們會返回一個 Promise
對象,操作成功后調(diào)用 resolve()
,操作失敗后調(diào)用 reject()
。
相關方法:
① read()
? 該方法用于從系統(tǒng)剪貼板中讀取任意數(shù)據(jù)的副本(文本、圖片等),返回一個 Promise
對象,在經(jīng)過異步數(shù)據(jù)檢索之后, Promise
返回一個包含相關數(shù)據(jù)的 ClipboardItem
對象的數(shù)組,該數(shù)組含有兩個數(shù)據(jù)對象,第一個對象中僅包含剪貼板中的文本數(shù)據(jù),第二個對象中包含剪貼板中的所有內(nèi)容數(shù)據(jù)。
? 該方法必須在網(wǎng)頁獲取焦點時,才能正常調(diào)用,否則會報錯。而且該方法不能在JS中直接調(diào)用,只能在處理用戶行為(點擊等交互行為)時才能正常調(diào)用,否則會報錯。
? 如果系統(tǒng)剪貼板中的內(nèi)容是復制的系統(tǒng)本地的文件,則通過該方法只能訪問到文件名,而無法訪問到文件本身的內(nèi)容。如果我們是復制的系統(tǒng)本地文件中的內(nèi)容,并包含文本和圖片,則該方法能正常獲取到文本信息,但圖片無法被獲取到。
② readText()
? 該方法從系統(tǒng)剪貼板讀取中文本數(shù)據(jù)的副本,返回一個 Promise
對象,在經(jīng)過異步數(shù)據(jù)檢索之后, Promise
返回一個包含相關文本數(shù)據(jù)的 String
字符串數(shù)據(jù)。
? 該方法必須在網(wǎng)頁獲取焦點時,才能正常調(diào)用,否則會報錯。但是與 read()
不同的是,該方法可以在JS中直接調(diào)用,不需要等待用戶行為。
? 如果系統(tǒng)剪貼板中的內(nèi)容是復制的系統(tǒng)本地的文件,則通過該方法可以訪問到文件名。如果我們是復制的系統(tǒng)本地文件中的內(nèi)容,并包含文本和圖片,則該方法只能獲取到其中文本信息。
案例代碼:
<button onclick="clickRead()">點擊訪問剪貼板</button> <p>我想調(diào)用Clipboard API來讀取剪貼板信息</p> <p>我想2342342342432</p> <img src="./image/img.png" alt=""> <div>23423423422</div> <script> // 在剛進入頁面時,先嘗試獲取剪貼板的內(nèi)容 window.navigator.clipboard.read().then((res) => { console.log('read--res-----', res); }).catch((err) => { console.log('read--err-----', err); }) // 在剛進入頁面時,先嘗試獲取剪貼板的文本內(nèi)容 window.navigator.clipboard.readText().then((res) => { console.log('readText--res-----', res); }).catch((err) => { console.log('readText--err-----', err); }) // 用戶點擊按鈕事件 function clickRead () { // 再次嘗試獲取剪貼板的內(nèi)容 promise異步操作 window.navigator.clipboard.read().then((res) => { console.log('用戶點擊-read--res-----', res); res[0].types.forEach((type, index) => { // 通過getType讀取剪貼板中對應的數(shù)據(jù)內(nèi)容 并返回相應blob對象 res[0].getType(type).then(res => { console.log('blob--', res); let reader = new FileReader(); // 為了方便查看 將bolb轉為base64 (異步操作) reader.readAsDataURL(res); // 轉換成功 reader.onload = () => { if (index === 0) { console.log('用戶剪貼板中的所有文本內(nèi)容轉換成的base64--', reader.result); } else if (index === 1) { console.log('用戶剪貼板中的所有數(shù)據(jù)內(nèi)容內(nèi)容轉換成的base64--', reader.result); } }; }); }) }).catch((err) => { // 讀取失敗的情況 console.log('用戶點擊-read--err-----', err); }) // 在用戶點擊事件中 再次嘗試獲取剪貼板的文本內(nèi)容 window.navigator.clipboard.readText().then((res) => { // 讀取成功的情況 console.log('用戶點擊-readText--res-----', res); }).catch((err) => { // 讀取失敗的情況 console.log('用戶點擊-readText--err-----', err); }) } </script>
頁面未獲取剪貼板訪問權限時:
有權限但頁面未獲取焦點時:
有權限且頁面獲取焦點時:
有權限且頁面獲取焦點,并觸發(fā)用戶行為:
文本內(nèi)容base64查看:
所有內(nèi)容base64查看:
③ write()
? 該方法用于寫入任意數(shù)據(jù)至系統(tǒng)剪貼板,參數(shù)為一個 ClipboardItem
對象數(shù)組(但每次只能包含一個 ClipboardItem
對象),里面包含了要寫入剪貼板的數(shù)據(jù),返回值為一個 Promise
對象,經(jīng)過異步操作之后,返回執(zhí)行結果。
? 目前主流瀏覽器都支持寫入的 MIME 數(shù)據(jù)類型有: text/plain
、 text/html
、 image/png
、 text/uri-list
。
④ writeText()
? 該方法用于寫入文本數(shù)據(jù)至系統(tǒng)剪貼板,參數(shù)為一個 String
字符串,表示要寫入剪貼板的文本數(shù)據(jù),返回值為一個 Promise
對象,經(jīng)過異步操作之后,返回執(zhí)行結果。
案例代碼:
<!-- 點擊選擇文件寫入到剪貼板 --> <input type="file" onchange="clickWrite(event)"> <script> // 在剛進入頁面時,先嘗試向剪貼板寫入內(nèi)容 // 定義數(shù)據(jù)類型 const type = "text/plain"; // 創(chuàng)建一個blob對象 const blob = new Blob(['我是要通過write()寫入剪貼板的內(nèi)容1111'], { type }); // 創(chuàng)建一個ClipboardItem對象數(shù)組 const data = [new ClipboardItem({ [type]: blob })]; console.log('data--', data); // 將數(shù)據(jù)寫入剪貼板 window.navigator.clipboard.write(data).then((res) => { console.log('write--res-----', res); // 輸出剪貼板中的內(nèi)容 window.navigator.clipboard.readText().then((res) => { console.log('readText--res-----', res); }).catch((err) => { console.log('readText--err-----', err); }) }).catch((err) => { console.log('write--err-----', err); }) // 因為讀寫都是異步操作 為了避免兩個寫操作互相干擾 所以等待1秒后 再嘗試向剪貼板寫入文本內(nèi)容 setTimeout(() => { window.navigator.clipboard.writeText('我是要通過writeText()寫入剪貼板的文本內(nèi)容2222').then((res) => { console.log('writeText--res-----', res); // 輸出剪貼板中的內(nèi)容 window.navigator.clipboard.readText().then((res) => { console.log('readText--res-----', res); }).catch((err) => { console.log('readText--err-----', err); }) }).catch((err) => { console.log('writeText--err-----', err); }) }, 1000) // 用戶選擇圖片寫入剪貼板事件 function clickWrite (e) { console.log('file--', e.target.files[0]); // 定義數(shù)據(jù)類型 const type = "image/png"; // 創(chuàng)建一個ClipboardItem對象數(shù)組 const data = [new ClipboardItem({ [type]: e.target.files[0] })]; console.log('data--', data); // 將數(shù)據(jù)寫入剪貼板 window.navigator.clipboard.write(data).then((res) => { console.log('write--res-----', res); // 輸出剪貼板中的內(nèi)容 window.navigator.clipboard.read().then((res) => { console.log('read--res-----', res); }).catch((err) => { console.log('read--err-----', err); }) }).catch((err) => { console.log('write--err-----', err); }) } </script>
執(zhí)行結果:
3、ClipboardEvent
? 該接口繼承了 Event
接口,提供了有關系統(tǒng)剪貼板信息修改的事件,即 cut
、 copy
、 paste
事件,前端規(guī)范稱其為剪貼板事件(Clipboard Event API)。
? 我們可以通過 ClipboardEvent(type[, options])
構造函數(shù)來創(chuàng)建 ClipboardEvent
對象,第一個參數(shù) type
,是一個字符串,表示當前事件類型的名字,可以為: cut
、 copy
、 paste
,大小寫敏感;第二個參數(shù) options
是可選的,內(nèi)包含一個 clipboardData
屬性,該屬性的值是一個 DataTransfer
對象,包含了剪貼板事件所涉及的數(shù)據(jù)。
var clipboardEvent = new ClipboardEvent(type[, options]); // 實例 var clipboardEvent = new ClipboardEvent('paste', { clipboardData: new DataTransfer() });
? ClipboardEvent.clipboardData
屬性保存了一個 DataTransfer
對象,該對象有兩個用途:① 用于指定通過 cut
和 copy
事件寫入到剪貼板中的數(shù)據(jù),通常使用 setData(format,data)
來指定數(shù)據(jù)。② 用于從 paste
事件中獲取想要從剪貼板中讀取的數(shù)據(jù),通常使用 getData(fomat)
來獲取。 fomat
表示數(shù)據(jù)類型,例如: text/plain
、 text/uri-list
。
案例代碼:
var clipboardEvent = new ClipboardEvent('paste', { clipboardData: new DataTransfer() }); console.log('clipboardEvent--', clipboardEvent.clipboardData.getData('text/plain')); clipboardEvent.clipboardData.setData('text/plain', 'Clipboard API來讀取剪貼板信息'); console.log('clipboardEvent--', clipboardEvent.clipboardData.getData('text/plain'));
執(zhí)行結果:
4、ClipboardItem
? 該接口表示在使用read()和write()讀寫剪貼板數(shù)據(jù)時,單個數(shù)據(jù)的數(shù)據(jù)格式,該數(shù)據(jù)格式中將 MIME 類型作為 key
,將數(shù)據(jù)作為 value
。
① 創(chuàng)建ClipboardItem對象
? 可通過構造函數(shù) ClipboardItem(data[, options])
來創(chuàng)建該對象,第一個參數(shù)為想要存儲的數(shù)據(jù),可以為 Blob
、 String
或 Promise
(但個人開發(fā)發(fā)現(xiàn) file
對象也可以);第二個對象參數(shù)表示數(shù)據(jù)的呈現(xiàn)形式,該對象只包含 presentationStyle
屬性,屬性值有三種: unspecified
、 inline
和 attachment
. 默認值為 unspecified
,但是該屬性支持性特別差:Chrome、Edge、Firefox、Opera都不支持該屬性, Safari
支持該屬性,所以該屬性了解即可。
? 我們也可以通過 ClipboardItem.presentationStyle
來獲取當前對象的數(shù)據(jù)呈現(xiàn)形式。
new ClipboardItem(data[, options]) // 實例 const test = new ClipboardItem({ ["text/plain"]: new Blob(['我是小朱同學'], { "text/plain" }) }
② 讀取ClipboardItem對象中的數(shù)據(jù)
? 首先我們可以通過 ClipboardItem.types
獲取當前 ClipboardItem
對象中所有MIME 類型組成的數(shù)組,然后再通過 getType(type)
方法來異步讀取對應的數(shù)據(jù),返回一個Promise,讀取的數(shù)據(jù)為Blob類型:
ClipboardItem.types.forEach(type => { ClipboardItem.getType(type).then(res => { console.log('blob--', res); }) })
二、document.execCommand()
1、簡介
? 該方法用來操作當前聚焦的可編輯元素( input
、 textarea
)中的內(nèi)容,例如復制、剪貼、粘貼、刪除、文本加粗、插入圖片等等效果,有些富文本編輯器組件就是基于該API進行開發(fā)。而且該API的兼容性很好,可以兼容到 IE6
及以上。該API已經(jīng)不推薦使用了,因為現(xiàn)在該API已經(jīng)被 Clipboard
全面替代,雖然目前多數(shù)主流瀏覽器還支持使用,但隨時有可能被完全棄用。
瀏覽器兼容性:
2、基本語法
cosnt result = document.execCommand(aCommandName[,aShowDefaultUI,aValueArgument])
參數(shù):
? ① aCommandName
:一個命令字符串,表示要執(zhí)行操作的名稱,常用的有: copy
、 cut
、 paste
、 bold
等等,具體可查詢:execCommand。
? ② aShowDefaultUI
:一個布爾值,表示是否展示用戶界面,一般為 false
(Firefox不支持)。
? ③ aValueArgument
:第一個參數(shù)中的某些命令需要的額外參數(shù),默認為 null
,例如: insertImage
需要提供插入 image
的 url
。
返回值:
? ① 一個 Boolean
:表示要執(zhí)行操作是否執(zhí)行成功( true
),若為 false
,則表示操作不被支持或操作失敗。
3、基本使用
function copyInputContent () { // 設置想要復制的文本內(nèi)容 const text = '讓我們一起快樂的敲代碼吧~'; // 創(chuàng)建一個input元素 let inputDom = document.createElement('textarea'); // 設置為只讀 防止移動端手機上彈出軟鍵盤 inputDom.setAttribute('readonly', 'readonly'); // 給input元素賦值 inputDom.value = text; // 將創(chuàng)建的input添加到body document.body.appendChild(inputDom); // 選中input元素的內(nèi)容 inputDom.select(); // 執(zhí)行瀏覽器復制命令 // 復制命令會將當前選中的內(nèi)容復制到剪切板中(這里就是創(chuàng)建的input標簽中的內(nèi)容) // Input要在正常的編輯狀態(tài)下原生復制方法才會生效 const result = document.execCommand('copy') // 復制操作后再將構造的標簽 移除 document.body.removeChild(inputDom); }
三、參考文檔
總結
到此這篇關于JavaScript實現(xiàn)點擊復制功能(JS訪問剪貼板相關)的文章就介紹到這了,更多相關JS點擊復制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
微信小程序怎么加入JavaScript腳本,做出動態(tài)效果
這篇文章主要介紹了教大家為小程序加入?JavaScript?腳本,做出動態(tài)效果,以及如何跟用戶互動。學會了腳本,就能做出復雜的頁面了。需要的朋友可以參考下2022-12-12layui的數(shù)據(jù)表格+springmvc實現(xiàn)搜索功能的例子
今天小編就為大家分享一篇layui的數(shù)據(jù)表格+springmvc實現(xiàn)搜索功能的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09