揭秘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文章时更加方便地复制代码。

相关推荐
Jiaberrr1 分钟前
小程序setData性能优化指南:避开坑点,让页面丝滑如飞
前端·javascript·vue.js·性能优化·小程序
m0_694845571 分钟前
HandBrake 是什么?视频转码工具使用与服务器部署教程
服务器·前端·pdf·开源·github·音视频
方安乐3 分钟前
react笔记之tanstack
前端·笔记·react.js
学嵌入式的小杨同学8 小时前
从零打造 Linux 终端 MP3 播放器!用 C 语言实现音乐自由
linux·c语言·开发语言·前端·vscode·ci/cd·vim
weixin_425543739 小时前
TRAE CN3.3.25 构建的Electron简易DEMO应用
前端·typescript·electron·vite·nestjs
Mr Xu_10 小时前
【Vue3 + ECharts 实战】正确使用 showLoading、resize 与 dispose 避免内存泄漏
前端·信息可视化·vue·echarts
0思必得010 小时前
[Web自动化] Selenium设置相关执行文件路径
前端·爬虫·python·selenium·自动化
雯0609~10 小时前
hiprint:实现项目部署与打印1-官网提供普通html版本
前端·html
不绝19111 小时前
UGUI——进阶篇
前端
Exquisite.11 小时前
企业高性能web服务器(4)
运维·服务器·前端·网络·mysql