前端js常用剪贴板(复制粘贴)操作和应用,以及navigator.clipboard新粘贴板API使用
最近的項目上需要做復制粘貼相關的操作,來總結下吧
復制、剪切、粘貼事件:
- copy 發(fā)生復制操作時觸發(fā);
- cut 發(fā)生剪切操作時觸發(fā);
- paste 發(fā)生粘貼操作時觸發(fā);
每個事件都有一個 before 事件對應:beforecopy、beforecut、beforepaste;
這幾個 before 一般不怎么用,所以我們把注意力放在三個事件就可以了。
觸發(fā)條件:
復制操作:
copy事件使用示例:
<body>gggwgzgf </body> <script type="text/javascript">document.body.oncopy = e => {// 監(jiān)聽全局復制 做點什么console.log(e)}; </script>
我們可以看到事件對象中的屬性:
我們主要研究的是里面的clipboardData屬性對象
clipboardData 對象: 用于訪問以及修改剪貼板中的數據
clipboardData對象中有兩個方法:
-
getData():常配合copy事件使用,用于設置到剪貼板中的值
-
setData():常配合paste事件使用,用于獲取設置到剪貼板中的值
兼容:
不同瀏覽器,所屬的對象不同:在 IE
中這個對象是window對象的屬性,在Chrome、Safari和Firefox中,這個對象是相應的event對象的屬性。所以我們在使用的時候,需要做一下如下兼容:
copy配合getSelection實現復制某段文本:
<body>gggwgzgf</body><script type="text/javascript">document.body.oncopy = e => {console.log(window.getSelection().toString())let copyMsg = window.getSelection().toString()//把值設置到剪貼板中,方便paste事件觸發(fā)去拿e.clipboardData.setData("Text", copyMsg);};</script>為了方便,這次,我直接使用ctrl+c測試了
注意:window.getSelection().toString()我是調用toString()方法轉成文本的,如果不調用這個方法,直接通過window.getSelection()取到值存到剪貼板會有出奇的效果,后面會說到,需要配合paste事件
粘貼paste事件
使用示例:
<body>gggwgzgf<input placeholder="這里存放粘貼操作的值" /></body><script type="text/javascript">document.body.oncopy = e => {console.log(window.getSelection().toString())let copyMsg = window.getSelection().toString()e.clipboardData.setData("Text", copyMsg);};document.body.onpaste=function(e){var data = e.clipboardData.getData("Text")document.querySelector("input").value = data}</script>
到這里,你可能有個疑問,只能復制粘貼文本嗎,圖片可以嗎?
這是可以的。
通過patse事件獲取剪切板中的圖片:
<script type="text/javascript">document.addEventListener('paste', function(event) {var items = (event.clipboardData && event.clipboardData.items) || [];var file = null;if(items && items.length) {for(var i = 0; i < items.length; i++) {if(items[i].type.indexOf('image') !== -1) {file = items[i].getAsFile();break;}}}console.log(file)}); </script>解釋: 當粘貼事件觸發(fā)時遍歷剪切版對象(clipboardData)中的所有items,找到類型為圖片的item并調用getAsFile方法得到文件對象
拿到file 對象后我們有幾種選擇:
示例代碼:
<body><img src="" id="imgTest" /></body><script type="text/javascript">document.addEventListener('paste', function(event) {var items = (event.clipboardData && event.clipboardData.items) || [];var file = null;if(items && items.length) {for(var i = 0; i < items.length; i++) {if(items[i].type.indexOf('image') !== -1) {file = items[i].getAsFile();break;}}}var blobUrl = URL.createObjectURL(file);document.getElementById("imgTest").src = blobUrl;});</script>
局限性:
對于qq,微信等的截圖或者按print screen得到的截圖,還有任意網頁的右擊復制圖片都能完美支持,但是,對于電腦本地圖片文件的復制沒辦法從剪切版獲取到
進階用法:
配合window.getSelection(),文字圖片混合復制粘貼:
<body><span>gegegseraw</span><img src="a1.png" width="100" /><hr />下面為粘貼區(qū)域:<div></div></body><script type="text/javascript">document.body.oncopy = function(e) { let copyMsg = window.getSelection()e.clipboardData.setData("Text", copyMsg);}document.body.addEventListener('paste', function(event) {var data = (event.clipboardData && event.clipboardData.items) || [];console.log(data)let div = document.querySelector("div")for(var i = 0; i < data.length; i += 1) {if((data[i].kind == 'string') &&(data[i].type.match('^text/plain'))) {// This item is the target nodeconsole.log("... Drop:plain")} else if((data[i].kind == 'string') &&(data[i].type.match('^text/html'))) {// Drag data item is HTMLdata[i].getAsString(function(s) {div.innerHTML = s});console.log("... Drop: HTML");} else if((data[i].kind == 'string') &&(data[i].type.match('^text/uri-list'))) {// Drag data item is URIconsole.log("... Drop: URI");} else if((data[i].kind == 'file') &&(data[i].type.match('^image/'))) {// Drag data item is an image fileconsole.log("... Drop: File ");}}});</script>效果:
navigator.clipboard介紹:
異步剪貼板 API 是一個相對較新的 API,瀏覽器仍在逐漸實現它。由于潛在的安全問題和技術復雜性,大多數瀏覽器正在逐步集成這個 API。剪貼板 Clipboard API 為 Navigator 接口添加了只讀屬性 clipboard,該屬性返回一個可以讀寫剪切板內容的 Clipboard 對象。 在 Web 應用中,剪切板 API 可用于實現剪切、復制、粘貼的功能。
系統(tǒng)剪貼板暴露于全局屬性 Navigator.clipboard 之中,Navigator.clipboard對象中有四個常用方法:都是異步的
- read():從剪貼板讀取數據(比如圖片),返回一個 Promise 對象。
- readText():從操作系統(tǒng)讀取文本,返回一個 Promise 對象。
- write():寫入任意數據至操作系統(tǒng)剪貼板,返回一個 Promise 對象。
- writeText():寫入文本至操作系統(tǒng)剪貼板,返回一個 Promise 對象。
注意:只有在用戶事先授予網站或應用對剪切板的訪問許可之后,才能使用異步剪切板讀寫方法。許可操作必須通過取得權限 Permissions API 的 "clipboard-read" 和/或 "clipboard-write" 項獲得。
使用實例:
復制writeText():
navigator.clipboard.writeText('要復制的文本').then(() => {console.log('文本已經成功復制到剪切板');}).catch(err => {// 如果用戶沒有授權,則拋出異常console.error('無法復制此文本:', err);});async,await優(yōu)化寫法:
async function copyPageUrl() {try {await navigator.clipboard.writeText(location.href);console.log('Page URL copied to clipboard');} catch (err) {console.error('Failed to copy: ', err);} }粘貼readText():
navigator.clipboard.readText().then(text => {console.log('Pasted content: ', text);}).catch(err => {console.error('Failed to read clipboard contents: ', err);});同理也可寫成async,await
write()寫入數據/圖片:
function setClipboard(text) {let data = new DataTransfer();data.items.add("text/plain", text);navigator.clipboard.write(data).then(function() {/* success */}, function() {/* failure */}); }代碼創(chuàng)建了一個 DataTransfer 對象,要替換的內容存儲在這里。執(zhí)行 DataTransferItemList.add() 將數據寫入進去,然后執(zhí)行 write() 方法,指定執(zhí)行成功或錯誤的結果。
read()讀取數據/圖片:
navigator.clipboard.read().then(data => {for (let i=0; i<data.items.length; i++) {if (data.items[i].type != "text/plain") {alert("Clipboard contains non-text data. Unable to access it.");} else {textElem.innerText = data.items[i].getAs("text/plain");}}});應用:
實現類知乎/掘金復制大段文本添加版權信息:
<body><span>0123456789abcdefg</span><hr /> 下面為粘貼區(qū)域:<div></div></body><script type="text/javascript">document.body.oncopy = event => {event.preventDefault(); // 取消默認的復制事件let textFont = nulllet copyFont = window.getSelection().toString(); // 被復制的文字 等下插入// 防知乎掘金 復制一兩個字則不添加版權信息 超過一定長度的文字 就添加版權信息if(copyFont.length > 10) {textFont =`內容: ${copyFont} 作者:codingWeb 鏈接:https://blog.csdn.net/fesfsefgs來源:csdn 著作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。`} else {textFont = copyFont; // 沒超過十個字 則采用被復制的內容。}event.clipboardData.setData('text', textFont); // 將信息寫入粘貼板};document.body.onpaste = function(event) {var data = event.clipboardData.getData("text")document.querySelector("div").innerHTML = data}</script>實現類起點網的防復制功能:
提示: 使用e.preventDefault()也可以禁用,示例中document.body全局都禁用了,也可以對 dom(某些區(qū)域)進行禁用。
點擊復制功能:
不能使用 clipboardData:
在 IE 中可以用window.clipboardData.setData('text','內容')實現。因為,在 IE
中clipboardData是window的屬性。而其他瀏覽器則是相應的event對象的屬性,這實際上是一種安全措施,防止未經授權的訪問,為了兼容其他瀏覽器,所以我們不能通過clipboardData來實現這種操作。
具體做法:
示例:
<body><button>#aaaaaa</button><button>#bbbbbb</button><button>#ffffff</button><input /></body><script type="text/javascript">function copyText(e) {var text = e.target.innerHTML; // 獲取要復制的內容也可以傳進來var input = document.querySelector('input'); // 獲取隱藏input的dominput.value = text; // 修改文本框的內容input.select(); // 選中文本document.execCommand('copy'); // 執(zhí)行瀏覽器復制命令console.log('復制成功');}document.body.onclick=copyText</script>
擴展:
如果不通過手動點擊元素觸發(fā)click事件,代碼控制,我們都知道,可以使用dom.click()觸發(fā)一次點擊操作
那別的事件也可以通過代碼控制觸發(fā)嗎?
答案是可以的
事件模擬:
function trigger(el,type){let ev = document.createEvent("HTMLEvents")ev.initEvent(type,true,true)el.dispatchEvent(ev)}使用:
trigger(domEle,"copy") trigger(domEle,"paste")鍵盤模擬:
let mockKeyboardEvent = new KeyboardEvent('keyup', { shiftKey: true, keyCode: 49 })document.dispatchEvent(mockKeyboardEvent)鼠標模擬:
let mockClickEvent = new MouseEvent('click', {...}); document.dispatchEvent(mockClickEvent);自定義事件模擬:(推薦)
//綁定document.body.onpaste = function (e) {console.log(e)} //觸發(fā),攜帶自定義參數let myEvent = new CustomEvent('paste', {detail: {username: 'aaaaaaa',password: '11111111'}})document.body.dispatchEvent(myEvent)總結
以上是生活随笔為你收集整理的前端js常用剪贴板(复制粘贴)操作和应用,以及navigator.clipboard新粘贴板API使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java short =_java sh
- 下一篇: Android 中Goolgle 相关服