在日常搜索技术文章时,我们常常会遇到在CSDN上复制代码需要登录的情况。今天,我们就来深入探讨一下CSDN设置复制弹出登录框的原理,以及如何绕过这一限制实现代码的自由复制。
CSDN设置复制弹出登录框的原理
监听复制事件
CSDN主要通过JavaScript来监听页面的复制事件(copy事件)。当用户尝试复制页面上的内容时,就会触发预先设定好的事件处理函数,在这个函数中会弹出登录框。以下是示例代码:
javascript
document.addEventListener('copy', function (event) {
// 弹出登录框的逻辑
// 例如:显示登录模态框等操作
});
在这段代码中,document.addEventListener('copy', ...) 用于监听整个文档的复制事件。一旦用户执行复制操作,就会执行回调函数,在回调函数里可以编写弹出登录框的具体逻辑,比如显示一个模态框要求用户登录。
设置CSS样式
除了监听复制事件,CSDN还会通过设置CSS样式来间接限制用户复制。例如,使用 user-select: none 样式禁止用户选中页面上的文本,从而达到限制复制的目的。示例代码如下:
sql
pre, code {
user-select: none;
}
这段CSS代码将 pre 和 code 标签内的文本设置为不可选中,这样用户就无法直接复制这些代码内容了。
解决方案代码分析(把这段脚本添加至油猴就行啦)
下面我们来看一段解决CSDN复制弹出登录框问题的代码,它通过几个步骤实现了代码的自由复制。
ini
// ==UserScript==
// @name CSDN免登录复制
// @namespace http://tampermonkey.net/CSDN_
// @version 2025-04-23
// @description CSDN免登录代码复制,优化复制功能和用户体验
// @author JensenHuang
// @match https://blog.csdn.net/*/article/details/*
// @icon https://g.csdnimg.cn/static/logo/favicon32.ico
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
function addCss(code, id) {
const style = document.createElement("style");
const css = document.createTextNode(code);
style.setAttribute("data-id", id || "codebox-css");
style.appendChild(css);
document.head.appendChild(style);
}
function copyCodeCssFunc() {
const css = ` #content_views pre, #content_views pre code { -webkit-touch-callout: auto !important; -webkit-user-select: auto !important; -khtml-user-select: auto !important; -moz-user-select: auto !important; -ms-user-select: auto !important; user-select: auto !important; }`;
addCss(css);
}
function copyCodeFunc() {
copyCodeCssFunc();
// 内容区
var content_views = document.querySelector("#content_views");
content_views.replaceWith(content_views.cloneNode(true));
修改复制按钮,支持一键复制
const buttons = document.querySelectorAll(".hljs-button");
buttons.forEach((btn) => {
// 更改标题
btn.dataset.title = "复制";
// 移除点击事件
btn.setAttribute("onclick", "");
// 克隆按钮
var elClone = btn.cloneNode(true);
// 替回按钮
btn.parentNode.replaceChild(elClone, btn);
// 重新添加点击事件
elClone.addEventListener("click", (e) => {
// 实现复制
const target = e.target;
const parentPreBlock = target.closest("pre");
const codeBlock = parentPreBlock.querySelector("code");
navigator.clipboard.writeText(codeBlock.innerText);
console.log(codeBlock.innerText);
target.dataset.title = "复制成功";
setTimeout(() => {
target.dataset.title = "复制";
}, 1000);
e.stopPropagation();
e.preventDefault();
});
});
}
copyCodeFunc();
})();
具体步骤分析
修改CSS样式
通过 copyCodeCssFunc 函数,将代码块的 user-select 样式设置为 auto,使代码块可以被选中和复制。在 copyCodeCssFunc 函数中,定义了一段CSS代码,将 #content_views 下的 pre 和 pre code 标签的 user-select 属性设置为 auto,并通过 addCss 函数将这段CSS代码添加到文档的头部。这样,代码块就可以被正常选中了。

克隆复制按钮并重新绑定事件
遍历所有的复制按钮,移除原有的点击事件,克隆按钮并替换原按钮,然后重新绑定点击事件。在新的点击事件处理函数中,使用 navigator.clipboard.writeText 方法将代码块的内容复制到剪贴板,并显示复制成功的提示。具体来说,首先使用 document.querySelectorAll('.hljs-button') 获取所有的复制按钮,然后对每个按钮进行处理。移除原有的点击事件后,克隆按钮并替换原按钮,再为新按钮添加点击事件。在点击事件处理函数中,通过 navigator.clipboard.writeText 方法将代码块的内容复制到剪贴板,并将按钮的标题设置为"复制成功",1秒后再恢复为"复制"。
阻止事件传播和默认行为
在点击事件处理函数中,调用 e.stopPropagation() 阻止事件冒泡,调用 e.preventDefault() 阻止默认行为,确保复制操作不会触发其他不必要的事件。这样可以避免复制操作引发其他意外的事件,保证复制功能的正常运行。
通过以上分析,我们了解了CSDN设置复制弹出登录框的原理,以及如何通过代码绕过这一限制。希望这篇文章能帮助你在浏览CSDN文章时更加方便地复制代码。