hexo next代码片段添加代码块复制和长代码自动展开

kionf

添加鼠标移动到长代码块, 自动展开. 代码块复制按钮及定制

0x00 添加第三方js插件clipboard.js

./themes/next/source/lib/zclip/clipboard.min.js 新增


0x01 插入自定义javascript

新增custom.js文件, 目录如下

./themes/next/source/js/src/custom.js 新增

./themes/next/source/js/src/custom.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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
var browserHeight = document.documentElement.clientHeight || document.body.clientHeight;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
function createCopyBtns() {
// 创建复制button 对象
var $figure = $("figure .figcode");
if ($figure.length > 0) {
$(".post-body").before('<div id="copyBtn" ><span id="imgCopy" ><i class="fa fa-paste fa-fw"></i></span><span id="imgSuccess" style="display: none;color: #6FB76F;"><i class="fa fa-check-circle fa-fw" aria-hidden="true"></i></span>');
$figure.append('<div class="codePinBtn"><img id="imgSuccess" src="/article_images/png/Pin_green.png" style="border:none; width: 24px;"></div>');
}
var $codeArea = $("figure .code");
if ($codeArea.length > 0) {
function changeToSuccess(item) {
$imgOK = $("#copyBtn").find("#imgSuccess");
if ($imgOK.css("display") == "none") {
$imgOK.css({
opacity: 0,
display: "block"
});
$imgOK.animate({
opacity: 1
}, 1000);
setTimeout(function () {
$imgOK.animate({
opacity: 0
}, 2000);
}, 2000);
setTimeout(function () {
$imgOK.css("display", "none");
}, 4000);
}
;
};
var clipboard = new ClipboardJS('#copyBtn', {
// 定制筛选复制
target: function () {
var node = document.querySelector("[copyFlag]");
var child = node.querySelector(".diff-deletion");
if (child != null) {
var pre = node.querySelector("pre").cloneNode(true);
child = pre.querySelector(".diff-deletion");
while (child != null) {
pre.removeChild(child)
child = pre.querySelector(".diff-deletion");
}
var node = document.getElementById('tmpcopy');
if (node == null) {
node = document.createElement('div');
node.id = 'tmpcopy';
node.style.position = 'fixed';
node.style.width = '0';
node.style.height = '0';
document.body.appendChild(node);
}
node.innerHTML = '';
node.appendChild(pre);
}
return node;
},
isSupported: function () {
alert(this.support);
return document.querySelector("[copyFlag]");
}
});
clipboard.on('success',
function (e) {
e.clearSelection();
changeToSuccess(e);
var node = document.getElementById("tmpcopy");
if (node != null) node.innerHTML = '';
});
clipboard.on('error',
function (e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});
$("#copyBtn").hover(
function () {
$(this).stop();
$(this).css("opacity", 1);
},
function () {
$(this).animate({
opacity: 0
}, 2000);
}
);
}
}
function FigureHover(figure) {
// 移动鼠标拉伸显示代码
var block = $(figure).attr("block");
if (block != 1) {
var codeArea = $(figure).find(".code")[0];
var width_code = codeArea.clientWidth;
var width_Scroll = codeArea.scrollWidth;
var width_Margin = -parseInt($(figure).css("marginRight"));
$codePinBtn = $(figure).find(".codePinBtn");
var width_Hide = width_Scroll - (width_code - width_Margin);
if (width_Hide > 0) {
$(figure).stop();
$codePinBtn.stop();
var width_Main = $("#main").width();
var width_Base = $(".main-inner").width();
var width_Blank = (width_Main - width_Base) / 2 - 10;
if (width_Blank > 0) {
if (width_Hide < width_Blank) {
width_Margin = width_Hide; //空白区域足够直接显示 全部
} else {
width_Margin = width_Blank * 0.8;
}
$(figure).animate({marginRight: -width_Margin});
$codePinBtn.animate({opacity: 1});
}
}
;
}
;
};
function FigureHoverOut(figure) {
// 鼠标移除代码块
$("#copyBtn").animate({
opacity: 0
}, 2000);
var block = $(figure).attr("block");
if (block != 1) {
$(figure).stop();
$(figure).animate({marginRight: "0"});
var $codePinBtn = $(figure).find(".codePinBtn");
$codePinBtn.stop();
$codePinBtn.css({opacity: 0});
}
};
$("figure").hover(
// 鼠标移入代码块
function () {
FigureHover(this);
var block = $(this).attr("block");
//-------鼠标活动在代码块内
//移除之前含有复制标志代码块的 copyFlag
$("[copyFlag]").removeAttr("copyFlag");
//在新的(当前鼠标所在代码区)代码块插入标志:copyFlag
$(this).find(".code").attr("copyFlag", 1);
//获取复制按钮
$copyBtn = $("#copyBtn");
if ($copyBtn.lenght != 0) {
//获取到按钮的前提下进行一下操作
//停止按钮动画效果
//设置为 显示状态
//修改 复制按钮 位置到 当前代码块开始部位
//设置代码块 左侧位置
$copyBtn.stop();
$copyBtn.css("opacity", 0.8);
$copyBtn.css("display", "block");
$copyBtn.css("top", parseInt($copyBtn.css("top")) + $(this).offset().top - $copyBtn.offset().top + 3);
$copyBtn.css("left", -$copyBtn.width() - 3);
}
},
function () {
FigureHoverOut(this);
},
);
function btnPinClick() {
var figure = this.parentElement.parentElement;
var block = $(figure).attr("block");
if (block != 1) {
$(".post-body").css("transform", "none");
$(figure).attr("block", 1);
$(this).find("img").attr("src", "/article_images/png/Pin_red.png");
} else {
$(figure).attr("block", 0);
$(this).find("img").attr("src", "/article_images/png/Pin_green.png");
}
}
$("figure").unbind("dblclick").bind("dblclick", function () { //双击事件
var block = $(this).attr("block");
if (block != 1) {
$(".post-body").css("transform", "none");
$(this).attr("block", 1);
$(this).find(".codePinBtn img").attr("src", "/article_images/png/Pin_red.png");
} else {
$(this).attr("block", 0);
$(this).find(".codePinBtn img").attr("src", "/article_images/png/Pin_green.png");
}
})
$(window).resize(function () {
var block;
var width_Main = $("#main").width();
var width_Base = $(".main-inner").width();
var width_Blank = (width_Main - width_Base) / 2 - 10;
$copyBtn = $("#copyBtn");
if (width_Blank < $copyBtn.width()) {
$copyBtn.css("display", "none");
} else {
$copyBtn.css("display", "block");
}
$("figure[block='1']").each(function () {
block = $(this).attr("block");
if (block == 1) {
var width_This = $(this).width();
var width_Scroll = $(this)[0].scrollWidth;
var width_Margin = -parseInt($(this).css("marginRight"));
var width_Hide = width_Scroll - (width_This - width_Margin);
if (width_Hide > 0) {
//var width_Main = $("#main").width();
//var width_Base = $(".main-inner").width();
//width_Blank = (width_Main - width_Base) / 2 - 10;
if (width_Blank > 0) {
if (width_Hide < width_Blank) {
width_Margin = width_Hide; //空白区域足够直接显示 全部
} else {
width_Margin = width_Blank * 0.8;
}
$(this).css({
marginRight: -width_Margin
});
$(this).find(".codePinBtn").animate({
opacity: 1,
left: $(".post-body")[0].getBoundingClientRect().right + width_Margin - $(this).find(".codePinBtn").width()
});
}
}
}
});
});
$(document).ready(function () {
createCopyBtns();
$(".codePinBtn").unbind("click").bind("click", btnPinClick);
});

