文本复制

一.屏蔽复制原理

1.1 CSS user-select

.user-select-none {
  user-select: none; /* 别看了,就是我屏蔽了你的复制功能。将none改为text即可恢复复制 */
}

二、断点调试

2.1 整理资源

在开始前,我们需要先整理一下这个复制功能会涉及到哪些因素。

既然是复制,那就离不开快捷键Ctrl+C。既然有Ctrl键,那就可能会有ctrlKey事件,还有可能会有键盘码keyCode。除此之外,复制的话需要先选中内容,那就需要document.selectionwindow.getSelection()事件。还有那个一复制就出现的登录框。

事实上,他还用了jquery中的copy事件。好尴尬呀,我竟然忘记了这个。

有了上述提到的这些资源后,我便开始了一个个定位分析。这个分析过程是非常复杂的,也走了不少弯路。

2.2为什么一复制就出现登录框?

我原以为他是把document.selection事件改写了,所以上来我就把目标定位到了关键字document.selection上。

一堆断点下来,发现这个没什么用处。看来我的常识经验在这次判断中误导了我。

后面又挨个把上面提到的资源都测试了下,结果发现原来复制跟登录框有关!相关代码见下方↓↓↓

var n = function() {
  window.csdn.loginBox.show({
    spm: "1001.2101.3001.9440"
  })
};
$("#content_views").unbind("keydown").bind("keydown", function(e) {
  if (e.ctrlKey && 67 == e.keyCode)
    return n(),
    !1
}),
$("#content_views").unbind("copy").bind("copy", function(e) {
  return n(),
  !1
})

执行copy事件时会触发登录框.png ↓↓↓执行copy事件时会触发登录框

注意这里有一个copy复制事件。他先用unbind来解绑copy复制事件,紧接着又重新绑定了copy复制事件。重点是下面的一行代码。

return n(),
!1

这行代码乍看起来可能有些不太习惯,我们用if进行改写下吧。

if (n()) {
  return true
} else {
  return false
}

由于函数n()调用了登录弹窗显示方法且没有直接的返回值,所以默认返回undefined。由于undefined条件不成立,所以会直接进入else条件中。也就相当于在执行copy复制事件时,直接返回了return false。这就是为什么在复制后粘贴时无任何内容的根本原因!

三、破解之道

3.1、法一:解绑copy事件

打开控制台,粘贴解绑copy复制事件的代码即可复制文件内容。

$("#content_views").unbind("copy")

然后我们就能轻松复制文章内的内容了。

需要注意的是,如果是代码区块,还需要使用1.1中的方法解除CSS后才能复制哦~

代码块复制

一、分析“登录后复制”按钮是如何工作的

一、分析“登录后复制”按钮是如何工作的

先上一张图,我们在未登录时,鼠标移入代码块时,在右上角会显示一个“登录后复制”的按钮。点击按钮,就会弹出登录框。配图:弹出登录框.png↓↓↓ 弹出登录框

细心的看官会发现“登录后复制”对应的是一个类名为.hljs-buttondiv,而这个dom元素上并未绑定点击事件。配图:登录后复制按钮上未绑定事件.png↓↓↓ 登录后复制按钮上未绑定事件

这里补充一句,当我在测试此插件的时候,发现有的文章里面的代码块会跟本案例有些出入。但看官不用担心,因为逻辑是相通的,稍做修改即可破解复制权限的。如果实在搞不定,可以使用文末的插件哈。

那他是怎么实现一点击就出现登录框的呢?

1.1、事件委托

实际上此处用的是事件委托来实现,昨天的那个copy也是一样的哈。即:把子元素的事件绑定到父元素上。

核心代码就是onclick点击事件。

onclick="mdcp.signin(event)"

1.2、登录后的变化

如果登录过后,此处就会变成“复制”两个字。

此时onclick事件会发生变化。

onclick="mdcp.copyCode(event)"

所以说,我们只需要在未登录时让点击事件变成copyCode即可。

文本复制-参考文章
代码块复制-参考文章