搭建自己的Hexo博客(4)

前言

搭建自己的Hexo博客(3)这篇文章,最近又对博客进行了一些简单优化,特地分享下。

正文

音乐问题

原来是直接使用的网易云音乐外链,考虑到音乐版权问题,可能以后外链失效影响到音乐播放。

故我将要使用的音乐文件迁移到了云服务器上,同时我们使用一款Hexo的音乐播放插件hexo-tag-aplayer

我们直接在package.json文件里添加hexo-tag-aplayer并使用npm install命令进行安装。

themes/next/layout/_custom/sidebar.swig文件里,我们原来使用的网易云外链,注释掉。

1
2
3
4
5
6
<!--网易云音乐外链,已废弃-->
<!--<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=70 src="//music.163.com/outchain/player?type=2&id=509313150&auto=0&height=66"></iframe>
<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=70 src="//music.163.com/outchain/player?type=2&id=34723470&auto=0&height=66"></iframe>
<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=70 src="//music.163.com/outchain/player?type=2&id=640866&auto=0&height=66"></iframe>
<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=70 src="//music.163.com/outchain/player?type=2&id=35345243&auto=0&height=66"></iframe>
<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=70 src="//music.163.com/outchain/player?type=2&id=512733081&auto=0&height=66"></iframe>-->

使用如下Aplayer相关加载代码。

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
<!--基于hexo-tag-aplayer的音乐播放器-->
<div id="aplayer-rWUYQYrx" class="aplayer aplayer-tag-marker" style="margin: 30px 0px 30px 0px;"></div>
<script>
var options = {
"narrow": false,//样式
"autoplay": false,//是否自动播放
"showlrc": 0,//是否显示歌词,需要有歌词文件
"mutex": true,//true的话播放时会暂停其它播放器
"theme": "#e6d0b2",//主题
"preload": "none", //预加载模式
"listmaxheight": "500px",//列表最大高度
"music": [
{
"title": "Sakura Tears",//显示的音乐名
"author": "Nigel Silin",//作家
"url": "http://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/Nigel%20Silin%20-%20Sakura%20Tears.mp3",//音乐文件路径
"pic": "http://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/music1.jpeg"//音乐图片
},
{
"title": "东京不太热",
"author": "封茗囧菌",
"url": "http://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/%E5%B0%81%E8%8C%97%E5%9B%A7%E8%8F%8C%20-%20%E4%B8%9C%E4%BA%AC%E4%B8%8D%E5%A4%AA%E7%83%AD.mp3",
"pic": "http://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/music2.jpeg"
},
{
"title": "春风吹",
"author": "锦零",
"url": "http://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/%E9%94%A6%E9%9B%B6%20-%20%E6%98%A5%E9%A3%8E%E5%90%B9%EF%BC%88Cover%20%E6%96%B9%E5%A4%A7%E5%90%8C%EF%BC%89.mp3",
"pic": "http://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/music3.jpeg"
},
{
"title": "Secret",
"author": "茶太",
"url": "https://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/%E8%8C%B6%E5%A4%AA%20-%20Secret.mp3",
"pic": "http://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/music4.jpeg"
},
{
"title": "secret base ~君がくれたもの~",
"author": "茅野愛衣,戸松遥,早見沙織",
"url": "https://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/%E8%8C%85%E9%87%8E%E6%84%9B%E8%A1%A3%2C%E6%88%B8%E6%9D%BE%E9%81%A5%2C%E6%97%A9%E8%A6%8B%E6%B2%99%E7%B9%94%20-%20secret%20base%20%7E%E5%90%9B%E3%81%8B%E3%82%99%E3%81%8F%E3%82%8C%E3%81%9F%E3%82%82%E3%81%AE%7E%20%2810%20years%20after%20Ver.%29.mp3",
"pic": "http://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/music5.jpeg"
},
{
"title": "ファンファーレ",
"author": "sumika",
"url": "https://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/sumika%20-%20%E3%83%95%E3%82%A1%E3%83%B3%E3%83%95%E3%82%A1%E3%83%BC%E3%83%AC.mp3",
"pic": "http://sakuratears.oss-cn-beijing.aliyuncs.com/blog/music/music6.jpeg"
}
]
};
options.element = document.getElementById("aplayer-rWUYQYrx");
var ap = new APlayer(options);
window.aplayers || (window.aplayers = []);
window.aplayers.push(ap);
</script>

