我正在尝试使用JavaScript开发打字速度竞赛。人们应该将他们从div中看到的所有单词写成textarea。
为了防止作弊(比如从div复制单词),只有当键盘按键关闭时才能检查写入的单词,但我想知道是否有办法阻止用户在浏览器中复制文本?
到目前为止我尝试过:
使用任何库都可以。
答案 0 :(得分:12)
您可以简单地将文字制作成图像。
<style type="text/css">
div.image {
width: 100px;
height: 100px;
background-image: url-to-your-image;
}
</style>
要生成图像,您可以使用服务器端脚本,如this question
的下水道或类似的东西:
<?php
header("Content-type: image/png");
$im = @imagecreate(210, 30)
or die("Cannot Initialize new GD image stream");
$background_color = imagecolorallocate($im, 255, 255, 255);
$text_color = imagecolorallocate($im, 0, 0, 0);
imagestring($im, 4, 5, 5, "This is a test", $text_color);
imagepng($im);
imagedestroy($im);
?>
答案 1 :(得分:6)
您可以阻止用户实际选择文字以使其无法复制 - 但我仍然会将其与粘贴检测相结合,而不像其他人推荐的那样
.noselect {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
&#13;
<p>this can be selected</p>
<p class="noselect">this can NOT be selected</p>
&#13;
但是用户仍然可以打开页面源并从那里复制它。
答案 2 :(得分:5)
这样做的一个疯狂的方法是,在此基础上布置另一个绝对定位的元素。但这也不允许点击链接!您可以使用position: relative
和更高z-index
来完成此操作。
.content {position: relative;}
.content .mask {position: absolute; z-index: 1; width: 100%; height: 100%;}
.content a {position: relative; z-index: 3;}
<div class="content">
<div class="mask"></div>
<p>Pages that you view in incognito tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed <strong>all</strong> of your incognito tabs. Any files that you download or bookmarks that you create will be kept. <a href="https://support.google.com/chrome/?p=incognito">Learn more about incognito browsing</a></p>
</div>
尝试使用touch
或longpress
事件。
<!DOCTYPE html>
<html>
<head>
<script>
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 init() {
preventLongPressMenu(document.getElementById('theimage'));
}
</script>
</head>
<body onload="init()">
<img id="theimage" src="http://www.google.com/logos/arthurboyd2010-hp.jpg" width="400">
</body>
</html>
答案 3 :(得分:4)
尝试在文本上放置透明div。 我在这里使用过jQuery。 这应该有用。
SELECT
......
......
Into #TempXML
FROM ConvertedToXML
WHERE ConvertedToXML.AsXml.exists('(//Field2[.="foo"])[1]', 'Varchar(10)') = 1;
答案 4 :(得分:3)
使用jQuery很容易禁用粘贴功能。例如,如果你有一个像这样的编辑字段:
<p id='someInput' contenteditable='true'>Here is the text</p>
然后,这段jQuery代码将禁用其上的粘贴功能:
$('#someInput').on('paste', function(e) {
return false;
});
答案 5 :(得分:3)
如果用户作弊,解决的一个好方法是将当前输入长度与最后输入长度进行比较。您可以使用数据属性来存储先前的值(或长度):
<textarea class="typing-only" data-temp=""></textarea>
jQuery的:
$(document).on('input', '.typing-only', function(){
if((this.value.length - 1) > $(this).data('temp').length){
alert('Cheat!');
}
$(this).data('temp', this.value);
});
答案 6 :(得分:3)
pointer-events: none
CSS pointer-events
允许您控制元素和鼠标之间的交互。设置为none
时,该元素永远不会成为鼠标事件的目标。
答案 7 :(得分:2)
您可以尝试使用:after 标记并使用内容:&#34;文字&#34 ;; 在css,AFAIK中进行样式设置,您无法选择:之前和:之后的内容。
答案 8 :(得分:2)
感谢您提供的惊人解决方案。我测试了所有这些,简而言之,其中一些仅在PC上工作,一些仅在Chrome和Firefox上工作,一些仅在Safari上工作,但不幸的是它们都没有100%工作。
虽然@Max答案可能最安全,但我没有在问题中使用PHP标记,因为如果我使用此解决方案处理答案,那将很难,因为我无法访问客户端上的文字!< / p>
所以我带来的最终解决方案是将所有提供的答案和一些新方法(比如每秒清除剪贴板)组合成一个jQuery插件。现在它也适用于多个元素,并在PC浏览器,Firefox,Chrome和Safari上100%工作。
(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));
$(document).ready(function(){
$(".words").blockCopy({
blockPasteClass : "noPasting"
});
});
<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>
让我知道你的意见。感谢。
答案 9 :(得分:2)
比接受的解决方案更简单的方法是简单地使用带有filltext
的画布元素
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.fillText("Can't copy this", 5, 30);
<canvas id="myCanvas"></canvas>
答案 10 :(得分:0)
您可以return false
处理jQuery的cut
copy
paste
事件。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(document).on("cut copy paste", function(event){
return false;
});
</script>
<textarea>Try to copy my text</textarea>