防止用户在浏览器上复制文本

时间:2015-09-26 10:30:13

标签: javascript php jquery html css

我正在尝试使用JavaScript开发打字速度竞赛。人们应该将他们从div中看到的所有单词写成textarea。

为了防止作弊(比如从div复制单词),只有当键盘按键关闭时才能检查写入的单词,但我想知道是否有办法阻止用户在浏览器中复制文本?

到目前为止我尝试过:

  1. 禁用右键单击(无法在移动浏览器上运行)
  2. 使用所有页面中的onmousedown事件显示提醒(它也没有效果)
  3. 使用任何库都可以。

11 个答案:

答案 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);
?> 

Test here

答案 1 :(得分:6)

您可以阻止用户实际选择文字以使其无法复制 - 但我仍然会将其与粘贴检测相结合,而不像其他人推荐的那样

&#13;
&#13;
.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;
&#13;
&#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>

尝试使用touchlongpress事件。

<!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>

Source

答案 3 :(得分:4)

尝试在文本上放置透明div。 我在这里使用过jQuery。 这应该有用。

SELECT 
    ......
    ......
Into #TempXML
FROM ConvertedToXML
WHERE ConvertedToXML.AsXml.exists('(//Field2[.="foo"])[1]', 'Varchar(10)') = 1;

这是一个小提琴 http://jsfiddle.net/lacrioque/tc4bwejn/

答案 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);
});

JSFiddle demo

答案 6 :(得分:3)

pointer-events: none

CSS pointer-events允许您控制元素和鼠标之间的交互。设置为none时,该元素永远不会成为鼠标事件的目标。

MDN definition page

答案 7 :(得分:2)

您可以尝试使用:after 标记并使用内容:&#34;文字&#34 ;; 在css,AFAIK中进行样式设置,您无法选择:之前和:之后的内容。

答案 8 :(得分:2)

感谢您提供的惊人解决方案。我测试了所有这些,简而言之,其中一些仅在PC上工作,一些仅在Chrome和Firefox上工作,一些仅在Safari上工作,但不幸的是它们都没有100%工作。

虽然@Max答案可能最安全,但我没有在问题中使用PHP标记,因为如果我使用此解决方案处理答案,那将很难,因为我无法访问客户端上的文字!< / p>

所以我带来的最终解决方案是将所有提供的答案和一些新方法(比如每秒清除剪贴板)组合成一个jQuery插件。现在它也适用于多个元素,并在PC浏览器,Firefox,Chrome和Safari上100%工作。

这个插件做什么

  1. 防止粘贴(可选)
  2. 清除剪贴板(看起来效果不佳)
  3. 吸收所有触摸事件
  4. 禁用右键单击
  5. 禁用用户选择
  6. 禁用指针事件
  7. 在任何选定的DOM中添加带有z-index的掩码
  8. 在任何选定的DOM上添加透明div
  9. 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;'>&nbsp;</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"
        });
    
    });
    

    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>
    

    让我知道你的意见。感谢。

    来源

答案 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>

JSFiddle example

答案 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>