这样我们部署后会看到音乐栏如下图所示,也是比较美观的。

upload successful

我们使用hexo-tag-aplayer还有一个好处,当我们想向一些文章里添加音乐时,只需在文章markdown文章中添加如下代码即可。

1
{% aplayer "Caffeine" "Jeff Williams" "caffeine.mp3" "picture.jpg" "lrc:caffeine.txt" %}

hexo-tag-aplayer是基于APlayer而构建的,有兴趣的同学可以看下APlayer,一款非常漂亮的H5音乐播放器。

相册问题

上篇文章简单制作了一个相册,但是不是很满意,最近又对相册做了些优化。大致想法如下:

  • 相册页应该支持Tab切换,可以按照不同类别进行区分
  • 原来瀑布流下拉加载有些问题,需要修复下
  • 照片处理时手动操作步骤应该尽量少且简单

根据以上问题,优化后的相册如下动图,可以看到更美观实用一些了。

upload successful

我简单把自己改动的代码分享下。

photo 文件夹下的index.md文件如下:

1
<div id = "ImageGrid" class="photo-record"><div class="tab"><div class="tab-item active">动漫</div><div class="tab-item">风景</div><div class="tab-item">TODO</div></div><div class="photoContent"><ul class="img-box-ul1 mainCont selected"></ul><ul class="img-box-ul2 mainCont"></ul><ul class="img-box-ul3 mainCont"></ul></div></div><div style="height:100px"></div>

样式如下,放在custom.styl里。

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
.photo-record{
width: 100%;
}
.photo-record .tab{
height:30px;
line-height:30px;
}
.photo-record .tab .tab-item{
display:inline-block;
width:60px;
text-align:center;
font-size:15px;
}
.photo-record .tab .tab-item.active{
color: #ff9a22;
border-bottom: 3px solid #ffc472;
}
.photoContent .mainCont {
display: none;
width:100%;
overflow: auto;
text-align: center;
}
.photoContent .mainCont.selected {
display: block;
}

photos.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
var photo = function() {
this.page = 1,
this.offset = 10,
this.flag = false,
this.init = function(index) {
if (this.flag) {
return;
}
this.flag = true;
var that = this;
$.getJSON("../js/src/photos.json", function(data) {
for (var i = 0; i < data.length; i++) {
if (i + 1 === index) {
that.render(that.page, data[i], index);
that.scroll(data[i], index);
}
}
});
},
this.render = function(page, data, index) {
var begin = (page - 1) * this.offset;
var end = page * this.offset;
if (begin >= data.length) return;
var imgNameWithPattern, imgName, imageSize, imageX, imageY, li = "";
for (var i = begin; i < end && i < data.length; i++) {
imgNameWithPattern = data[i].split(' ')[1];
imgName = imgNameWithPattern.split('.')[0]
imageSize = data[i].split(' ')[0];
imageX = imageSize.split('.')[0];
imageY = imageSize.split('.')[1];
li += '<div class="card" style="width:330px">' +
'<div class="img-box" style="height:' + 330 * imageY / imageX + 'px">' +
'<a data-fancybox="gallery" class="fancybox fancybox.image" href="http://sakuratears.oss-cn-beijing.aliyuncs.com/blog/photos/' + index + "/" + imgNameWithPattern + '?raw=true" data-caption="' + imgName + '">' +
'<img src="http://sakuratears.oss-cn-beijing.aliyuncs.com/blog/photos/' + index + "/" + imgNameWithPattern + '?raw=true"/>' +
'</a>' +
'</div>' +
'</div>'
}
var box = $(".img-box-ul" + index);
box.append(li);
box.lazyload();
this.minigrid(index);
},
this.minigrid = function(index) {
var grid = new Minigrid({
container: ".img-box-ul" + index,
item: '.card',
gutter: 12
});
grid.mount();
// $(window).resize(function() {
// grid.mount();
// });
},
this.scroll = function(data, index) {
var that = this;
$(window).scroll(function() {
var windowPageYOffset = window.pageYOffset;
var windowPageYOffsetAddHeight = windowPageYOffset + window.innerHeight;
var sensitivity = 0;
var grid = $("#ImageGrid");
var offsetTop = grid.offset().top + grid.height();
if (offsetTop >= windowPageYOffset && offsetTop < windowPageYOffsetAddHeight + sensitivity) {
that.render(++that.page, data, index);
}
})
}
};

