Hexo-pure改造计划——添加代码块复制按钮

温馨提示:点击页面下方以展开或折叠目录~

为代码块添加复制按钮

方法一(弃用)【应该是代码位置没插对】

原因:生成网页之后函数变了。虽然一开始弄的时候是好的,不知道咋回事。

作者说:坑:理论上可以在其他地方添加,但是必须保证代码在jq以及页面dom加载后运行。

正常应该是

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

addLoadEvent(()=>{
$('.highlight').each(function (i, e) {
var $wrap = $('<div>').addClass('highlight-wrap')
$(e).after($wrap)
$wrap.append($('<button>').addClass('copy-btn').append('copy').on('click', function (e) {
var code = $(this).parent().find(".code")[0].innerText

code += "\n/**\n* 感谢您复制代码,使用代码请注明引用出处\n* kajweb @ https://blog.iwwee.com\n*/"

var ta = document.createElement('textarea')
document.body.appendChild(ta)
ta.style.position = 'absolute'
ta.style.top = '0px'
ta.style.left = '0px'
ta.value = code
ta.select()
ta.focus()
var result = document.execCommand('copy')
document.body.removeChild(ta)

if(result)$(this).text('copy success')
else $(this).text('copy failed')

$(this).blur()
})).on('mouseleave', function (e) {
var $b = $(this).find('.copy-btn')
setTimeout(function () {
$b.text('copy')
}, 300)
}).append(e)
})
})

而我的却是

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

addLoadEvent(() =>{
$(".highlight").each(function(t, e) {
var n = $("<div>").addClass("highlight-wrap");
$(e).after(n),
n.append($("<button>").addClass("copy-btn").append("复制").on("click",
function(t) {
var e = $(this).parent().find(".code")[0].innerText,
n = document.createElement("textarea");
document.body.appendChild(n),
n.style.position = "absolute",
n.style.top = "0px",
n.style.left = "0px",
n.value = e,
n.select(),
n.focus();
e = document.execCommand("copy");
document.body.removeChild(n),
e ? $(this).text("复制成功") : $(this).text("复制失败"),
$(this).blur()
})).on("mouseleave",
function(t) {
var e = $(this).find(".copy-btn");
setTimeout(function() {
e.text("复制")
},
300)
}).append(e)
})
})

参考链接
为代码块增加复制按钮

添加全局函数 addLoadEvent

/themes/pure/source/js目录下打开application.js,在文件最后追加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}

/**
* 感谢您复制代码,使用代码请注明引用出处
* kajweb @ https://blog.iwwee.com
*/

新增按钮

pure默认情况下是没有代码复制功能的,此时需要对hexo增加复制代码块功能。
首先在/themes/pure/layout/_partial目录下新增article-copy-code.ejs,增加以下内容:

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<% if(theme.codeblock.copy_button.enable){ %>
<style>
.copy-btn {
display: inline-block;
padding: 6px 12px;
font-size: 13px;
font-weight: 700;
line-height: 20px;
color: #333;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
background-color: #eee;
background-image: linear-gradient(#fcfcfc, #eee);
border: 1px solid #d5d5d5;
border-radius: 3px;
user-select: none;
outline: 0;
}

.highlight-wrap .copy-btn {
transition: opacity .3s ease-in-out;
opacity: 0;
padding: 2px 6px;
position: absolute;
right: 4px;
top: 8px;
z-index: 2;
}

.highlight-wrap:hover .copy-btn,
.highlight-wrap .copy-btn:focus {
opacity: 1
}

.highlight-wrap {
position: relative;
}
</style>

<script>
addLoadEvent(()=>{
$('.highlight').each(function (i, e) {
var $wrap = $('<div>').addClass('highlight-wrap')
$(e).after($wrap)
$wrap.append($('<button>').addClass('copy-btn').append('<%= __("codeblock.copy_button") %>').on('click', function (e) {
var code = $(this).parent().find(".code")[0].innerText
<% if(theme.codeblock.copyright.enable){ %>
code += "<%= theme.codeblock.copyright.content %>"
<% } %>
var ta = document.createElement('textarea')
document.body.appendChild(ta)
ta.style.position = 'absolute'
ta.style.top = '0px'
ta.style.left = '0px'
ta.value = code
ta.select()
ta.focus()
var result = document.execCommand('copy')
document.body.removeChild(ta)
<% if(theme.codeblock.copy_button.result){ %>
if(result)$(this).text('<%= __("codeblock.copy_success") %>')
else $(this).text('<%= __("codeblock.copy_failure") %>')
<% } %>
$(this).blur()
})).on('mouseleave', function (e) {
var $b = $(this).find('.copy-btn')
setTimeout(function () {
$b.text('<%= __("codeblock.copy_button") %>')
}, 300)
}).append(e)
})
})
</script>
<% } %>

插入到页面

编辑/themes/pure/layout/layout.ejs,在</body>前面一行增加<%- partial('_partial/article-copy-code')%>

1
2
3
4
5
6
7
8

<%- body %>
<%- partial('_common/footer', null, {cache: !config.relative_link}) %>
<%- partial('_common/script', {post: page}) %>
<%- partial('_partial/article-copy-code') %>
</body>
</html>

理论上可以在其他地方添加,但是必须保证代码在jq以及页面dom加载后运行。

增加语言文件

/themes/pure/languages目录下选择对应的语言文件,在文件后面增加:

1
2
3
4
codeblock:
copy_button: 复制
copy_success: 复制成功
copy_failure: 复制失败

增加主题配置文件

打开themes/pure/_config.yml,在文件末尾添加

1
2
3
4
5
6
7
codeblock: 
copy_button:
enable: true
result: true
copyright:
enable: true
content:

方法二

参考链接
Hexo NexT 代码块复制功能
Hexo NexT 代码块复制功能