防止用户在浏览器上复制文本 [英] Prevent user from copying text on browsers
问题描述
我正在尝试使用JavaScript开发打字速度竞赛。人们应该把他们从div看到的所有单词写成textarea。
I'm trying to develop a typing speed competition using JavaScript. People should write all the words they see from a div to a textarea.
为了防止作弊(比如从div复制单词),一种方法是只检查写入的单词时键盘键已关闭,但我想知道是否有办法阻止用户在浏览器中复制文本?
To prevent cheating (like copying the words from div) one way is check the written words only when a keyboard key is down, but I was wondering if there is a way to prevent the user from copying the text in a browser?
到目前为止我尝试了什么:
What I have tried so far:
- 禁用右键单击(在移动浏览器上不起作用)
- 使用onmousedown显示提醒所有页面中的事件(它也不起作用)
使用任何库都没问题。
推荐答案
感谢您提供惊人的解决方案。我测试了所有这些,简而言之,其中一些仅在PC上运行,一些仅在Chrome和Firefox上运行,一些仅在 Safari ,但不幸的是,他们都没有100%工作。
Thanks for your amazing solutions. I tested all of them, and in short some of them worked only on a PC, some only on Chrome and Firefox and some only on Safari, but unfortunately none of them worked 100%.
虽然@Max答案可能最安全,但我没有在问题中使用PHP标记,因为如果我使用此解决方案处理答案,那将很难,因为我无法访问客户端上的文字!
Although @Max answer might be safest, I didn't tag with PHP in the question because if I use this solution dealing with answers, it will be hard because I don't have access to words on the client side!
所以我带来的最终解决方案是将所有提供的答案和一些新方法(比如每秒清除剪贴板)组合成一个jQuery插件。现在它也适用于多个元素,并在PC浏览器,Firefox,Chrome和Safari上100%工作。
So the ultimate solution I came with was combining all of the provided answers plus some new methods (like clearing the clipboard every second) into a jQuery plugin. Now it works on multiple elements too and worked 100% on PC browsers, Firefox, Chrome, and Safari.
- 防止粘贴(可选)
- 清除剪贴板(看起来不起作用)
- 吸收所有触摸事件
- 禁用右键单击
- 禁用用户选择
- 禁用指针事件
- 在任何选定的DOM中添加带有z-index的掩码
- 在任何选定的上添加透明div DOM
- Prevent pasting (optional)
- Clearing clipboard (looks like it doesn't work well)
- Absorbs all touch events
- Disable right click
- Disable user selections
- Disable pointer events
- Add a mask with a z-index inside any selected DOM
- Add a transparent div on any selected DOM
A jsFiddle :
A jsFiddle:
(function($) {
$.fn.blockCopy = function(options) {
var settings = $.extend({
blockPasteClass : null
}, options);
if(settings.blockPasteClass){
$("." + settings.blockPasteClass ).bind('copy paste cut drag drop', function (e) {
e.preventDefault();
return false;
});
}
function style_appender(rule){
$('html > head').append($('<style>'+rule+'</style>'));
}
function html_appender(html){
$("body").append(html);
}
function clearClipboard() {
var $temp = $("#bypasser");
$temp.val("You can't cheat !").select();
document.execCommand("copy");
}
function add_absolute_div(id) {
html_appender("<div id='noClick"+id+"' onclick='return false;' oncontextmenu='return false;'> </div>");
}
function absorbEvent_(event) {
var e = event || window.event;
e.preventDefault && e.preventDefault();
e.stopPropagation && e.stopPropagation();
e.cancelBubble = true;
e.returnValue = false;
return false;
}
function preventLongPressMenu(node) {
node.ontouchstart = absorbEvent_;
node.ontouchmove = absorbEvent_;
node.ontouchend = absorbEvent_;
node.ontouchcancel = absorbEvent_;
}
function set_absolute_div(element,id){
var position = element.position();
var noclick = "#noClick" + id;
$(noclick).css({
height: (element.height()),
width: (element.width()),
position: 'absolute',
top: position.top,
left: position.left,
'z-index': 100
})
}
$("body").bind("contextmenu", function(e) {
e.preventDefault();
});
//Append needed rules to CSS
style_appender(
"* {-moz-user-select: none !important; -khtml-user-select: none !important; -webkit-user-select: none !important; -ms-user-select: none !important; user-select: none !important; }"+
".content {position: relative !important; }" +
".content .mask {position: absolute !important ; z-index: 1 !important; width: 100% !important; height: 100%!important;}" +
".content a {position: relative !important; z-index: 3 !important;}"+
".content, .content .mask{ pointer-events: none;}"
);
//Append an input to clear the clipboard
html_appender("<input id='bypasser' value='nothing' type='hidden'>");
//Clearing clipboard Intervali
setInterval(clearClipboard,1000);
var id = 1;
return this.each( function() {
//Preventing using touch events
preventLongPressMenu($(this));
//Add CSS preventer rules to selected DOM & append mask to class
$(this).addClass("content").append("<div class='mask'></div>");
//Append an absolute div to body
add_absolute_div(id);
//Set position of the div to selected DOM
set_absolute_div($(this),id);
id++;
});
}
}(jQuery));
用法
Usage
$(document).ready(function(){
$(".words").blockCopy({
blockPasteClass : "noPasting"
});
});
用于演示的HTML:
HTML for demo:
<div class="words">Test1: Can you copy me or not?</div><br>
<div class="words">Test2: Can you <br> copy me or not?</div><br>
<textarea class="words">Test3: Can you <br>copy me or not?</textarea><br>
<textarea class="noPasting" placeholder="Test1: Paste content if you can" ></textarea><br>
<textarea class="noPasting" placeholder="Test2: Paste content if you can" ></textarea>
让我知道你的意见。谢谢。
Let me know your opinions. Thanks.
这篇关于防止用户在浏览器上复制文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!