深入探讨JavaScript、JQuery屏蔽网页鼠标右键菜单及禁止选择复制
发布时间:2024-06-23 09:05:25
我记得在刚开始接触动态HTML及JavaScript时就接触过关于鼠标右键屏蔽的脚本代码,当时这些代码很多会用在防止浏览者未经允许的复制网页上的文字或者其他内容,后来的实际应用证明这种做法是不符合用户体验的,而且破解的方法也有很多,比如我曾经写过一篇文章讲解如何解除网页禁止复制的办法。
由此可见,限制右键及复制是不明智的做法,但是今天我仍然要谈谈关于禁止网页复制、右键菜单的事儿,因为随着网页APP技术的发展,网页应用和桌面应用之间的界限越来越模糊,有一些桌面程序实际上是由网页配合JavaScript实现的,另外一些手机应用也可以是由HTML5+JavaScript实现的,在这种情形下,限制右键就是有必要的了,因为作为APP来说,网页的右键选择文字及弹出菜单在大多数情况下显得没有必要了。
接下来介绍的可能只包含某一方面的代码,但是我相信大家一定能够举一反三:-)
一、粗暴版的限制选择复制或者禁止鼠标右键
我们先谈谈如何粗暴的限制或者禁止浏览者复制网页上的文字,正常的防止浏览者复制文字,我们肯定是想到禁用用户的某些特定的操作,比如鼠标右键,选择,复制等等,而这些操作对应了相应的脚本事件,只要给这些事件加上一个方法,让其返回false就可以“吃”掉这个操作了,一般粗暴的禁止复制的脚本代码如下:
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()}
}
}
为什么称这个方法为粗暴版的呢?因为使用这个方法禁止鼠标右键后你会发现网页上任何控件都无法右击或者选择了,网页似乎成了死板的图片,也许你会觉得无所谓,但是对于input、textarea文本框这类字符输入控件就有很大的关系了,这些地方不能限制用户的右键及选择复制操作。
二、合理判断要限制的HTML标签元素
如何判断当前处理的层所在的元素标签呢,也就是说得到鼠标当前所在的HTML Tag,这里我们以oncontextmenu为例,其实在document.body.oncontextmenu传入的函数有一个参数我们略去了,完整的写法应该是document.body.oncontextmenu=function(e){}这里的e是JavaScript中的Event事件对象,在IE中可能是通过window.event获取的。通过这个事件对象可以获取触发事件时鼠标所在的HTML Tag,我们可以判断是不是我们要忽略处理元素标签,这里我提供一个函数如下:
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是事件对象event,target是事件对象所引用的元素对象,当然这里两个变量都采取了兼容IE的写法,具体可以参考《How can I make event.srcElement work in Firefox and what does it mean?》;这里的whitelists是白名单HTML元素标签Tag名,比如['INPUT', 'TEXTAREA'],表示将输入文本框input和textarea加入判断,如果当前事件元素是的话就返回true,这样我们通过下面的代码可以选择性的屏蔽鼠标右键了:
document.body.oncontextmenu=function(e){
return isTagName(e, ['A', 'TEXTAREA']);
}
三、JQuery版的选择性屏蔽禁止文本选择
同样的对于其他的操作也可以选择性的屏蔽,在JQuery支持的环境中我在StackOverflow找到了这么一篇文章《How to disable text selection using jQuery?》,虽然是讲解的禁止选择的,不过可以借鉴一下,具体代码如下:
(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外还给相关元素添加了某些特殊浏览器支持的CSS特性,这样基本可以实现大多数浏览器的兼容,同时这段代码还屏蔽了键盘按键选择Ctrl+A和Ctrl+C,不得不佩服作者周到的考虑。
四、进一步完善:屏蔽鼠标点击操作
我在测试这段代码时遇到一个问题就是点击除input、select、textarea外的元素时会全部选择页面,原文作者给出一个简单的方法就是在使用代码上附加.on('mousedown', false),这样就屏蔽了鼠标的单击,使用代码变成如下:
$(':not(input,select,textarea)').disableSelection().on('mousedown', false);
但是问题又来了,我发现采取上述代码后,input,select,textarea也开始变得不正常起来,看样子屏蔽mousedown的特性应用到所有元素上了。现在转换一下思路,结合刚才我提出的方案,判断event对象来实现选择性屏蔽,我将代码修正如下:
$(':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就不会限制mousedown了,我们将这段代码抽出为函数:
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版的选择性屏蔽禁止鼠标右键
对于右键菜单,我们可以这样处理:
$(document).bind("contextmenu",function(e){
if (!jQuery_isTagName(e, ['INPUT', 'TEXTAREA'])) {
e.preventDefault();
return false;
}
return true;
});
猜你喜欢
- 每次调用内部的方法时,方法前面加 self.举例:例子参考百度知道里面的回答class MyClass: def __init_
- 如何使用Iframe实现本页提交?例:chunfeng.html< html>< head>&n
- 前言实际工作中,偶尔遇到如下情况,例如使用Pandas计算如下相关系数,并把结果写入Excel文件中。correlations = df.c
- 安装 SQL2000 时,系统经常会提示:操作被挂起,要求重新启动计算机,如图1: 图1重新启动后,再次安装时问题仍然存在。解决办
- //实例化上传类$upload = new Zend_File_Transfer();//设置过滤器,大小限制为5M,格式为jpg,gif,
- Oracle关系型数据库管理系统是世界上流行的关系数据库,它是一个极其强大、灵活和复杂的系统,据说,在使用oracle时应有这样的思想,那就
- 问题发现在七月份时,经常发现有几个定时任务报错,查看了下异常原因,大概定位是数据库执行异常### Error querying databa
- 利用python开发了一个提取sim.log 中的各个关键步骤中的时间并进行统计的程序:#!/usr/bin/python2.6import
- HTML5 是近十年来 Web 标准最巨大的飞跃。和以前的版本不同,HTML 5 并非仅仅用来表示 Web 内容,它的使命是将 W
- 原文地址:30 Days of Mootools 1.2 Tutorials - Day 13 - Regular ExpressionsM
- 程序运行前加载1.导包前面加下划线,运行前加载2.把要加载的写在init函数里面路由设置路由的作用:根据不同的请求指定不同的控制器路由函数:
- 需求问题在日常工作中,对于前端发送过来的请求,后端django大部分都是采用json格式返回,也有采用模板返回视图的方式。在模板返回视图的方
- 具体代码如下所述:__author__ = 'Yue Qingxuan'# -*- coding: utf-8 -*-#求质
- 本文实例讲述了python登录豆瓣并发帖的方法。分享给大家供大家参考。具体如下:这里涉及urllib、urllib2及cookielib常用
- 一、运算符 . [] () 属性存取及函数调用 delete new typeof + - ! 一元运算符 * / % 乘法,除法,取模 +
- 我就废话不多说了,大家还是直接看代码吧~#! python3# -*- coding: utf-8 -*-import os, codecs
- 本文主要内容:聚类算法的特点聚类算法样本间的属性(包括,有序属性、无序属性)度量标准聚类的常见算法,原型聚类(主要论述K均值聚类),层次聚类
- 本文实例讲述了Python3删除排序数组中重复项的方法。分享给大家供大家参考,具体如下:给定一个排序数组,你需要在[原地]删除重复出现的元素
- 1. 正则表达式基础1.1. 简单介绍正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个
- 前言:中文编码问题一直是程序员头疼的问题,而Python2中的字符编码足矣令新手抓狂。本文将尽量用通俗的语言带大家彻底的了解字符编码以及Py