(function() {
$(".photo-record .tab .tab-item").each(function (i,e) {
var tempPhoto = new photo();
$(e).click(function(){
$(this).addClass("active").siblings().removeClass("active");
$(".photo-record .photoContent .mainCont").eq(i).addClass("selected").siblings().removeClass("selected");
tempPhoto.init(i + 1);
});
});
$(".photo-record .tab .tab-item.active").click();
})();

从上面的photos.js我们可以看到photos.json应该为下面这种格式。

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
[
[
"3200.2000 photo-1-10.jpg",
"1920.1080 photo-1-1.jpg",
"1920.1080 photo-1-12.jpg",
"1920.1200 photo-1-11.jpg",
"1920.1200 photo-1-13.jpg",
"1920.1080 photo-1-14.jpg",
"1920.1200 photo-1-16.jpg",
"1920.1080 photo-1-15.jpg",
"1920.1186 photo-1-18.jpg",
"1920.1080 photo-1-19.jpg",
"1920.1080 photo-1-17.jpg",
"1024.610 photo-1-2.jpg",
"3160.2560 photo-1-20.jpg",
"2560.1440 photo-1-21.jpg",
"1920.1080 photo-1-22.jpg",
"3139.2203 photo-1-23.jpg",
"1024.1024 photo-1-24.jpeg",
"2200.1400 photo-1-3.jpg",
"1200.750 photo-1-4.jpg",
"3500.1898 photo-1-5.jpg",
"1080.1920 photo-1-6.jpg",
"1600.1120 photo-1-7.jpg",
"1728.1080 photo-1-8.jpg",
"1920.1080 photo-1-9.jpg"
],
[
"3968.2976 photo-2-1.jpg",
"2976.3968 photo-2-2.jpg"
],
[]
]

这就需要我们使用photosTools.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
"use strict";
const fs = require("fs");
const sizeOf = require('image-size');
const path = "source/images_backup/photos";
const output = "themes/next/source/js/src/photos.json";
var dimensions;
fs.readdir(path, function(err, dirents) {
if (err) {
return;
}
let arr = [];
for (let i = 0; i < dirents.length; i++) {
console.log(dirents);
if(dirents[i]===".DS_Store"){
continue;
}
fs.readdir(path + "/" + dirents[i], function(err, files) {
console.log(files);
let tempArr = [];
for (let j = 0; j < files.length; j++) {
fs.stat(path + "/" + dirents[i] + "/" + files[j], function(err, stats) {
if (!files[j].endsWith(".jpg") || files[j].endsWith(".jpeg")) {

}
if (err) {
return;
}
if (stats.isFile()) {
if (files[j].endsWith(".jpg") || files[j].endsWith(".jpeg") ||
files[j].endsWith(".mp4") || files[j].endsWith(".png") || files[j].endsWith(".gif")) {
dimensions = sizeOf(path + "/" + dirents[i] + "/" + files[j]);
console.log(dimensions.width, dimensions.height);
tempArr.push(dimensions.width + '.' + dimensions.height + ' ' + files[j]);
}
}
})
}
arr.push(tempArr);
});
if (i === dirents.length - 1) {
setTimeout(function() {
fs.writeFile(output, JSON.stringify(arr, null, "\t"), function() {});
}, 10000);
return;
}
}

});

同时原来的photos图片文件夹里,应该使用1,2,3…等文件夹,并将图片放入到这些文件夹中,至于1,2,3…和图片类型的对应关系,就需要自己配置就行了。

以上就是新的图片标签页面的一些设计。

可以看到我们创建了3个Tab页切换(如需更多,可以继续进行配置),每个Tab页对应一个photo对象,该对象会加载并渲染图片信息,每次加载10个,使用向下滚动我们可以加载更多,并使用fancbox美化图片样式。

由于需要知道图片宽高来美化图片样式,因此我们使用了NodeJs的fs和imagesize模块,用来读取文件并生成photos.json文件。

