揭秘CSDN复制弹出登录框原理及解决方案

在日常搜索技术文章时,我们常常会遇到在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代码将 precode 标签内的文本设置为不可选中,这样用户就无法直接复制这些代码内容了。

解决方案代码分析(把这段脚本添加至油猴就行啦)

下面我们来看一段解决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 下的 prepre code 标签的 user-select 属性设置为 auto,并通过 addCss 函数将这段CSS代码添加到文档的头部。这样,代码块就可以被正常选中了。

克隆复制按钮并重新绑定事件

遍历所有的复制按钮,移除原有的点击事件,克隆按钮并替换原按钮,然后重新绑定点击事件。在新的点击事件处理函数中,使用 navigator.clipboard.writeText 方法将代码块的内容复制到剪贴板,并显示复制成功的提示。具体来说,首先使用 document.querySelectorAll('.hljs-button') 获取所有的复制按钮,然后对每个按钮进行处理。移除原有的点击事件后,克隆按钮并替换原按钮,再为新按钮添加点击事件。在点击事件处理函数中,通过 navigator.clipboard.writeText 方法将代码块的内容复制到剪贴板,并将按钮的标题设置为"复制成功",1秒后再恢复为"复制"。

阻止事件传播和默认行为

在点击事件处理函数中,调用 e.stopPropagation() 阻止事件冒泡,调用 e.preventDefault() 阻止默认行为,确保复制操作不会触发其他不必要的事件。这样可以避免复制操作引发其他意外的事件,保证复制功能的正常运行。

通过以上分析,我们了解了CSDN设置复制弹出登录框的原理,以及如何通过代码绕过这一限制。希望这篇文章能帮助你在浏览CSDN文章时更加方便地复制代码。

相关推荐
walking95713 小时前
重新学习前端之TypeScript
前端·javascript·面试
walking95713 小时前
重新学习前端之Linux
前端·vue.js·面试
walking95713 小时前
重新学习前端之CSS
前端·vue.js·面试
walking95713 小时前
重新学习前端之Git
前端·vue.js·面试
walking95714 小时前
重新学习前端之小程序
前端
魔术师Grace14 小时前
AI让我退化成原始人了
前端·程序员
铁皮饭盒14 小时前
今天你会学到这些关键词
前端·后端
李剑一14 小时前
耗时 2 小时!我复刻了全网超火的通透 3D 水晶球动效,Vue3+Three.js 做出高级视觉特效
前端·three.js
oil欧哟14 小时前
🤔 很长时间没写文章了,分享一下最近的一些思考
前端·后端
Hello--_--World14 小时前
Vue指令:v-if vs v-show、v-if 与 v-for 的优先级冲突、自定义指令
前端·javascript·vue.js