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

相关推荐
majingming1233 小时前
FUNCTION
java·前端·javascript
A_nanda4 小时前
Vue项目升级
前端·vue3·vue2
SuperEugene4 小时前
Axios 接口请求规范实战:请求参数 / 响应处理 / 异常兜底,避坑中后台 API 调用混乱|API 与异步请求规范篇
开发语言·前端·javascript·vue.js·前端框架·axios
abigale035 小时前
【浏览器 API / 网络请求 / 文件处理】前端文件上传全流程:从基础上传到断点续传
前端·typescript·文件上传·vue cli
Setsuna_F_Seiei5 小时前
AI 对话应用之页面滚动交互的实现
前端·javascript·ai编程
新缸中之脑6 小时前
追踪来自Agent的Web 流量
前端
wefly20176 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
英俊潇洒美少年7 小时前
vue如何实现react useDeferredvalue和useTransition的效果
前端·vue.js·react.js
kyriewen117 小时前
给浏览器画个圈:CSS contain 如何让页面从“卡成PPT”变“丝滑如德芙”
开发语言·前端·javascript·css·chrome·typescript·ecmascript
英俊潇洒美少年7 小时前
react19和vue3的优缺点 对比
前端·javascript·vue.js·react.js