有時候咱們常常會碰到這些場景:玩掘金、知乎的時候複製一段文字,老是會在內容後面加上一些版權信息,以及像小說網站等都有禁止選中,禁止複製這種功能,還有點擊自動複製帳號的功能。css
我也常常遇到這些場景,有時候會去想這後面究竟是怎麼作,週末趁着有空去研究了一下,而後發現這些都跟操做剪貼板有關係,而且都不難,瞭解一下基本都知道怎麼作了,整理分享一波給你們。html
我的博客瞭解一下:obkoro1.com前端
copy
發生複製操做時觸發;cut
發生剪切操做時觸發;paste
發生粘貼操做時觸發;beforecopy
、beforecut
、beforepaste
;這幾個before通常不怎麼用,因此咱們把注意力放在另外三個事件就能夠了。git
觸發條件:github
鼠標右鍵菜單的複製
、粘貼
、剪切
;web
使用了相應的鍵盤組合鍵,好比:command+c
、command+v
;瀏覽器
就算你是隨便按的,也會觸發事件。高程中介紹在Chorme
、Firefox
和Safari
中,這幾個before事件只會在真實會發生剪貼板事件的狀況下觸發,IE上則能夠觸發before。我實際測試的時候最新版chorme
也會亂按也會觸發,因此限制應該是在早一點的版本上。安全
so 想說的是:before這幾個事件最好不要用,有關於剪切板的處理最好放在copy
、cut
、paste
上面。dom
使用姿式:post
以copy爲例:
document.body.oncopy = e => {
// 監聽全局複製 作點什麼
}
// 還有這種寫法:
document.addEventListener("copy", e => {
// 監聽全局複製 作點什麼
});
複製代碼
上面是在document.body
上全局監聽的,然而不少人不知道的是,咱們還能夠爲某些dom單獨添加剪切板事件:
// html結構
<div id="test1"></div>
<div id="test2"></div>
// 寫法同樣:
let test1 = document.querySelector('#test1');
test1.oncopy = e => {
// 監聽test1發生的複製事件 作點什麼
// test1發生的複製事件會觸發回調,其餘地方不會觸發回調
}
複製代碼
其餘事件也是同樣的,這裏就不贅述了。
兼容:
不一樣瀏覽器,所屬的對象不一樣:在IE中這個對象是window
對象的屬性,在Chrome
、Safari
和Firefox
中,這個對象是相應的event
對象的屬性。因此咱們在使用的時候,須要作一下以下兼容:
document.body.oncopy = e => {
let clipboardData = (e.clipboardData || window.clipboardData);
// 獲取clipboardData對象 + do something
}
複製代碼
對象方法:
對象有三個方法: getData()
、setData()
、clearData()
getData()
訪問剪切板中的數據
參數: getData()
接受一個'text'
參數,即要取得的數據的格式。
在複製、剪切、粘貼觸發的事件的數據:
實際上在chorme上測試只有paste
粘貼的時候才能用getData()
訪問到數據,用法以下:
要粘貼的數據:
document.body.onpaste = e => {
let clipboardData = (e.clipboardData || window.clipboardData); // 兼容處理
console.log('要粘貼的數據', clipboardData.getData('text'));
}
複製代碼
被複制/剪切的數據:
在複製和剪切中的數據,須要經過window.getSelection(0).toString()
來訪問:
document.body.oncopy = e => {
console.log('被複制的數據:', window.getSelection(0).toString());
}
複製代碼
setData():
修改剪切板中的數據
參數:第一個參數也是'text'
,第二個參數是要放在剪切板中的文本。
剩下的留在下面仿知乎/掘金複製大段文本添加版權信息那裏再說。
clearData()
:
這個方法就不太知道了,試了很久不知道怎麼用(若是有大佬知道,能夠在評論區指點一下)。
若是隻是爲了禁止複製,或者禁止粘貼,在下面還有另外的方法能夠作到,而且能夠細粒化操做。
若是學習不是爲了裝X,那麼一切將毫無心義,來看這個東西能夠在哪些場景使用:
實現很簡單:取消默認複製以後,主要是在被複制的內容後面添加信息,而後根據clipboardData的setData()方法將信息寫入剪貼板。
能夠直接複製這段代碼到本地去試試。
// 掘金這裏不是全局監聽,應該只是監聽文章的dom範圍內。
document.body.oncopy = event => {
event.preventDefault(); // 取消默認的複製事件
let textFont, copyFont = window.getSelection(0).toString(); // 被複制的文字 等下插入
// 防知乎掘金 複製一兩個字則不添加版權信息 超過必定長度的文字 就添加版權信息
if (copyFont.length > 10) {
textFont = copyFont + '\n'
+ '做者:OBKoro1\n'
+ '連接:https://juejin.im/user/58714f0eb123db4a2eb95372/posts\n'
+ '來源:掘金\n'
+ '著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。';
} else {
textFont = copyFont; // 沒超過十個字 則採用被複制的內容。
}
if (event.clipboardData) {
return event.clipboardData.setData('text', textFont); // 將信息寫入粘貼板
} else {
// 兼容IE
return window.clipboardData.setData("text", textFont);
}
}
複製代碼
而後command+c、command+v,輸出:
你複製的內容
做者:OBKoro1
連接:https://juejin.im/user/58714f0eb123db4a2eb95372/posts
來源:掘金
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
複製代碼
能夠把代碼拷到本地玩一玩:
// 禁止右鍵菜單
document.body.oncontextmenu = e => {
console.log(e, '右鍵');
return false;
// e.preventDefault();
};
// 禁止文字選擇。
document.body.onselectstart = e => {
console.log(e, '文字選擇');
return false;
// e.preventDefault();
};
// 禁止複製
document.body.oncopy = e => {
console.log(e, 'copy');
return false;
// e.preventDefault();
}
// 禁止剪切
document.body.oncut = e => {
console.log(e, 'cut');
return false;
// e.preventDefault();
};
// 禁止粘貼
document.body.onpaste = e => {
console.log(e, 'paste');
return false;
// e.preventDefault();
};
// css 禁止文本選擇 這樣不會觸發js
body {
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
複製代碼
PS:
e.preventDefault()
也能夠禁用,但建議使用return false
這樣就不用去訪問e
和e
的方法了。document.body
全局都禁用了,也能夠對dom(某些區域)進行禁用。破解防複製:
上面的防複製方法經過js
+css
實現的,因此思路就是:禁用js
+取消user-select
樣式。
Chrome
瀏覽器的話:打開瀏覽器控制檯,按F1
進入Setting
,勾選Disable JavaScript
(禁止js)。
此時若是還不能複製的話,就要去找user-select
樣式,取消這個樣式就能夠了。
因此那些盜版小說手打的,我真的不太能理解,Excuse me???
不能使用clipboardData:
在IE中能夠用window.clipboardData.setData('text','內容')
實現。
上文提到過,在IE中clipboardData
是window
的屬性。
而其餘瀏覽器則是相應的event
對象的屬性,這其實是一種安全措施,防止未經受權的訪問,爲了兼容其餘瀏覽器,因此咱們不能經過clipboardData
來實現這種操做。
具體作法:
建立一個隱藏的input
框
點擊的時候,將要複製的內容放進input
框中
選擇文本內容input.select()
這裏只能用input
或者textarea
才能選擇文本。
document.execCommand("copy"),執行瀏覽器的複製命令。
function copyText() {
var text = document.getElementById("text").innerText; // 獲取要複製的內容也能夠傳進來
var input = document.getElementById("input"); // 獲取隱藏input的dom
input.value = text; // 修改文本框的內容
input.select(); // 選中文本
document.execCommand("copy"); // 執行瀏覽器複製命令
alert("複製成功");
}
複製代碼
點擊複製內容的demo在這裏,能夠點進去看看。
工做之餘瞭解一下這些東西仍是頗有趣的,也能夠擴寬你的知識面。
事實上只要監聽了這些事件,咱們就能夠對要剪切的內容進行各類各樣的操做,好比:複製的時候更換文本,粘貼的時候查找有沒有圖片(上傳圖片),或者文本的長度進行剪切等等,惟一限制你的
博客、前端積累文檔、公衆號、GitHub、wx:OBkoro一、郵箱:obkoro1@foxmail.com
以上2018.8.8
參考資料:
js高程 14.2.2操做剪貼板