hexo的fluid主题添加瀑布流懒加载相册功能

本文最后更新于:5 个月前

相册演示地址:https://www.aigisss.com/blog/photos/ ,当前演示环境基于hexo===5.2.0 , fluid===1.8.7,很大程度上参考了醉里挑灯赏猫的Hexo NexT 博客增加瀑布流相册页面这篇博客!在此感谢班班提供的帮助!!

创建相册页面

新建相册页 hexo new page photos,编辑 /source/photos/index.md,输入以下内容:

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
---
title: photos
date: 2020-12-30 19:04:03
layout: photo
---

<style>
.ImageGrid {
width: 100%;
max-width: 1040px;
margin: 0 auto;
text-align: center;
}
.card {
overflow: hidden;
transition: .3s ease-in-out;
border-radius: 8px;
background-color: #efefef;
padding: 1.4px;
}
.ImageInCard img {
padding: 0;
border-radius: 8px;
width:100%;
height:100%;
}
@media (prefers-color-scheme: dark) {
.card {background-color: #333;}
}
</style>

<div id="imageTab"></div>
<div class="ImageGrid"></div>

处理图片信息

为了加快图片的加载速度,我使用GitHub +jsDelivr的方式,网上有许多的教程,此处不再演示。文件夹结构如图:

主要功能是使用image-size( npm i -S image-size安装)访问照片文件夹,获取每张照片的大小和文件名,并生成对应的 json 文件:

cnpm i安装之后,把照片放在目录后,执行以下命令:

1
node gallery/create.js

如果报错,请注意检查保存本地照片的文件夹里有没有非图片类文件,特别是要删除如 .DS_Store 这样的隐藏文件。json 文件样例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[
{
"name": "广州一游",
"children": [
"1080.1440 圣心大教堂.jpg",
"1080.1440 广州塔顶夜晚景色.jpg",
"1080.1440 广州塔顶夜晚景色2.jpg",
"1080.1440 晚上广州塔.jpg",
"1080.1443 白天广州塔.jpg"
]
},
{
"name": "澳门游玩",
"children": [
"1080.1443 夜晚澳门巴黎铁塔.jpg",
"1443.1080 微信图片_20210108213615.jpg",
"1443.1080 微信图片_20210108213635.jpg",
"1443.1080 微信图片_20210108213645.jpg",
"1443.1080 微信图片_20210108213707.jpg",
"1080.1443 白天澳门巴黎铁塔.jpg"
]
}
]

photos.json拷贝到博客目录下的photos

加载 js和css文件

/source/js/ 目录下创建 photoWall.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
var imgDataPath = "/blog/photos/photos.json"; //图片名称高宽信息json文件路径
var imgPath = "https://cdn.jsdelivr.net/gh/Cenergy/images/gallery/"; //图片访问路径
var imgMaxNum = 50; //图片显示数量

var windowWidth =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
if (windowWidth < 768) {
var imageWidth = 145; //图片显示宽度(手机端)
} else {
var imageWidth = 250; //图片显示宽度
}

const photo = {
page: 1,
offset: imgMaxNum,
init: function () {
var that = this;
$.getJSON(imgDataPath, function (data) {
that.render(that.page, data);
//that.scroll(data);
that.eventListen(data);
});
},
constructHtml(options) {
const {
imageWidth,
imageX,
imageY,
name,
imgPath,
imgName,
imgNameWithPattern,
} = options;
const htmlEle = `<div class="card lozad" style="width:${imageWidth}px">
<div class="ImageInCard" style="height:${
(imageWidth * imageY) / imageX
}px">
<a data-fancybox="gallery" href="${imgPath}${name}/${imgNameWithPattern}"
data-caption="${imgName}" title="${imgName}">
<img class="lazyload" data-src="${imgPath}${name}/${imgNameWithPattern}"
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
onload="lzld(this)"
lazyload="auto">
</a>
</div>
</div>`;
return htmlEle;
},
render: function (page, data = []) {
this.data = data;
if (!data.length) return;
var html,
imgNameWithPattern,
imgName,
imageSize,
imageX,
imageY,
li = "";

let liHtml = "";
let contentHtml = "";

data.forEach((item, index) => {
const activeClass = index === 0 ? "active" : "";
liHtml += `<li class="nav-item" role="presentation">
<a class="nav-link ${activeClass} photo-tab" id="home-tab" photo-uuid="${item.name}" data-toggle="tab" href="#${item.name}" role="tab" aria-controls="${item.name}" aria-selected="true">${item.name}</a>
</li>`;
});
const [initData = {}] = data;
const { children = [],name } = initData;
children.forEach((item, index) => {
imgNameWithPattern = item.split(" ")[1];
imgName = imgNameWithPattern.split(".")[0];
imageSize = item.split(" ")[0];
imageX = imageSize.split(".")[0];
imageY = imageSize.split(".")[1];
let imgOptions = {
imageWidth,
imageX,
imageY,
name,
imgName,
imgPath,
imgNameWithPattern,
};
li += this.constructHtml(imgOptions);
});
contentHtml += ` <div class="tab-pane fade show active" role="tabpanel" aria-labelledby="home-tab">${li}</div>`;

const ulHtml = `<ul class="nav nav-tabs" id="myTab" role="tablist">${liHtml}</ul>`;
const tabContent = `<div class="tab-content" id="myTabContent">${contentHtml}</div>`;

$("#imageTab").append(ulHtml);
$(".ImageGrid").append(tabContent);
this.minigrid();
},
eventListen: function (data) {
let self = this;
var html,
imgNameWithPattern,
imgName,
imageSize,
imageX,
imageY,
li = "";
$('a[data-toggle="tab"]').on("shown.bs.tab", function (e) {
$(".ImageGrid").empty();
const selectId = $(e.target).attr("photo-uuid");
const selectedData = data.find((data) => data.name === selectId) || {};
const { children,name } = selectedData;
let li = "";
children.forEach((item, index) => {
imgNameWithPattern = item.split(" ")[1];
imgName = imgNameWithPattern.split(".")[0];
imageSize = item.split(" ")[0];
imageX = imageSize.split(".")[0];
imageY = imageSize.split(".")[1];
let imgOptions = {
imageWidth,
imageX,
imageY,
name,
imgName,
imgPath,
imgNameWithPattern,
};
li += self.constructHtml(imgOptions);
});
$(".ImageGrid").append(li);
self.minigrid();
});
},
minigrid: function () {
var grid = new Minigrid({
container: ".ImageGrid",
item: ".card",
gutter: 12,
});
grid.mount();
$(window).resize(function () {
grid.mount();
});
},
};
photo.init();

然后使用注册器将需要的js,css注入,在scripts/injector.js(如没有,则创建)中输入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
const { root: siteRoot = "/" } = hexo.config;
// layout为photo的时候导入这些js与css
hexo.extend.injector.register(
"body_end",
`
<link rel="stylesheet" href="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.css">
<script src="//cdn.jsdelivr.net/npm/minigrid@3.1.1/dist/minigrid.min.js"></script>
<script src="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/lazyloadjs/3.2.2/lazyload.js"></script>
<script defer src="${siteRoot}js/photoWall.js"></script>`,
"photo"
);

至此,已经能看到加载出图片了,但是假如不使用cdn或者其他懒加载策略的话会感觉很慢!!

参考:https://blog.dlzhang.com/posts/31/


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!