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

Jaf*_*ali 12 html javascript css php jquery

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

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

到目前为止我尝试了什么:

  1. 禁用右键单击(在移动浏览器上无效)
  2. 在所有页面中使用onmousedown事件显示警报(它也不起作用)

使用任何库都可以.

Max*_*Max 12

您可以简单地将文本制作成图像.

<style type="text/css">
div.image {
    width: 100px;
    height: 100px;
    background-image: url-to-your-image;
}
</style>
Run Code Online (Sandbox Code Playgroud)

要生成图像,您可以使用服务器端脚本,如此问题的答案

或类似的东西:

<?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);
?> 
Run Code Online (Sandbox Code Playgroud)

在这里测试

  • 完美解决方案 解决了真正的XY问题. (5认同)
  • 如果用户使用的OCR不适用于打字文本应该没有问题 (2认同)

gya*_*rus 6

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

.noselect {
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
Run Code Online (Sandbox Code Playgroud)
<p>this can be selected</p>
<p class="noselect">this can NOT be selected</p>
Run Code Online (Sandbox Code Playgroud)

但是用户仍然可以打开页面源并从那里复制它.

  • 'user-select'不是[标准](https://developer.mozilla.org/en-US/docs/Web/CSS/user-select),可能不适合在Mozilla MDN上使用:**非标准**此功能是非标准的,不在标准轨道上.不要在面向Web的生产站点上使用它:它不适用于每个用户.实现之间可能存在很大的不兼容性,并且行为可能在将来发生变化. (2认同)

Pra*_*man 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;}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

尝试使用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>
Run Code Online (Sandbox Code Playgroud)

资源

  • 我总是通过"检查元素"然后"删除节点"或添加"display:none;"来摆脱这个问题.在CSS中. (2认同)

Jaf*_*ali 2

感谢您提供出色的解决方案。我测试了所有这些,总之有些只能在 PC 上运行,有些只能在 Chrome 和 Firefox 上运行,有些只能在Safari上运行,但不幸的是它们都没有 100% 运行。

虽然@Max答案可能是最安全的,但我没有在问题中使用PHP标记,因为如果我使用这个解决方案处理答案,这将很困难,因为我无法访问客户端的单词!

因此,我提出的最终解决方案是将所有提供的答案加上一些新方法(例如每秒清除剪贴板)组合到一个 jQuery 插件中。现在它也适用于多种元素,并且在 PC 浏览器、Firefox、Chrome 和 Safari 上 100% 运行。


这个插件的作用

  1. 防止粘贴(可选)
  2. 清除剪贴板(看起来效果不太好)
  3. 吸收所有触摸事件
  4. 禁用右键单击
  5. 禁用用户选择
  6. 禁用指针事件
  7. 在任何选定的 DOM 内添加带有 z 索引的遮罩
  8. 在任何选定的 DOM 上添加透明 div

一个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));
Run Code Online (Sandbox Code Playgroud)

用法

$(document).ready(function(){

    $(".words").blockCopy({
        blockPasteClass : "noPasting"
    });

});
Run Code Online (Sandbox Code Playgroud)

演示 HTML:

<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>
Run Code Online (Sandbox Code Playgroud)

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

来源