PS:弄完相册后,突然想到了视频相关的一些展示,这个在后面我会考虑美观等特性,考虑是否为博客添加视频功能,及添加的位置等一些要素。

屏蔽相关

我们为博客添加一些屏蔽功能,先上代码。

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
/**
* 屏蔽f12 审查元素
*/
document.onkeydown = function(){
if(window.event){
var e = window.event;
if(e.keyCode == 123) {
console.log("禁用F12键");
e.keyCode=0;
e.returnValue=false;
}
// if(e.keyCode == 13) {
// console.log("禁用Enter键");
// e.keyCode = 0;
// e.returnValue=false;
// }
// if(e.keyCode == 8) {
// console.log("禁用Backspace键");
// e.returnValue=false;
// }
var ctrlKey = e.ctrlKey || e.metaKey;
var shiftKey = e.shiftKey;
if(ctrlKey && shiftKey && e.keyCode == 73){
console.log("禁用Ctrl+Shift+I键");
e.keyCode=0;
e.returnValue=false;
}
}
}

/**
* 屏蔽右键菜单
* @param event
* @returns {boolean}
*/
document.oncontextmenu = function (event){
if(window.event){
event = window.event;
}try{
var the = event.srcElement;
if (!((the.tagName == "INPUT" && the.type.toLowerCase() == "text") || the.tagName == "TEXTAREA")){
return false;
}
return true;
}catch (e){
return false;
}
}

/**
* 屏蔽粘贴
* @param event
* @returns {boolean}
*/
document.onpaste = function (event){
if(window.event){
event = window.event;
}try{
var the = event.srcElement;
if (!((the.tagName == "INPUT" && the.type.toLowerCase() == "text") || the.tagName == "TEXTAREA")){
return false;
}
return true;
}catch (e){
return false;
}
}

/**
* 屏蔽复制
* @param event
* @returns {boolean}
*/
document.oncopy = function (event){
if(window.event){
event = window.event;
}try{
var the = event.srcElement;
if(!((the.tagName == "INPUT" && the.type.toLowerCase() == "text") || the.tagName == "TEXTAREA")){
return false;
}
return true;
}catch (e){
return false;
}
}

/**
* 屏蔽剪切
* @param event
* @returns {boolean}
*/
document.oncut = function (event){
if(window.event){
event = window.event;
}try{
var the = event.srcElement;
if(!((the.tagName == "INPUT" && the.type.toLowerCase() == "text") || the.tagName == "TEXTAREA")){
return false;
}
return true;
}catch (e){
return false;
}
}

/**
* 屏蔽选中
* @param event
* @returns {boolean}
*/
document.onselectstart = function (event){
if(window.event){
event = window.event;
}try{
var the = event.srcElement;
if (!((the.tagName == "INPUT" && the.type.toLowerCase() == "text") || the.tagName == "TEXTAREA")){
return false;
}
return true;
} catch (e) {
return false;
}
};

/**
* 尝试阻止开发者模式
* @type {HTMLElement}
*/
var fuck = document.createElement('div');
Object.defineProperty(fuck, 'id', {
get:function(){
console.log("Hello World!");
location.href="about:blank";
history.replaceState();
}
});
console.log(fuck);

我们将上述代码引入到博客代码中,就会欣然发现:

在博客页面上:

  • 鼠标右键审查元素失效
  • F12失效,Chrome浏览器下Ctrl+Shift+I启动开发者模式快捷键失效
  • 复制、粘贴、剪贴、鼠标选中元素失效
  • 开发者模式和博客页面是无法共存的

当然这并不能阻止大家获取到网站运行的代码,因为js、html或者图片等资源,一旦被加载到客户端,客户端就已经拿到代码了。

然而这仍然是有趣的一件事情。

我们这里主要就是监听一些键盘事件来对某些按键行为进行阻止,对于屏蔽了开发者模式,主要和Object.defineProperty这个属性相关,但这个属性一些低版本浏览器是不支持的。

总结

今天到这里就差不多了,我们对博客进行了一些优化操作,及简单介绍了如何进行这些操作,接下来我仍将去探寻博客一些可以优化的地方。

我的博客地址:https://www.sakuratears.top




-------------文章结束啦 ~\(≧▽≦)/~ 感谢您的阅读-------------

您的支持就是我创作的动力!

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