0x02 添加自动改变代码片段js

./themes/next/source/js/src/function.js 新增

./themes/next/source/js/src/function.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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
function getClass(tagName, className) //获得标签名为tagName,类名className的元素
{
if (document.getElementsByClassName) //支持这个函数
{
return document.getElementsByClassName(className);
} else {
var tags = document.getElementsByTagName(tagName); //获取标签
var tagArr = []; //用于返回类名为className的元素
for (var i = 0; i < tags.length; i++) {
if (tags[i].class == className) {
tagArr[tagArr.length] = tags[i]; //保存满足条件的元素
}
}
return tagArr;
}
}
function addEvent(obj, type, fn) {
if (obj.addEventListener) obj.addEventListener(type, fn, false);
else if (obj.attachEvent) obj.attachEvent('on' + type, fn);
else obj['on' + type] = fn;
}
function removeEvent(obj, type, fn) {
if (obj.removeEventListener) obj.removeEventListener(type, fn, false);
else if (obj.detachEvent) obj.detachEvent('on' + type, fn);
else obj['on' + type] = null;
};
function resizePos(obj, callback) {
if (typeof callback == "function") {
addEvent(window, 'scroll', function() {
callback(obj);
});
addEvent(window, 'resize', function() {
callback(obj);
});
}
}
function getBrowser(getVersion) {
//注意关键字大小写
var ua_str = navigator.userAgent.toLowerCase(),
ie_Tridents, trident, match_str, ie_aer_rv, browser_chi_Type;
//判断IE 浏览器,
//blog: http://blog.csdn.Net/aerchi/article/details/51697592
if ("ActiveXObject" in self) {
// ie_aer_rv: 指示IE 的版本.
// It can be affected by the current document mode of IE.
ie_aer_rv = (match_str = ua_str.match(/msie ([\d.]+)/)) ? match_str[1] :
(match_str = ua_str.match(/rv:([\d.]+)/)) ? match_str[1] : 0;
// ie: Indicate the really version of current IE browser.
ie_Tridents = { "trident/7.0": 11, "trident/6.0": 10, "trident/5.0": 9, "trident/4.0": 8 };
//匹配 ie8, ie11, edge
trident = (match_str = ua_str.match(/(trident\/[\d.]+|edge\/[\d.]+)/)) ? match_str[1] : undefined;
browser_chi_Type = (ie_Tridents[trident] || ie_aer_rv) > 0 ? "internet-explorer" : undefined;
} else {
//判断 windows edge 浏览器
// match_str[1]: 返回浏览器及版本号,如: "edge/13.10586"
// match_str[1]: 返回版本号,如: "edge"
//若要返回 "edge" 请把下行的 "ie" 换成 "edge"。 注意引号及冒号是英文状态下输入的
browser_chi_Type = (match_str = ua_str.match(/edge\/([\d.]+)/)) ? "edge" :
//判断firefox 浏览器
(match_str = ua_str.match(/firefox\/([\d.]+)/)) ? "firefox" :
//判断chrome 浏览器
(match_str = ua_str.match(/chrome\/([\d.]+)/)) ? "chrome" :
//判断opera 浏览器
(match_str = ua_str.match(/opera.([\d.]+)/)) ? "opera" :
//判断safari 浏览器
(match_str = ua_str.match(/version\/([\d.]+).*safari/)) ? "safari" : undefined;
}
//返回浏览器类型和版本号
var verNum, verStr;
verNum = trident && ie_Tridents[trident] ? ie_Tridents[trident] : match_str[1];
verStr = (getVersion != undefined) ? browser_chi_Type + "/" + verNum : browser_chi_Type;
return verStr;
}

