深入探討JavaScript、JQuery屏蔽網(wǎng)頁(yè)鼠標(biāo)右鍵菜單及禁止選擇復(fù)制
我記得在剛開(kāi)始接觸動(dòng)態(tài)HTML及JavaScript時(shí)就接觸過(guò)關(guān)于鼠標(biāo)右鍵屏蔽的腳本代碼,當(dāng)時(shí)這些代碼很多會(huì)用在防止瀏覽者未經(jīng)允許的復(fù)制網(wǎng)頁(yè)上的文字或者其他內(nèi)容,后來(lái)的實(shí)際應(yīng)用證明這種做法是不符合用戶體驗(yàn)的,而且破解的方法也有很多,比如我曾經(jīng)寫過(guò)一篇文章講解如何解除網(wǎng)頁(yè)禁止復(fù)制的辦法。
由此可見(jiàn),限制右鍵及復(fù)制是不明智的做法,但是今天我仍然要談?wù)勱P(guān)于禁止網(wǎng)頁(yè)復(fù)制、右鍵菜單的事兒,因?yàn)殡S著網(wǎng)頁(yè)APP技術(shù)的發(fā)展,網(wǎng)頁(yè)應(yīng)用和桌面應(yīng)用之間的界限越來(lái)越模糊,有一些桌面程序?qū)嶋H上是由網(wǎng)頁(yè)配合JavaScript實(shí)現(xiàn)的,另外一些手機(jī)應(yīng)用也可以是由HTML5+JavaScript實(shí)現(xiàn)的,在這種情形下,限制右鍵就是有必要的了,因?yàn)樽鳛锳PP來(lái)說(shuō),網(wǎng)頁(yè)的右鍵選擇文字及彈出菜單在大多數(shù)情況下顯得沒(méi)有必要了。
接下來(lái)介紹的可能只包含某一方面的代碼,但是我相信大家一定能夠舉一反三:-)
一、粗暴版的限制選擇復(fù)制或者禁止鼠標(biāo)右鍵
我們先談?wù)勅绾未直┑南拗苹蛘呓篂g覽者復(fù)制網(wǎng)頁(yè)上的文字,正常的防止瀏覽者復(fù)制文字,我們肯定是想到禁用用戶的某些特定的操作,比如鼠標(biāo)右鍵,選擇,復(fù)制等等,而這些操作對(duì)應(yīng)了相應(yīng)的腳本事件,只要給這些事件加上一個(gè)方法,讓其返回false就可以“吃”掉這個(gè)操作了,一般粗暴的禁止復(fù)制的腳本代碼如下:
window.onload = function() {
with(document.body) {
oncontextmenu=function(){return false}
ondragstart=function(){return false}
onselectstart=function(){return false}
onbeforecopy=function(){return false}
onselect=function(){document.selection.empty()}
oncopy=function(){document.selection.empty()}
}
}
為什么稱這個(gè)方法為粗暴版的呢?因?yàn)槭褂眠@個(gè)方法禁止鼠標(biāo)右鍵后你會(huì)發(fā)現(xiàn)網(wǎng)頁(yè)上任何控件都無(wú)法右擊或者選擇了,網(wǎng)頁(yè)似乎成了死板的圖片,也許你會(huì)覺(jué)得無(wú)所謂,但是對(duì)于input、textarea文本框這類字符輸入控件就有很大的關(guān)系了,這些地方不能限制用戶的右鍵及選擇復(fù)制操作。
二、合理判斷要限制的HTML標(biāo)簽元素
如何判斷當(dāng)前處理的層所在的元素標(biāo)簽?zāi)?,也就是說(shuō)得到鼠標(biāo)當(dāng)前所在的HTML Tag,這里我們以oncontextmenu為例,其實(shí)在document.body.oncontextmenu傳入的函數(shù)有一個(gè)參數(shù)我們略去了,完整的寫法應(yīng)該是document.body.oncontextmenu=function(e){}這里的e是JavaScript中的Event事件對(duì)象,在IE中可能是通過(guò)window.event獲取的。通過(guò)這個(gè)事件對(duì)象可以獲取觸發(fā)事件時(shí)鼠標(biāo)所在的HTML Tag,我們可以判斷是不是我們要忽略處理元素標(biāo)簽,這里我提供一個(gè)函數(shù)如下:
var isTagName = function(e, whitelists) {
e = e || window.event;
var target = e.target || e.srcElement;
Array.prototype.contains = function(elem)
{
for (var i in this)
{
if (this[i].toString().toUpperCase() == elem.toString().toUpperCase()) return true;
}
return false;
}
if (whitelists && !whitelists.contains(target.tagName)) {
return false;
}
return true;
};
這里的e是事件對(duì)象event,target是事件對(duì)象所引用的元素對(duì)象,當(dāng)然這里兩個(gè)變量都采取了兼容IE的寫法,具體可以參考《How can I make event.srcElement work in Firefox and what does it mean?》;這里的whitelists是白名單HTML元素標(biāo)簽Tag名,比如['INPUT', 'TEXTAREA'],表示將輸入文本框input和textarea加入判斷,如果當(dāng)前事件元素是的話就返回true,這樣我們通過(guò)下面的代碼可以選擇性的屏蔽鼠標(biāo)右鍵了:
document.body.oncontextmenu=function(e){
return isTagName(e, ['A', 'TEXTAREA']);
}
三、JQuery版的選擇性屏蔽禁止文本選擇
同樣的對(duì)于其他的操作也可以選擇性的屏蔽,在JQuery支持的環(huán)境中我在StackOverflow找到了這么一篇文章《How to disable text selection using jQuery?》,雖然是講解的禁止選擇的,不過(guò)可以借鑒一下,具體代碼如下:
(function($){
$.fn.ctrlCmd = function(key) {
var allowDefault = true;
if (!$.isArray(key)) {
key = [key];
}
return this.keydown(function(e) {
for (var i = 0, l = key.length; i < l; i++) {
if(e.keyCode === key[i].toUpperCase().charCodeAt(0) && e.metaKey) {
allowDefault = false;
}
};
return allowDefault;
});
};
$.fn.disableSelection = function() {
this.ctrlCmd(['a', 'c']);
return this.attr('unselectable', 'on')
.css({'-moz-user-select':'-moz-none',
'-moz-user-select':'none',
'-o-user-select':'none',
'-khtml-user-select':'none',
'-webkit-user-select':'none',
'-ms-user-select':'none',
'user-select':'none'})
.bind('selectstart', false);
};
})(jQuery);
在使用上采取下面的代碼:
$(':not(input,select,textarea)').disableSelection();
這樣就可以除去input、select、textarea外禁止選擇了,這段代碼的技巧是除了采取selectstart外還給相關(guān)元素添加了某些特殊瀏覽器支持的CSS特性,這樣基本可以實(shí)現(xiàn)大多數(shù)瀏覽器的兼容,同時(shí)這段代碼還屏蔽了鍵盤按鍵選擇Ctrl+A和Ctrl+C,不得不佩服作者周到的考慮。
四、進(jìn)一步完善:屏蔽鼠標(biāo)點(diǎn)擊操作
我在測(cè)試這段代碼時(shí)遇到一個(gè)問(wèn)題就是點(diǎn)擊除input、select、textarea外的元素時(shí)會(huì)全部選擇頁(yè)面,原文作者給出一個(gè)簡(jiǎn)單的方法就是在使用代碼上附加.on('mousedown', false),這樣就屏蔽了鼠標(biāo)的單擊,使用代碼變成如下:
但是問(wèn)題又來(lái)了,我發(fā)現(xiàn)采取上述代碼后,input,select,textarea也開(kāi)始變得不正常起來(lái),看樣子屏蔽mousedown的特性應(yīng)用到所有元素上了?,F(xiàn)在轉(zhuǎn)換一下思路,結(jié)合剛才我提出的方案,判斷event對(duì)象來(lái)實(shí)現(xiàn)選擇性屏蔽,我將代碼修正如下:
$(':not(input,select,textarea)').disableSelection().on('mousedown', function(e) {
var event = $.event.fix(e);
var elem = event.target || e.srcElement;
if (elem.tagName.toUpperCase() != 'TEXTAREA' && elem.tagName.toUpperCase() != 'INPUT') {
e.preventDefault();
return false;
}
return true;
});
這樣textarea和input就不會(huì)限制mousedown了,我們將這段代碼抽出為函數(shù):
function jQuery_isTagName(e, whitelists) {
e = $.event.fix(e);
var target = e.target || e.srcElement;
if (whitelists && $.inArray(target.tagName.toString().toUpperCase(), whitelists) == -1) {
return false;
}
return true;
}
$(':not(input,select,textarea)').disableSelection().on('mousedown', function(e) {
if (!jQuery_isTagName(e, ['INPUT', 'TEXTAREA'])) {
e.preventDefault();
return false;
}
return true;
});
五、JQuery版的選擇性屏蔽禁止鼠標(biāo)右鍵
對(duì)于右鍵菜單,我們可以這樣處理:
$(document).bind("contextmenu",function(e){
if (!jQuery_isTagName(e, ['INPUT', 'TEXTAREA'])) {
e.preventDefault();
return false;
}
return true;
});
相關(guān)文章
限時(shí)搶購(gòu)-倒計(jì)時(shí)的完整實(shí)例(分享)
下面小編就為大家?guī)?lái)一篇限時(shí)搶購(gòu)-倒計(jì)時(shí)的完整實(shí)例(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09js中對(duì)象與對(duì)象創(chuàng)建方法的各種方法
這篇文章主要給大家介紹了關(guān)于js中對(duì)象與對(duì)象創(chuàng)建方法的各種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02three.js如何實(shí)現(xiàn)3D動(dòng)態(tài)文字效果
這篇文章主要給大家介紹了關(guān)于three.js如何實(shí)現(xiàn)3D動(dòng)態(tài)文字效果的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03JavaScript中創(chuàng)建對(duì)象和繼承示例解讀
這篇文章主要介紹了JavaScript中怎樣創(chuàng)建對(duì)象和繼承,需要的朋友可以參考下2014-02-02js實(shí)現(xiàn)鼠標(biāo)感應(yīng)向下滑動(dòng)隱藏菜單的方法
這篇文章主要介紹了js實(shí)現(xiàn)鼠標(biāo)感應(yīng)向下滑動(dòng)隱藏菜單的方法,涉及javascript操作鼠標(biāo)事件的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02JS實(shí)現(xiàn)根據(jù)密碼長(zhǎng)度顯示安全條功能
這篇文章主要介紹了基于JS實(shí)現(xiàn)根據(jù)密碼長(zhǎng)度顯示安全條功能,非常不錯(cuò),在一些網(wǎng)站上經(jīng)常會(huì)遇到此功能,需要的的朋友參考下實(shí)現(xiàn)代碼吧2017-03-03