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