0x03 插入到主题

新建文件 custom.swig ,目录如下:(相对目录为工程目录)

./themes/next/layout_custom/custom.swig 新增

1
2
3
<script type="text/javascript" src="/js/src/function.js"></script>
<script type="text/javascript" src="/lib/zclip/clipboard.min.js"></script>
<script type="text/javascript" src="/js/src/custom.js"></script>

修改文件 _layout.swig ,目录如下:(相对目录为工程目录)

./themes/next/layout/_layout.swig 修改

./themes/next/layout/_layout.swig
<!doctype html>
...
<html class="{{ html_class | lower }}" lang="{{ config.language }}">
<head>
...
</head>
<body itemscope itemtype="http://schema.org/WebPage" lang="{{ page.lang || page.language || config.language }}">
...
...
{% include '_third-party/mathjax.swig' %}
{% include '_third-party/scroll-cookie.swig' %}
{% include '_third-party/exturl.swig' %}
{% include '_custom/custom.swig' %}
</body>
</html>

0x04 更改button

./themes/next/source/css/_custom/button.styl 新增

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.codePinBtn{
flex: 0 0 auto;
opacity: 0;
z-index: 1000;
margin-left: -23px;
align-self: start;
}
#copyBtn {
opacity: 0;
position: fixed;
display: block;
z-index: 1000;
line-height: 1;
font-size: 1.5em;
left: 18px;
}

./themes/next/source/css/_custom/custom.styl 修改

...
@import button;

添加代码拉伸控制button文件greenred


剩下的自己鼓捣