0%

Blog 2:[Hexo教程]Hexo之代码块添加复制按钮

注意
经验证,此方法仅适用于安全域下,否则会报 navigator.clipboard Cannot read properties of undefined (reading ‘writeText‘)
安全域包括本地访问与开启TLS安全认证的地址,如 https 协议的地址、127.0.0.1 或 localhost 。
具体情况请参照 这里

请注意:本文转载Evan Zhong’s Blog,根据目前版本之Hexo和NexT进行了微调。

使用JavaScript实现之。


准备

本JS脚本适用于以下结构的代码块:

1
2
3
4
5
6
7
8
<figure class="highlight">
<table>
<tr>
<td class="gutter">...</td>
<td class="code"><pre><code>...</code></pre></td>
</tr>
</table>
</figure>

请注意:这是Hexo中大多数主题默认的代码块渲染结构。


创建JavaScript脚本

在Hexo博客项目的根目录下创建code-copy.js文件。参考路径如下:

1
/source/js/code-copy.js

请注意:若source目录下没有js文件夹,则手动创建之

并在code-copy.js文件中写入以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('figure.highlight').forEach((figure) => {
if (figure.querySelector('.copy-btn')) return;

const copyBtn = document.createElement('button');
copyBtn.className = 'copy-btn';
copyBtn.title = '复制';

// 缩小后的复制图标(14*15)
const copyIcon = `
<svg xmlns="http://www.w3.org/2000/svg" height="14" width="15" viewBox="0 0 24 24" fill="white">
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 18H8V7h11v16z"/>
</svg>
`;

// 成功后显示的勾(14*15)
const checkIcon = `
<svg xmlns="http://www.w3.org/2000/svg" height="14" width="15" viewBox="0 0 24 24" fill="#00cc66">
<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
</svg>
`;

copyBtn.innerHTML = copyIcon;

// 按钮样式(浅灰底、缩小)
Object.assign(copyBtn.style, {
position: 'absolute',
top: '8px',
right: '8px',
padding: '4px',
background: '#aaa',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
opacity: '0.85',
zIndex: 1000,
transition: 'opacity 0.2s ease',
boxShadow: '0 1px 3px rgba(0, 0, 0, 0.15)'
});

copyBtn.addEventListener('mouseover', () => copyBtn.style.opacity = '1');
copyBtn.addEventListener('mouseout', () => copyBtn.style.opacity = '0.85');

copyBtn.addEventListener('click', () => {
const code = figure.querySelector('td.code');
const text = code ? code.innerText : '';
navigator.clipboard.writeText(text).then(() => {
copyBtn.innerHTML = checkIcon;
setTimeout(() => {
copyBtn.innerHTML = copyIcon;
}, 1000);
});
});

figure.style.position = 'relative';
figure.appendChild(copyBtn);
});
});

引用JS脚本

打开此文件:

1
themes/next/layout/_partial/footer.swig

footer.swig文件中,找到</body>标签之前,添加以下代码:

1
<script src="/js/code-copy.js"></script>

请注意:如果找不到</body>标签,则可以尝试在footer.swig文件末尾添加之。


更新博客

运行Hexo三部曲:

1
2
3
hexo clean
hexo g
hexo d

可以输入hexo s在本地启动服务,访问https://localhost:4000查看效果。或者在GitHub Pages上查看效果。

-------------本文结束 感谢您的时间-------------

欢迎关注我的其它发布渠道