📢 新文章推送 · 每周更新优质内容 · 订阅更新 →
向下滚动
技术笔记

Lumin Blog 复制版权追加功能文档

AI 智能总结

Lumin Blog 复制版权追加功能文档

📌 概述

当读者在文章页面选中文字并执行复制操作(Ctrl+C / Cmd+C)时,系统会自动在剪贴板内容末尾追加版权声明信息,包括作者、文章标题、原文链接和版权声明。此功能无需任何配置即可生效。

🎯 一、功能说明

属性说明
生效范围仅文章详情页(.single-post .post-content 内)
触发方式选中文字后执行复制操作(键盘快捷键 / 右键菜单复制)
最低字数选中文字 ≥ 30 字时才追加(短文本不触发)
输出格式纯文本(text/plain)+ 富文本(text/html)双格式
配置需求零配置,自动从页面 DOM 提取信息

复制效果示例

选中原文

Hugo 是一个用 Go 语言编写的静态网站生成器,它的构建速度非常快……

粘贴后内容

Hugo 是一个用 Go 语言编写的静态网站生成器,它的构建速度非常快……


作者:Lumin 文章:Hugo 静态博客搭建指南 链接:https://example.com/posts/hugo-guide/ 声明:本文为原创文章,转载请注明出处。

🏗️ 二、代码结构

2.1 模块定义

定义在 assets/js/main.jsCopyCopyright 模块中:

 1var CopyCopyright = (function() {
 2  var MIN_LENGTH = 30;  // 最低触发字数
 3
 4  function init() {
 5    // 仅在文章页生效
 6    var article = document.querySelector('.single-post .post-content');
 7    if (!article) return;
 8
 9    document.addEventListener('copy', function(e) {
10      var selection = window.getSelection();
11      if (!selection || selection.rangeCount === 0) return;
12
13      var text = selection.toString();
14      if (text.length < MIN_LENGTH) return;
15
16      // 从页面 DOM 提取文章信息
17      var metaItems = document.querySelectorAll('.post-meta .meta-item');
18      var authorText = '';
19      if (metaItems.length > 0) {
20        authorText = metaItems[0].textContent.trim();
21      }
22      var titleEl = document.querySelector('.post-title');
23      var titleText = titleEl ? titleEl.textContent.trim() : '';
24      var permalink = window.location.href;
25
26      // 构建追加文本
27      var appendix = '\n\n' +
28        '-----------------------\n' +
29        '作者:' + authorText + '\n' +
30        '文章:' + titleText + '\n' +
31        '链接:' + permalink + '\n' +
32        '声明:本文为原创文章,转载请注明出处。';
33
34      // 写入剪贴板(纯文本 + 富文本双格式)
35      if (e.clipboardData && e.clipboardData.setData) {
36        e.preventDefault();
37        e.clipboardData.setData('text/plain', text + appendix);
38
39        var htmlAppendix = '<br><br><hr style="border:none;border-top:1px solid #ddd;margin:12px 0;">' +
40          '<p style="color:#888;font-size:13px;">' +
41          '作者:' + authorText + '<br>' +
42          '文章:<a href="' + permalink + '">' + titleText + '</a><br>' +
43          '声明:本文为原创文章,转载请注明出处。</p>';
44        e.clipboardData.setData('text/html', selection.toString() + htmlAppendix);
45      }
46    });
47  }
48
49  return { init: init };
50})();

2.2 模块注册

main.jsDOMContentLoaded 初始化列表中注册:

1var coreModules = [
2  // ... 其他模块
3  { name: 'CopyCopyright',    fn: CopyCopyright.init }
4];

🔍 三、核心逻辑详解

3.1 触发条件判断

 1用户执行复制操作
 2 3检查:当前页面是否为文章页?(.single-post .post-content 存在)
 4    ↓ 否 → 不绑定事件,功能不生效
 5    ↓ 是
 6检查:是否有选中的文字?(window.getSelection())
 7    ↓ 否 → 忽略
 8    ↓ 是
 9检查:选中文字长度 ≥ 30 字?
10    ↓ 否 → 仅复制原文,不追加版权
11    ↓ 是
12拦截 copy 事件 → 追加版权信息到剪贴板

3.2 为什么设置 30 字门槛?

场景选中字数是否追加原因
复制代码片段5-20 字❌ 不追加代码片段追加版权会破坏代码结构
复制文章标题5-15 字❌ 不追加标题本身已是引用信息
复制术语/关键词2-5 字❌ 不追加过短文字追加版权显得突兀
复制段落/章节30+ 字✅ 追加这才是需要保护的原创内容

3.3 双格式输出

剪贴板同时写入两种格式,适配不同的粘贴目标:

text/plain(粘贴到记事本、终端、纯文本编辑器):

