最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 惊呆了,鼠标选一下就触发复制(document.copy )?原来是这样

    正文概述 掘金(lhyt)   2021-04-03   865

    现场复现

    用户只是简单的说了几句,大家都表示不可思议,都表示这不可能。最后屏幕共享的时候,果然如此,简直让人怀疑人生。一用鼠标选中了文本,页面就弹出不能复制,大概是这样的表现:

    惊呆了,鼠标选一下就触发复制(document.copy )?原来是这样

    选择文字的时候不手动复制都会触发copy

    远程控制排查问题

    首先打开控制台,把document.copy改写一下

    const cp =  document.oncopy.bind(document);
    document.oncopy = () => {
        console.log(1);
        cp();
        return false;
    }
    

    结果发现,选一下竟然真的还是弹出toast和打印了1

    惊呆了,鼠标选一下就触发复制(document.copy )?原来是这样

    接下来加了个断点,还是会触发,一样的过程,看起来也没啥区别。于是,开始怀疑用户的插件,瞄了一眼,没有任何可疑的插件,然后把她的Chrome扩展全部关掉,依然会复现

    此时想起一句话:90%可以通过重启解决,9%可以通过重装解决,1%只能通过买新电脑解决

    惊呆了,鼠标选一下就触发复制(document.copy )?原来是这样

    电脑重启了,继续远程控制。还是一样的问题,我说要不你多打开其他网站试试,任何网站都行。小姐姐还是很耐心的一个个操作给我看:“你看什么页面都ok,就你这有问题”。于是我随便试了几个页面,打开控制台输入oncopy,然后就立刻复现问题:

    document.oncopy = () => {
        console.log(1);
        return false;
    }
    

    "你看呐,所有的页面都有同样的问题~ 你再随便试多几个页面看看" ——其实我在查资料,看看是不是有我知识盲区之外的

    资料也没查到类似的问题,大概无奈的看着她操作了几分钟,我也一句话都没有说,对着电脑发呆。突然萌生一个念头:系统上的个性化设定

    check了一下输入法,搜狗,应该无影响。但是,在对方频繁操作中,有一个若隐若现的小logo引起我注意

    惊呆了,鼠标选一下就触发复制(document.copy )?原来是这样

    惊呆了,鼠标选一下就触发复制(document.copy )?原来是这样

    惊呆了,鼠标选一下就触发复制(document.copy )?原来是这样

    ?‍?:“我发现你这有一个小logo,是干嘛的”

    ?‍?:“一个翻译工具”

    ?‍?:“多动动看看,我想看清楚一点”

    ?‍?:“你看,放在这里,它就会翻译屏幕上的单词”

    ?‍?:“那你试一下翻译其他软件如ppt呢”

    ?‍?:“居然也可以喔”

    ?‍?:“那关掉这个翻译软件,再回来看看页面呢”

    ?‍?:“好像没问题了”

    ?‍?:“嗯,那就是这个软件的问题。我看有一个自动翻译你鼠标所在的英文的功能,这个功能的实现方式可能是:你鼠标放到英文上,它会触发系统的copy事件,可能是直接帮你复制或者是背后帮你按下按键。你再打开这个应用,先把这个功能关了吧”

    ?‍?:“哦,我知道了,有一个划词搜索的功能,应该跟他有关”

    惊呆了,鼠标选一下就触发复制(document.copy )?原来是这样

    关掉后,问题是解决了,还是很好奇:你这软件叫什么,我也下载来玩玩

    下载来玩玩

    下载回来开启,自己写了一个简单的demo,果然都复现了

    const C: React.FC = () => {
      const ref = React.useRef<HTMLDivElement>(null);
      React.useEffect(() => {
        document.oncopy = (): boolean => {
          Toast.error('禁止复制');// 仅仅一个toast,随便找个ui库吧
          return false;
        };
        document.onclick = (): void => {
          ref.current!.innerHTML += '你点击了页面<br />';
        };
        const handleKeydown = (e): void => {
          ref.current!.innerHTML += `你按下了${e.key}<br />`;
        };
        document.addEventListener('keydown', handleKeydown);
        return (): void => {
          document.oncopy = null;
          document.onclick = null;
          document.removeEventListener('keydown', handleKeydown);
        };
      }, []);
      return (
        <>
          <pre>
            我说 你是人间的四月天; 笑响点亮了四面风; 轻灵在春的光艳中交舞着变。 你是四月早天里的云烟,
            黄昏吹着风的软,星子在 无意中闪,细雨点洒在花前。
          </pre>
          <div>
            操作记录
            <div ref={ref} />
          </div>
        </>
      );
    };
    

    按照预期,如果不开欧路词典,我们复制页面的内容,将会弹出toast禁止复制,如下:

    惊呆了,鼠标选一下就触发复制(document.copy )?原来是这样

    开启了欧路词典,表现是这样:

    惊呆了,鼠标选一下就触发复制(document.copy )?原来是这样

    问题因此转化为,如何区分出欧路词典的copy

    解决方案

    我们使用一种最简单的方式,按下command(key为Meta)不弹起的时候,生产key的队列,当最后一个按下的是c,则消费生产者队列,往前搜索有没有按过command

    const Cpn: React.FC = () => {
      const ref = React.useRef<HTMLDivElement>(null);
      const providerQuene = React.useRef<string[]>([]);
    
      const triggerCopy = React.useCallback(() => {
        // 消费生产者队列的数据
        const last = providerQuene.current.pop();
        // 如果最后按下的是c,而且键盘不弹起,往前找是不是按下过command
        if (last === 'c' && providerQuene.current.includes('Meta')) {
          Toast.error('禁止复制');
        }
      }, [providerQuene]);
      React.useEffect(() => {
        document.oncopy = (): boolean => {
          triggerCopy();
          return false;
        };
        document.onclick = (): void => {
          ref.current!.innerHTML += '你点击了页面<br />';
        };
        const handleKeydown = (e: KeyboardEvent): void => {
          if (e.key === 'Meta') {
            providerQuene.current.push('Meta');
          }
          if (e.key === 'c') {
            providerQuene.current.push('c');
          }
          ref.current!.innerHTML += `你按下了${e.key}<br />`;
        };
        const handleKeyUp = ({ key }: KeyboardEvent): void => {
          key === 'Meta' && (providerQuene.current = []); // meta键弹起,清理生产者队列
        };
        document.addEventListener('keydown', handleKeydown);
        document.addEventListener('keyup', handleKeyUp);
        return (): void => {
          document.oncopy = null;
          document.onclick = null;
          document.removeEventListener('keydown', handleKeydown);
          document.removeEventListener('keyup', handleKeyUp);
        };
      }, []);
      return (
        <>
          <pre>
            我说 你是人间的四月天; 笑响点亮了四面风; 轻灵在春的光艳中交舞着变。 你是四月早天里的云烟,
            黄昏吹着风的软,星子在 无意中闪,细雨点洒在花前。
          </pre>
          <div>
            操作记录
            <div ref={ref} />
          </div>
        </>
      );
    };
    
    

    最后


    下载网 » 惊呆了,鼠标选一下就触发复制(document.copy )?原来是这样

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元