实现复制代码块的功能,效果:
我的提问
我在hexo-theme-yilia-plus主题上的提问:https://github.com/JoeyBling/hexo-theme-yilia-plus/issues/29
初级版
个人觉得这个功能还是挺重要的。
加强版
如果文章中有原创版权声明,复制时,会携带相关信息。
🙋Others
我自己也去查了下,找到的好像都是next主题的,没有yilia主题的,但是不太会转化……
参考链接:
- 工具:clipboard.js:https://github.com/zenorocha/clipboard.js,中文网:http://www.clipboardjs.cn/
- Hexo NexT 代码块复制功能:https://www.jianshu.com/p/3e9d614c1e77
- hexo-next 添加代码块复制功能:https://www.zhyong.cn/posts/ca02/
- Hexo–第二弹(包含复制代码块,和版权声明):https://www.jianshu.com/p/4d0020bde612
自己动手
因为回复比较慢,就自己动手去尝试了。
该文章也是基于next主题,迁移过来有些问题:
- next主题可能自带jQuery,故没有引入,但是yilia没有,需要引入。
- 会报错
ClipboardJS is not defined
,我这里直接改成了Clipboard
就可以了,后面找到原因了:是版本问题,https://github.com/zenorocha/clipboard.js/releases/v2.0.0,v2.0.0的变化:Changes constructor fromnew Clipboard()
tonew ClipboardJS()
#468。相关问题:
0.原理
在页面加载完毕后,使用js动态地为每一个代码块添加一个按钮,使用这个按钮复制代码块内容。
1.新建实现复制功能的js
H:\Hexo\themes\yilia\source\js\clipboard_use.js
/*页面载入完成后,创建复制按钮*/
!function (e, t, a) {
/* code */
var initCopyCode = function(){
var copyHtml = '';
copyHtml += '<button class="btn-copy" data-clipboard-snippet="">';
copyHtml += ' <i class="fa fa-globe"></i><span>copy</span>';
copyHtml += '</button>';
$(".highlight .code").before(copyHtml);
new Clipboard('.btn-copy', {
target: function(trigger) {
return trigger.nextElementSibling;
}
});
}
initCopyCode();
}(window, document);
2.引入js
在H:\Hexo\themes\yilia\layout\layout.ejs
文件的</body>
前引入:(作用:页面加载完再执行js)
<!-- 代码块复制功能 -->
<script src="https://cdn.jsdelivr.net/npm/clipboard@1/dist/clipboard.min.js"></script>
<script type="text/javascript" src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<!-- <script type="text/javascript" src="/js/clipboard.js"></script> -->
<script type="text/javascript" src="/js/clipboard_use.js"></script>
需要注意的问题:
- 前面提到:因为:
clipboard_use.js
中需要用到jQuery,而yilia没有引入jQuery,故需要引入。 - 对于
clipboard.js
的引入问题:根据github社区反馈,引入本地文件好像会出现问题(我本地测试就引入不了),故使用CDN引入。(有人反映CDN好像也会有问题,反正我没有遇到……) - 注意引入顺序:
jquery
和clipboard.js
需要在clipboard_use.js
之前引入。 <script>
标签问题,虽然HTML5标准里面没有严格要求标签一定要关闭,但是建议要关闭,不然可能会出现问题。这里我一开始没有关闭标签,就出现问题了,后面研究了很久才发现原来是这个问题。
3.添加样式
修改:H:\Hexo\themes\yilia\source\main.0cf68a.css
,在末尾添加下面代码(最好是pre .css~* .id, pre .id
下面,即代码块样式附近)
/* 这是原代码块 */
pre .css~* .id, pre .id {
color:#fd971f
}
/* 代码块复制按钮 */
.highlight {
/* 方便copy代码按钮(btn-copy)的定位 */
position: relative;
}
.btn-copy {
display: inline-block;
cursor: pointer;
background-color: #eee;
background-image: linear-gradient(#fcfcfc, #eee);
border: 1px solid #d5d5d5;
border-radius: 3px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-appearance: none;
font-size: 13px;
font-weight: 700;
line-height: 20px;
color: #333;
-webkit-transition: opacity .3s ease-in-out;
-o-transition: opacity .3s ease-in-out;
transition: opacity .3s ease-in-out;
padding: 2px 6px;
position: absolute;
right: 5px;
top: 5px;
opacity: 0;
}
.btn-copy span {
margin-left: 5px;
}
.highlight:hover .btn-copy {
opacity: 1;
}
/* 代码块复制按钮 */
成果
点击按钮后,会全选代码块,就复制成功了。
效果图:
动图:
问题讨论
乍一看效果还不错,但是还是存在问题:
- 如果代码块超出,会出现问题。虽然图标样式使用绝对定位,但是该按钮没有“固定”在代码块页面的右上角,仅仅是固定在当前页面的右上角,可能不好理解,截个图:
然后我去研究了下CSDN的样式,发现好像差不多,但是效果明显不一样啊。后面有空再研究吧。 - 虽然复制成功会全选代码块,但是不成功呢?不晓得?好像没反应。后期可能会添加对应设置(模仿CSDN):默认时“复制”,复制成功显示“复制成功”,几秒后再次显示“复制”,失败给出对应提示。
依赖升级
使用最新版本的clipboard.js–v2.0.4,CDN:https://cdn.jsdelivr.net/npm/clipboard@2.0.4/dist/,替换之前的,需要修改的地方:
1.改变引入源
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/clipboard@2.0.4/dist/clipboard.js"></script>
2.改变函数名
Clipboard
to ClipboardJS
new Clipboard('.btn-copy', {
target: function(trigger) {
return trigger.nextElementSibling;
}
});
改为:
new ClipboardJS('.btn-copy', {
target: function(trigger) {
return trigger.nextElementSibling;
}
});
文章首发于:hexo+yilia添加复制代码块的功能