注意
经验证,此方法仅适用于安全域下,否则会报 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文件。参考路径如下:
请注意:若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 = '复制';
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> `;
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上查看效果。