Last active 1 month ago

清空掘金代码块头部右侧原有按钮,仅保留一个自定义“复制代码段”按钮,点击后复制纯净代码文本(无行号、无HTML样式)

jetsung revised this gist 5 months ago. Go to revision

1 file changed, 2 insertions, 2 deletions

juejin.user.js

@@ -1,8 +1,8 @@
1 1 // ==UserScript==
2 2 // @name 掘金复制代码段
3 3 // @namespace https://docs.scriptcat.org/
4 - // @version 0.0.1
5 - // @description 清空掘金代码块头部右侧原有按钮,仅保留一个自定义“复制代码段”按钮,点击后复制纯净代码文本(无行号、无HTML样式)
4 + // @version 0.1.0
5 + // @description 免登录复制掘金代码片段
6 6 // @author You
7 7 // @match https://juejin.cn/post/*
8 8 // @icon https://www.google.com/s2/favicons?sz=64&domain=juejin.cn

jetsung revised this gist 5 months ago. Go to revision

1 file changed, 104 insertions

juejin.user.js(file created)

@@ -0,0 +1,104 @@
1 + // ==UserScript==
2 + // @name 掘金复制代码段
3 + // @namespace https://docs.scriptcat.org/
4 + // @version 0.0.1
5 + // @description 清空掘金代码块头部右侧原有按钮,仅保留一个自定义“复制代码段”按钮,点击后复制纯净代码文本(无行号、无HTML样式)
6 + // @author You
7 + // @match https://juejin.cn/post/*
8 + // @icon https://www.google.com/s2/favicons?sz=64&domain=juejin.cn
9 + // @downloadURL https://gist.asfd.cn/jetsung/juejin/raw/HEAD/juejin.user.js
10 + // @updateURL https://gist.asfd.cn/jetsung/juejin/raw/HEAD/juejin.user.js
11 + // @grant none
12 + // ==/UserScript==
13 +
14 + (function() {
15 + 'use strict';
16 +
17 + // 自定义按钮样式
18 + const customBtnStyle = {
19 + display: 'inline-block',
20 + padding: '2px 10px',
21 + marginLeft: '8px',
22 + fontSize: '13px',
23 + color: '#fff',
24 + backgroundColor: '#007fff',
25 + borderRadius: '6px',
26 + cursor: 'pointer',
27 + userSelect: 'none',
28 + transition: 'all 0.3s',
29 + boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
30 + };
31 +
32 + function addCustomCopyButton() {
33 + document.querySelectorAll('.code-block-extension-header').forEach(header => {
34 + const headerRight = header.querySelector('.code-block-extension-headerRight');
35 + if (!headerRight || headerRight.querySelector('.juejin-custom-copy-btn')) return;
36 +
37 + // 清空右侧所有原有按钮
38 + headerRight.innerHTML = '';
39 +
40 + // 创建自定义按钮
41 + const copyBtn = document.createElement('div');
42 + copyBtn.className = 'juejin-custom-copy-btn';
43 + copyBtn.textContent = '复制代码段';
44 + Object.assign(copyBtn.style, customBtnStyle);
45 +
46 + // 悬停与成功效果
47 + copyBtn.addEventListener('mouseenter', () => copyBtn.style.backgroundColor = '#0066cc');
48 + copyBtn.addEventListener('mouseleave', () => {
49 + if (copyBtn.textContent !== '复制成功') copyBtn.style.backgroundColor = '#007fff';
50 + });
51 +
52 + headerRight.appendChild(copyBtn);
53 +
54 + // 复制逻辑(更稳健的纯文本提取)
55 + copyBtn.addEventListener('click', async () => {
56 + const codeContainer = header.parentElement.querySelector('pre code') ||
57 + header.nextElementSibling?.querySelector('code') ||
58 + header.parentElement.querySelector('code.hljs');
59 +
60 + if (!codeContainer) {
61 + copyBtn.textContent = '无代码';
62 + setTimeout(() => copyBtn.textContent = '复制代码段', 2000);
63 + return;
64 + }
65 +
66 + let pureCode = '';
67 +
68 + // 优先尝试直接取 code 的纯文本(最干净)
69 + if (codeContainer.textContent) {
70 + pureCode = codeContainer.textContent.trim();
71 + } else {
72 + // 备选:逐行提取
73 + const lines = Array.from(codeContainer.querySelectorAll('div, span, .code-block-extension-codeLine'))
74 + .map(el => el.textContent || '');
75 + pureCode = lines.join('\n').trim();
76 + }
77 +
78 + // 去除可能的行号前缀(如果还有残留)
79 + pureCode = pureCode.replace(/^\s*\d+\s*/gm, '').trim();
80 +
81 + try {
82 + await navigator.clipboard.writeText(pureCode);
83 + copyBtn.textContent = '复制成功 ✓';
84 + copyBtn.style.backgroundColor = '#52c41a';
85 + setTimeout(() => {
86 + copyBtn.textContent = '复制代码段';
87 + copyBtn.style.backgroundColor = '#007fff';
88 + }, 2000);
89 + } catch (err) {
90 + console.error('复制失败', err);
91 + copyBtn.textContent = '复制失败';
92 + setTimeout(() => copyBtn.textContent = '复制代码段', 2000);
93 + }
94 + });
95 + });
96 + }
97 +
98 + // 页面初次加载
99 + window.addEventListener('load', addCustomCopyButton);
100 +
101 + // 动态监听(掘金是 SPA,内容会异步加载)
102 + const observer = new MutationObserver(addCustomCopyButton);
103 + observer.observe(document.body, { childList: true, subtree: true });
104 + })();
Newer Older