1原文内容...
2
3-----------------------
4作者:Lumin
5文章:文章标题
6链接:https://example.com/posts/xxx/
7声明:本文为原创文章,转载请注明出处。

text/html(粘贴到 Word、富文本编辑器、邮件):

原文内容后跟随一条分隔线 + 灰色小字版权信息,链接可点击跳转。

3.4 信息提取来源

字段DOM 选择器来源说明
作者.post-meta .meta-item(第一个)文章元数据区的作者项
标题.post-title文章标题 <h1>
链接window.location.href当前页面 URL

⚙️ 四、自定义配置

4.1 修改最低触发字数

CopyCopyright 模块中修改 MIN_LENGTH 值:

1var MIN_LENGTH = 30;  // 改为 50 可提高门槛,改为 10 可降低门槛

4.2 修改版权声明文案

appendix 变量中修改追加的文本内容:

1var appendix = '\n\n' +
2  '-----------------------\n' +
3  '作者:' + authorText + '\n' +
4  '文章:' + titleText + '\n' +
5  '链接:' + permalink + '\n' +
6  '声明:本文为原创文章,转载请注明出处。';  // 修改此行

4.3 添加许可协议信息

如果站点配置了许可协议(如 CC BY-NC-SA 4.0),可以追加到版权信息中:

1var appendix = '\n\n' +
2  '-----------------------\n' +
3  '作者:' + authorText + '\n' +
4  '文章:' + titleText + '\n' +
5  '链接:' + permalink + '\n' +
6  '许可:CC BY-NC-SA 4.0\n' +
7  '声明:本文为原创文章,转载请注明出处。';

4.4 扩展生效范围

默认仅文章页生效。如需在其他页面也启用,修改 init() 中的选择器判断:

1// 原始:仅文章页
2var article = document.querySelector('.single-post .post-content');
3
4// 扩展:文章页 + 独立页面
5var article = document.querySelector('.single-post .post-content, .page-content');

🛡️ 五、与其他版权功能的协作

Lumin Blog 有三层版权保护机制,各司其职:

层级功能触发条件作用
1. 复制追加CopyCopyright 模块选中 ≥30 字后复制在剪贴板内容中追加版权信息
2. 底部声明文章页版权声明块文章页底部始终显示明确展示许可协议和转载要求
3. 代码复制CodeBlock 模块点击代码块复制按钮复制代码时显示"复制成功"提示

三层机制互补:

  • 复制追加:被动保护,读者复制时自动生效
  • 底部声明:主动展示,明确告知版权规则
  • 代码复制:特殊场景,代码块有独立的复制交互

🐛 六、常见问题

Q1: 复制代码块时也会追加版权吗?

不会。代码块的复制按钮使用 navigator.clipboard.writeText() API 直接写入剪贴板,不触发 copy 事件,因此 CopyCopyright 模块不会介入。而如果用户手动选中代码文字复制,由于代码通常较短(< 30 字),也不会触发追加。

Q2: 在手机浏览器上有效吗?

有效copy 事件在移动端浏览器上同样触发(长按选中文字 → 复制)。但部分移动端浏览器可能不支持 clipboardData.setData(),此时功能降级为仅复制原文。

Q3: 粘贴到微信/钉钉时格式对吗?

取决于目标应用。微信/钉钉等 IM 工具通常读取 text/html 格式,会显示带样式的版权信息(分隔线 + 灰色小字 + 可点击链接)。部分应用仅读取纯文本格式,则显示纯文本版本的版权信息。

Q4: 如何临时禁用此功能?

在浏览器开发者工具控制台执行:

1document.removeEventListener('copy', CopyCopyright.handler);

📊 七、性能指标

指标数值
DOM 查询次数3 次(init 时 1 次 + 每次 copy 时 2 次)
事件监听器1 个(document 级 copy 事件)
单次 copy 回调耗时< 0.5ms(字符串拼接 + setData)
内存占用~150 bytes(闭包变量)
对正常复制的影响选中 < 30 字时完全无影响

📁 八、相关文件索引

文件作用
assets/js/main.js CopyCopyright 模块核心逻辑:copy 事件监听 + 版权信息追加
layouts/_default/single.html L157-168文章底部版权声明块(视觉展示层)
layouts/_default/single.html L63-69文章标题和作者元数据(信息提取来源)
assets/js/main.js CodeBlock 模块代码块复制按钮(独立复制通道,不触发版权追加)
6 / 14
版权声明

本文作者 Lumin

本文链接 https://www.zhengquan.xyz/tech/copy-copyright-guide/

许可协议 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

请作者喝杯咖啡 ☕

  • 微信打赏
    微信支付
  • 支付宝打赏
    支付宝
点击按钮查看打赏二维码
🎁 推荐工具
试试这些实用在线工具,提升工作效率
前往工具集 →

留言评论

期待你的想法

评论加载中