📚 更多文档目录

🚀 搭建教程 | 1 - 📑 前置教程 | 2 - 🎈 主题调整 | 3 - ✨ 魔改教程 | 4 - 🐈 重构自用数据记录


本篇教程基于 Hexo 6.3.0 & Butterfly 4.8.5 为博主的魔改教程记录,以防自己日后因魔改迷失所记录 📝

本小节魔改内容不包括 顶部banner栏,如有需要请移步至 ✨ 第二章 - 三小节 | 魔改页前置

最后更新于 2023 年 08 月 04 日

230808 更新:新增适配Memos动态部署功能
(注:此版本230808的Memos数据处理暂时有些小问题,但能满足基本使用。此问题在下个版本会进行优化,现推荐选其他两种部署方式使用)

230804 更新:新增显示短文数量的设置功能

230803 更新:新增开启pajx时JSON加载的音乐功能

230802 更新:修复JSON加载导致的音乐功能错误;修复JSON载入导致时间戳混乱

230801 更新:新增适配JSON动态部署功能

230731 更新:新增静态部署版的视频说,适配bilibili以及video链接(动态部署版230802已适配)

Butterfly 即刻短文 静态版部署方案 参考 - Heo

todolist本地yml动态JSON动态Memos
瀑布流✔️支持支持✔️支持✔️支持
图片灯箱✔️支持支持✔️支持✔️支持
多图显示✔️支持支持✔️支持✔️支持
外部链接✔️支持支持✔️支持✔️支持
自定标识✔️支持✔️支持❌暂未适配
快速评论✔️支持✔️支持❌暂未适配
音乐模块✔️支持✔️支持⚠️仅支持网易云
视频模块✔️支持✔️支持⚠️仅支持bilibili

效果预览

iCat版动静态部署

创建数据

  • 创建 [blogRoot]/source/essay/index.md 页面,配置以下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
---
title: 即刻短文
date: 2023-01-17 13:38:17
type: essay
top_img: false
aside: false
top_page: true
top_bg: https://img.meuicat.com/banner
top_item: 即刻短文
top_title: 封の碎碎念
top_tips: 使用 即刻短文动态部署版 构建
top_link: /about/
top_text: 关于博主
---

<!-- 页面内容 -->
  • 创建 [blogRoot]/themes/butterfly/layout/includes/page/essay.pug 页面文件,并新增以下内容
    (注意该页面中可能存在部分 fontawesome 图标 需要自行替换)
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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#icat-bber
section.icat-timeline.icat-page-1
if page.essay_url
script.
(()=>{
const replaceSymbol = (str) => {
return str.replace(/[\p{P}\p{S}]/gu, "-")
}

let result = ""

fetch("!{url_for(page.essay_url)}")
.then(response => response.json())
.then(str => {
for(let i = 0; i < str.length; i++){
let listResult = ""
let essayNumber = parseInt(str[i].essay_number)
let essayList = str[i].essay_list
let lists = ""
let listsTips = ""
if (essayNumber === -1) {
lists = essayList
listsTips = `<div id="icat-bber-tips" style="color: var(--icat-secondtext);">- 已展开所有短文 -</div>`
} else {
lists = essayList.slice(0, essayNumber)
listsTips = `<div id="icat-bber-tips" style="color: var(--icat-secondtext);">- 只展开最近 ${essayNumber} 条短文 -</div>`
}

for(let j = 0; j < lists.length; j++){
let content = ""
let onclick = ""
if (lists[j].content === undefined || lists[j].content === null) {
content = ""
} else if (lists[j].content) {
content = `<p class="datacont">${lists[j].content}</p>`
onclick = `onclick="icatessay.commentText('${lists[j].content}')"`
}

let listImage = ""
let listImages = ""
if (lists[j].image) {
const image = lists[j].image
for(let e = 0; e < image.length; e++){
listImage += `
<div class="imgbox">
<a class="icat-bber-content-img" href="${image[e]}" target="_blank" data-fancybox="gallery" data-caption="">
<img src="${image[e]}" />
</a>
</div>`
}
listImages += `<div class="icat-bber-container-img">${listImage}</div>`
}

let video = ""
if (lists[j].video) {
if (lists[j].video.player) {
video = `<div class="icat-bber-video"><video src="${lists[j].video.player}" controls="controls" style="object-fit: cover;"></video></div>`
}
if (lists[j].video.bilibili) {
video = `<div class="icat-bber-video"><iframe src="${lists[j].video.bilibili}" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe></div>`
}
}

let aplayer = ""
if (lists[j].aplayer) {
aplayer = `<div class="icat-bber-music"><div class="aplayer no-destroy" data-id="${lists[j].aplayer.id}" data-server="${lists[j].aplayer.server}" data-type="song" data-order="list" data-preload="none" data-autoplay="false" data-mutex="true" data-theme="var(--icat-main)"></div></div>`
}

let link = ""
if (lists[j].link) {
link = `<a class="icat-bber-content-link" target="_blank" title="跳转到短文指引的链接" href="${lists[j].link}" rel="external nofollow"><i class="iconfont icat-jump-link"></i>链接</a>`
}

let from = ""
if (lists[j].from) {
from = `<div class="icat-bber-info-from"><span>${lists[j].from}</span></div>`
}

listResult += `
<div class="icat-bber-item">
<div class="icat-bber-content">
${content}
${listImages}
${video}
${aplayer}
</div>
<hr>
<div class="icat-bber-bottom">
<div class="icat-bber-info">
<div class="icat-bber-info-time">
<i class="iconfont icat-time-fill"></i>
<time class="datatime" datetime="${lists[j].date}" style="display: inline;">${datedata}</time>
</div>
${link}
${from}
</div>
<div class="icat-bber-reply" ${onclick}>
<i class="iconfont icat-message"></i>
</div>
</div>
</div>`

var datedata = new Date(lists[j].date).toISOString()
}

result += `<div id="waterfall" class="list">${listResult}</div> ${listsTips}`
}

document.querySelector(".icat-page-1").insertAdjacentHTML("afterbegin", result)
window.lazyLoadInstance && window.lazyLoadInstance.update()

icatessay.changeTimeInEssay();
icatessay.reflashEssayWaterFall();
// 即刻短文

if (window.aplayers) {
for (let i = 0; i < window.aplayers.length; i++) {
if (!window.aplayers[i].options.fixed) {
window.aplayers[i].destroy()
}
}
}

typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

})
})()
else if page.memos_url
#waterfall.list
script.
(()=>{
fetch("!{url_for(page.memos_url)}").then(res => res.json()).then(data => {
let items = [],
html = '';
data.forEach(item => { items.push(Format(item)) });
document.getElementsByClassName('list')[0].innerHTML = items.map(item => item.content).join('');
});

function Format(item) {
let date = getTime(new Date(item.createdTs * 1000).toString()),
content = item.content,
imgs = content.match(/!\[.*\]\(.*?\)/g),
musics = content.match(/{\s*music\s*(.*)\s*}/g),
videos = content.match(/{\s*bilibili\s*(.*)\s*}/g);
text = '';
contents = '';

if (imgs) imgs = imgs.map(item => { return item.replace(/!\[.*\]\((.*?)\)/, '$1'); });

if (item.resourceList.length) {
if (!imgs) imgs = [];
item.resourceList.forEach(t => {
if (t.externalLink) imgs.push(t.externalLink);
else imgs.push(`{url}/o/r/${t.id}/${t.publicId}/${t.filename}`);
});
}

text = content.replace(/#(.*?)\s/g, '').replace(/\!\[(.*?)\]\((.*?)\)/g, '').replace(/\{(.*?)\}/g, '');
let link = '';
content = text.replace(/\[(.*?)\]\((.*?)\)/g, (match, p1, p2) => {
link = p2;
return ``;
});
contents = `<p class="datacont">${content}</p>`;

if (imgs) {
contents += `<div class="icat-bber-container-img">`;
imgs.forEach(e => contents += `<div class="imgbox"><a class="icat-bber-content-img" href="${e}" target="_blank" data-fancybox="gallery" data-caption=""><img src="${e}" /></a></div>`);
contents += '</div>';
}

if (musics) musics.forEach(item => { contents += `<div class="icat-bber-music"><div class="aplayer no-destroy" data-id="${item.replace(/{\s*music\s*(.*)\s*}/, '$1')}" data-server="netease" data-type="song" data-order="list" data-preload="none" data-autoplay="false" data-mutex="true" data-theme="var(--icat-main)"></div></div>` })
if (videos) videos.forEach(item => {
contents += `<div class="icat-bber-video"><iframe src="//player.bilibili.com/player.html?autoplay=0&bvid=${item.replace(/{\s*bilibili\s*(.*)\s*}/, '$1').replace(/.*video\/([^\/]*).*/, '$1')}" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe></div>`
})

let linkElement = '';
if (link) {
linkElement = `<a class="icat-bber-content-link" target="_blank" title="跳转到短文指引的链接" href="${link}" rel="external nofollow"><i class="iconfont icat-jump-link"></i>链接</a>`;
}

return {
content: `<div class="icat-bber-item"><div class="icat-bber-content">${contents}</div><hr><div class="icat-bber-bottom"><div class="icat-bber-info"><div class="icat-bber-info-time"><i class="iconfont icat-time-fill"></i><time class="datatime" datetime="${item.date}" style="display: inline;">${date}</time></div>${linkElement}</div></div></div>`,
date: date,
text: text.replace(/\[(.*?)\]\((.*?)\)/g, '[链接]' + `${imgs?'[图片]':''}`),
link: link
};
}

function getTime(time) {
var nol = function (h) { return h > 9 ? h : '0' + h }
var now = new Date()
var yesterday = new Date(now.getTime() - (1000 * 60 * 60 * 24)).toLocaleDateString()
var twoDaysAgo = new Date(now.getTime() - 2 * (1000 * 60 * 60 * 24)).toLocaleDateString()
let d = new Date(time),
ls = [d.getFullYear(), nol(d.getMonth() + 1), nol(d.getDate()), nol(d.getHours()), nol(d.getMinutes()), nol(d.getSeconds())],
day = d.toLocaleDateString()
if (day === now.toLocaleDateString()) {
return '今天 ' + ls[3] + ':' + ls[4]
} else if (day === yesterday) {
return '昨天 ' + ls[3] + ':' + ls[4]
} else if (day === twoDaysAgo) {
return '前天 ' + ls[3] + ':' + ls[4]
} else {
if (now.getFullYear() == ls[0]) return ls[1] + '月' + ls[2] + '日 ' + ls[3] + ':' + ls[4]
else return ls[0] + '-' + ls[1] + '-' + ls[2] + '- ' + ls[3] + ':' + ls[4]
}
}
})()
else
if site.data.essay
#waterfall.list
each i in site.data.essay
each item, index in i.essay_list
-
let lists = ""
let essayList = `9999`
var essayNumber = i.essay_number
if (essayNumber === -1) {
lists = essayList
} else {
lists = essayNumber
}
-
if index < lists
.icat-bber-item
.icat-bber-content
p.datacont= item.content
if item.image
.icat-bber-container-img
each iten, indey in item.image
.imgbox
a.icat-bber-content-img(href=item.image[indey], target="_blank", data-fancybox="gallery", data-caption="")
img(src=item.image[indey])
if item.video
.icat-bber-video
if item.video.bilibili
iframe(src=item.video.bilibili scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true")
else if item.video.player
video(src=item.video.player controls="controls" style="object-fit: cover;")
if item.aplayer
.icat-bber-music
.aplayer.no-destroy(data-id=item.aplayer.id data-server=item.aplayer.server data-type="song" data-order="list" data-preload="none" data-autoplay="false" data-mutex="true" data-theme='var(--icat-main)')
hr
.icat-bber-bottom
.icat-bber-info
.icat-bber-info-time
- var datedata = new Date(item.date).toISOString()
i.iconfont.icat-time-fill
time.datatime(datetime= item.date)= datedata
if item.link
a.icat-bber-content-link(target="_blank", title="跳转到短文指引的链接", href=item.link, rel="external nofollow")
i.iconfont.icat-jump-link
| 链接
if item.from
.icat-bber-info-from
span=item.from
.icat-bber-reply(onclick="icatessay.commentText(" + `'${item.content}'` + ")")
i.iconfont.icat-message
each l in site.data.essay
if l.essay_number === -1
#icat-bber-tips(style='color: var(--icat-secondtext);')
| - 已展开所有短文 -
else
#icat-bber-tips(style='color: var(--icat-secondtext);')
| - 只展开最近 #{l.essay_number} 条短文 -
  • 修改 [blogRoot]/themes/butterfly/layout/page.pug 来使页面匹配
    + 号直接删除 即是正常缩进)
1
2
3
4
5
6
7
8
9
    ···
case page.type
+ when 'essay'
+ include includes/page/essay.pug
when 'photo'
include includes/page/photo.pug
when 'tags'
include includes/page/tags.pug
···
  • _config.butterfly.yml 主题配置文件中开启站点的 pjax
1
2
3
4
5
6
7
8
9
10
# Pjax
# https://github.com/MoOx/pjax
# 当用户点击链接,通过ajax更新页面需要变化的部分,然后使用HTML5的pushState修改浏览器的URL地址;这样可以不用重复加载相同的资源(css/js), 从而提升网页的加载速度
# 使用pjax后,一些自己DIY的js可能会无效,跳转页面时需要重新调用;使用pjax后,一些个别页面加载的js/css,将会改为所有页面都加载
# --------------------------------------
pjax:
enable: true
exclude:
# - xxxx
# - xxxx
  • 新建 [blogRoot]/source/css/essay_page/essay_page.css 样式文件,并新增以下内容
    (也可以在自建的css文件里新增内容)
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
247
248
249
250
251
252
253
254
255
256
#icat-bber {
margin-top: 1.5rem;
width: 100%;
}
#icat-bber #waterfall.list {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
#icat-bber .icat-timeline #waterfall {
opacity: 0;
transition: .3s;
}
#icat-bber .icat-timeline #waterfall.show {
opacity: 1;
}
#icat-bber .icat-timeline #waterfall .icat-bber-item {
position: relative;
width: 32%;
border: var(--style-border-always);
border-radius: 12px;
padding: 1rem 1rem 0.9rem;
transition: all 0.3s ease 0s;
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: flex-start;
background: var(--icat-card-bg);
box-shadow: var(--icat-shadow-border);
margin-right: 2%;
animation: slide-in .6s .4s backwards;
}
#icat-bber > section > #waterfall > .icat-bber-item {
margin-bottom: 1rem;
}
#icat-bber .icat-timeline #waterfall .icat-bber-item:hover {
border: var(--style-border-hover);
}
@media screen and (max-width: 1300px) {
#icat-bber .icat-timeline #waterfall .icat-bber-item {
width: 49%;
margin-right: 1%;
}
}
@media screen and (max-width: 768px) {
#icat-bber .icat-timeline #waterfall .icat-bber-item {
width: 100%;
margin-right: 0px;
}
}
/* 响应式 */

#icat-bber div.icat-bber-content {
display: flex;
flex-flow: wrap;
border-radius: 12px;
width: 100%;
height: 100%;
}
#icat-bber p {
margin: 0px;
}
#icat-bber .icat-bber-content .datacont {
order: 0;
font-size: 0.8rem;
font-weight: 700;
color: var(--icat-fontcolor);
width: 100%;
line-height: 1.38;
border-radius: 12px;
margin-bottom: 0.8rem;
display: flex;
flex-direction: column;
text-align: justify;
padding: 0px 8px;
}
#icat-bber .icat-bber-container-img {
display: flex;
gap: 8px;
width: 100%;
flex-wrap: wrap;
margin-bottom: 10px;
padding-left: 8px;
}
#icat-bber .icat-bber-container-img .imgbox {
width: calc(100% / 4 - 8px);
aspect-ratio: 1 / 1;
overflow: hidden;
border-radius: 6px;
}
#icat-bber .icat-bber-container-img .imgbox .icat-bber-content-img {
height: 100px;
display: flex;
position: relative;
}
#icat-bber .icat-bber-container-img .imgbox .icat-bber-content-img img {
object-fit: cover;
width: 100%;
max-height: 100%;
border-radius: 6px;
animation: slide-in .6s .4s backwards;
}
#icat-bber .icat-bber-video {
position: relative;
padding: 30% 50%;
margin-bottom: 10px
}
#icat-bber .icat-bber-video video,
#icat-bber .icat-bber-video iframe {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
margin: 0;
border-radius: 6px;
border: var(--style-border);
}
#icat-bber .icat-bber-music {
width: 100%;
height: 90px;
margin: 0 0 0.5rem;
border-radius: 8px;
overflow: hidden;
border: var(--style-border-always);
background: var(--icat-secondbg);
}
#icat-bber .aplayer {
margin: 0;
}
#icat-bber .aplayer.aplayer-withlrc .aplayer-pic {
height: 82px;
width: 82px;
margin: 4px;
border-radius: 4px;
}
.icat-bber-music .aplayer.aplayer-withlrc .aplayer-info {
padding: 5px 7px 0;
}
#icat-bber .aplayer .aplayer-info .aplayer-music {
height: 23px;
text-align: center;
}
#icat-bber .aplayer .aplayer-info .aplayer-music .aplayer-title {
font-size: 0.8rem;
font-weight: 700;
margin: 0;
color: var(--icat-fontcolor);
}
#icat-bber .aplayer .aplayer-info .aplayer-controller {
align-items: center;
}
#icat-bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap {
padding: 0;
}
#icat-bber .aplayer .aplayer-info .aplayer-controller .aplayer-time {
position: initial;
}
#icat-bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar {
background: var(--icat-gray);
height: 8px;
border-radius: 12px;
transition: 0.3s;
overflow: hidden;
}
#icat-bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-loaded {
height: 100%;
border-radius: 12px;
}
#icat-bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played {
height: 100%;
border-radius: 12px;
}
#icat-bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played .aplayer-thumb {
display: none;
}
#icat-bber .aplayer .aplayer-info .aplayer-controller .aplayer-time {
position: initial;
}
#icat-bber .aplayer .aplayer-lrc p {
color: var(--icat-fontcolor);
}
#icat-bber .icat-timeline #waterfall .icat-bber-item hr {
display: flex;
position: relative;
margin: 8px 0px;
border: 1px dashed var(--icat-blue);
width: 100%;
opacity: 0.4;
}
#icat-bber .icat-bber-bottom {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 10px;
}
#icat-bber .icat-bber-info {
display: flex;
}
#icat-bber > section > #waterfall > .icat-bber-item > div .icat-bber-info-time,
#icat-bber > section > #waterfall > .icat-bber-item > div .icat-bber-info-from {
color: var(--icat-fontcolor);
font-size: 0.7rem;
background-color: var(--icat-gray-op);
padding: 0px 8px;
border-radius: 20px;
cursor: default;
display: flex;
align-items: center;
padding-right: 12px;
}
#icat-bber > section > #waterfall > .icat-bber-item > div .icat-bber-info-time > i {
padding-right: 4px;
}
#icat-bber > section > #waterfall > .icat-bber-item > div .icat-bber-info-from {
margin-left: 0.5rem;
}
#icat-bber > section > #waterfall > .icat-bber-item > div .icat-bber-info-from span {
margin-left: 0.35rem;
}
#icat-bber .icat-bber-content-link {
display: flex;
margin-left: 0.5rem;
font-size: 0.7rem;
align-items: center;
background-color: rgba(245, 108, 108, 0.13);
color: rgb(245, 108, 108);
padding: 0px 8px;
border-radius: 20px;
padding-right: 10px;
}
#icat-bber .icat-bber-content-link i {
margin-right: 4px;
}
#icat-bber .icat-bber-content-link:hover {
background-color: var(--icat-main);
color: var(--icat-white);
}
#icat-bber-tips {
font-size: 14px;
display: flex;
justify-content: center;
margin-bottom: 2rem;
}

[data-theme="dark"] #icat-bber .icat-timeline #waterfall .icat-bber-item hr {
opacity: 0.2;
}
[data-theme="dark"] #icat-bber .icat-bber-music .aplayer,
[data-theme="dark"] #icat-bber .aplayer .aplayer-lrc:before,
[data-theme="dark"] #icat-bber .aplayer .aplayer-lrc:after {
background: var(--icat-card-bg);
color: var(--icat-fontcolor);
}

/* 即刻短文样式 */
  • _config.butterfly.yml 主题配置文件中 inject 下的 head 引入 essay_page.css 样式文件
1
2
3
4
5
6
7
8
9
  ···

inject:
head:
- <link rel="stylesheet" href="/css/essay_page/essay_page.css"> # 即刻短文样式
bottom:
- ···

···
  • 创建 [blogRoot]/source/js/custom.js 文件,并新增以下内容,用来处理即刻短文的逻辑
    (或写在自建的公共 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
var percentFlag = false; // 节流阀
function essayScroll() {
let a = document.documentElement.scrollTop || window.pageYOffset; // 卷去高度
const waterfallResult = a % document.documentElement.clientHeight; // 卷去一个视口
waterfallResult <= 99 || (waterfallResult = 99);

if (
!percentFlag &&
waterfallResult + 100 >= document.documentElement.clientHeight &&
document.querySelector("#waterfall")
) {
// console.info(waterfallResult, document.documentElement.clientHeight);
setTimeout(() => {
waterfall("#waterfall");
}, 500);
} else {
setTimeout(() => {
document.querySelector("#waterfall") && waterfall("#waterfall");
}, 500);
}

const r = window.scrollY + document.documentElement.clientHeight;

let p = document.getElementById("post-comment") || document.getElementById("footer");

(p.offsetTop + p.offsetHeight / 2 < r || 90 < waterfallResult) && (percentFlag = true);
}

function replaceAll(e, n, t) {
return e.split(n).join(t);
}

var icatessay = {
diffDate: function (d, more = false) {
const dateNow = new Date();
const datePost = new Date(d);
const dateDiff = dateNow.getTime() - datePost.getTime();
const minute = 1000 * 60;
const hour = minute * 60;
const day = hour * 24;
const month = day * 30;

let result;

// Check if the suffix object and required properties exist
const suffix = GLOBAL_CONFIG.date_suffix || {};
const daySuffix = suffix.day || '天前';
const hourSuffix = suffix.hour || '小时前';
const minSuffix = suffix.hour || '分钟前';

if (more) {
const monthCount = dateDiff / month;
const dayCount = dateDiff / day;
const hourCount = dateDiff / hour;
const minuteCount = dateDiff / minute;

if (monthCount >= 1) {
result = datePost.toLocaleDateString().replace(/\//g, "-");
} else if (dayCount >= 1) {
result = parseInt(dayCount) + " " + daySuffix;
} else if (hourCount >= 1) {
result = parseInt(hourCount) + " " + hourSuffix;
} else if (minuteCount >= 1) {
result = parseInt(minuteCount) + " " + minSuffix;
} else {
result = suffix.just;
}
} else {
result = parseInt(dateDiff / day);
}
return result;
},

changeTimeInEssay: function () {
document.querySelector("#icat-bber") &&
document.querySelectorAll("#icat-bber time").forEach(function (e) {
var t = e,
datetime = t.getAttribute("datetime");
(t.innerText = icatessay.diffDate(datetime, true)), (t.style.display = "inline");
});
},
reflashEssayWaterFall: function () {
document.querySelector("#waterfall") &&
setTimeout(function () {
waterfall("#waterfall");
document.getElementById("waterfall").classList.add("show");
}, 500);
},
commentText: function (e) {
if (e == "undefined" || e == "null") e = "好棒!";
var n = document.getElementsByClassName("el-textarea__inner")[0],
t = document.createEvent("HTMLEvents");
if (!n) return;
t.initEvent("input", !0, !0);
var o = replaceAll(e, "\n", "\n> ");
(n.value = "> " + o + "\n\n"), n.dispatchEvent(t);
var i = document.querySelector("#post-comment").offsetTop;
window.scrollTo(0, i - 80),
n.focus(),
n.setSelectionRange(-1, -1),
document.getElementById("comment-tips") && document.getElementById("comment-tips").classList.add("show");
},
};

icatessay.changeTimeInEssay();
icatessay.reflashEssayWaterFall();
// 即刻短文处理逻辑
  • 创建 [blogRoot]/source/js/waterfall/waterfall.js 文件,并新增以下内容,用于处理瀑布流
    (或写在公共 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
function waterfall(a) {
function b(a, b) {
var c = window.getComputedStyle(b);
return parseFloat(c["margin" + a]) || 0;
}
function c(a) {
return a + "px";
}
function d(a) {
return parseFloat(a.style.top);
}
function e(a) {
return parseFloat(a.style.left);
}
function f(a) {
return a.clientWidth;
}
function g(a) {
return a.clientHeight;
}
function h(a) {
return d(a) + g(a) + b("Bottom", a);
}
function i(a) {
return e(a) + f(a) + b("Right", a);
}
function j(a) {
a = a.sort(function (a, b) {
return h(a) === h(b) ? e(b) - e(a) : h(b) - h(a);
});
}
function k(b) {
f(a) != t && (b.target.removeEventListener(b.type, arguments.callee), waterfall(a));
}
"string" == typeof a && (a = document.querySelector(a));
var l = [].map.call(a.children, function (a) {
return (a.style.position = "absolute"), a;
});
a.style.position = "relative";
var m = [];
l.length && ((l[0].style.top = "0px"), (l[0].style.left = c(b("Left", l[0]))), m.push(l[0]));
for (var n = 1; n < l.length; n++) {
var o = l[n - 1],
p = l[n],
q = i(o) + f(p) <= f(a);
if (!q) break;
(p.style.top = o.style.top), (p.style.left = c(i(o) + b("Left", p))), m.push(p);
}
for (; n < l.length; n++) {
j(m);
var p = l[n],
r = m.pop();
(p.style.top = c(h(r) + b("Top", p))), (p.style.left = c(e(r))), m.push(p);
}
j(m);
var s = m[0];
a.style.height = c(h(s) + b("Bottom", s));
var t = f(a);
window.addEventListener ? window.addEventListener("resize", k) : (document.body.onresize = k);
}

// 瀑布流
  • _config.butterfly.yml 主题配置文件中 inject 下的 bottom 引入 custom.jswaterfall.js
1
2
3
4
5
6
7
8
9
10
  ···

inject:
head:
- ···
bottom:
- <script async data-pjax src="/js/custom.js"></script> # 即刻逻辑文件
- <script async data-pjax src="/js/waterfall/waterfall.js"></script> # 即刻瀑布流JS

···

部署数据文件

  • 创建 [blogRoot]/source/_data/essay.yml 文件,并新增以下内容
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
- class_name: 即刻短文
essay_number: -1 # -1:显示全部;需填入整数如:10 或 100等
essay_list:
- content: 完噜 还剩一天让我咋准备 😭
date: 2023/07/31 15:30:50
from: iPhone XR
video:
player: /video/1.mp4

- content: 完噜 还剩一天让我咋准备 😭
date: 2023/07/31 15:30:50
from: iPhone XR
video:
bilibili: //player.bilibili.com/player.html?aid=913951276&bvid=BV1RM4y1p75T&cid=1211165267&page=1

- content: 完噜 还剩一天让我咋准备 😭
date: 2023/05/11 20:35:42
from: iPhone XR
image:
- https://s1.ax1x.com/2023/05/11/p9sKEh8.jpg

- content: 如果要定义 那就是下班后的日落和在家等我下班的她~
date: 2023/05/10 16:16:15
aplayer:
server: netease
id: 1949516216

- content: Melancholia - | 一款纯记录写作类Hexo主题 ✍️
date: 2023/04/23 22:27:22
from: Macbook Pro
link: https://github.com/yife68/Hexo-Theme-Melancholia

- content: 爱看 但还是得吃我一拳
date: 2023/04/22 15:10:30
from: iPhone XR
image:
- https://s1.ax1x.com/2023/05/03/p9JqGXd.jpg
- https://s1.ax1x.com/2023/05/03/p9Jq86H.jpg

- content: iCat 新启程
date: 2023/03/24 16:54:25
from: iPhone XR
link: https://meuicat.com/blog/14/
image:
- https://s1.ax1x.com/2023/05/02/p9GosYQ.jpg

- content: 各种观影史集于一体!人生足迹页诞生咯~
date: 2023/02/19 14:50:17
from: Macbook Pro
link: /collect/
  • 新增 [blogRoot]/source/essay/index.md 页面的 Post Front-matter 配置项 essay_url
1
2
3
4
5
6
7
---
···

essay_url: https://cdn.meuicat.com/gh/yife/essay.json
---

<!-- 文章内容 -->
  • 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
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
[
{
"class_name": "即刻短文",
"essay_number": "-1", // -1:显示全部;需填入整数如:10 或 100等
"essay_list": [
{
"content": "园长新造型!爱死",
"date": "2023/08/01 17:12:30",
"video": {
"bilibili": "//player.bilibili.com/player.html?aid=701381935&bvid=BV1dm4y1L7vj&cid=1212026428&page=1"
}
},
{
"content": "这辈子都不想完善项目了 😭 两点了 一看才搓完三分之一..",
"date": "2023/08/01 02:02:44",
"video": {
"player": "https://meuicat.com/video/1.mp4"
}
},
{
"content": "让我看看是谁在路上都还在敲键盘 噢 原来是我自己啊..",
"date": "2023/07/31 15:54:26",
"from": "iPhone XR"
},
{
"content": "落班 烧个排骨778~",
"date": "2023/07/26 17:55:36",
"from": "iPhone XR",
"image": [
"https://s1.ax1x.com/2023/07/26/pCjWbY4.jpg",
"https://s1.ax1x.com/2023/07/26/pCjWqfJ.jpg"
]
},
{
"content": "嘘..听歌..睡觉...",
"date": "2023/07/20 00:38:41",
"aplayer": {
"server": "netease",
"id": "1430702919"
}
},
{
"content": "人生应该是一个轴对称的形状,最后失去的,也就是最开始拥有的。现在没人记得你的生日,有好处也有坏处,至少我是这么理解的。但无论是好还是坏,忍一忍,都会很快过去的",
"date": "2023/07/19 01:48:36",
"from": "iPhone XR",
"link": "/blog/64"
},
{
"content": "用堆AI重绘一下我最爱的头像(图一 👉 图二)",
"date": "2023/07/06 16:30:32",
"from": "iPhone XR",
"link": "/blog/61",
"image": [
"https://yife68.gitee.io/icat-pic/posts/2023/7/10.webp",
"https://yife68.gitee.io/icat-pic/posts/2023/7/11.webp"
]
},
{
"content": "",
"date": "2023/06/30 08:26:22",
"aplayer": {
"server": "netease",
"id": "2009974513"
}
}
]
}
]
  • 新增 [blogRoot]/source/essay/index.md 页面的 Post Front-matter 配置项 memos_url
1
2
3
4
5
6
7
---
···

memos_url: https://memos.meuicat.com/api/v1/memo?creatorId=1&tag=说说&limit=10
---

<!-- 文章内容 -->

获取api地址
memos地址就是首页地址,如:memos.meuicat.com

  • 发送一条 公共 memos

  • 点击 探索 接着点击用户名

  • 查看URL获取ID

如url是:https://memos.meuicat.com/u/1
则creatorId就是1
最后完整链接如下:
https://memos.meuicat.com/api/v1/memo?creatorId=1&tag=说说&limit=10
能看到数据则为正确链接

注:&limit后面的数字是表示需要获取多少条数据内容

  • Memos用法:
1
2
3
4
5
6
7
8
#说说 {说说标签} 我是内容 [我是链接](链接地址) ![](图片链接)
<!-- 常规写法 -->

#说说 {music 29947420 }
<!-- 音乐写法 -->

#说说 22222 { bilibili https://m.bilibili.com/video/BV1WV4y1b7oa }
<!-- 视频写法 -->

数据参数释义

参数备选值/类型释义
class_nameString【可选】标识符,无实际意义,选填
essay_listArray【必选】即刻短文数据列表
essay_list.contentString【必选】短文 文字内容
essay_list.dateTime【必选】短文发布时间 格式建议为 2022/10/26 08:00:00
essay_list.imageArray【可选】短文图片内容, 可填写多张图片
essay_list.fromString【可选】短文 来自何处, 当然也可以填任何你想填写的标识
essay_list.linkString【可选】外部链接
essay_list.aplayerArray【可选】aplayer 播放器的单曲音乐, 需 aplayer 支持
essay_list.aplayer.serverString【essay_list.aplayer 后必选】aplayer 服务商
essay_list.aplayer.idString【essay_list.aplayer 后必选】单曲 id
essay_list.videoString【可选】视频播放器选项
essay_list.video.playerString【essay_list.video 后必选】video链接
essay_list.video.bilibiliString【essay_list.video 后必选】哔哩哔哩的嵌入代码链接

Heo版静态部署

todolist支持度
图片灯箱
多图片多行显示
外部链接
瀑布流
快速评论
本地修改 yml 发布

创建数据

  • 创建 [blogRoot]/source/essay/index.md 页面,配置以下内容
1
2
3
4
5
6
7
8
9
---
title: 即刻短文
date: 2023-01-17 13:38:17
type: essay
top_img: false
aside: false
---

<!-- 页面内容 -->
  • 创建 [blogRoot]/themes/butterfly/layout/includes/page/essay.pug 页面文件,并新增以下内容
    (注意该页面中可能存在部分 fontawesome 图标 需要自行替换)
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
#essay_page
.author-content.author-content-item.essayPage.single
.card-content
.author-content-item-tips 即刻短文
span.author-content-item-title 封の碎碎念
.content-bottom
.tips 使用 即刻短文静态部署版 构建
.banner-button-group
a.banner-button(onclick='pjax.loadUrl("/daily/")', data-pjax-state)
i.iconfont.icat-essay(style='font-size: 1rem')
span.banner-button-text 关于说说
#bber
section.timeline.page-1
ul#waterfall.list
each i in site.data.essay
each item, index in i.essay_list
if index < 200
li.bber-item
.bber-content
p.datacont= item.content
if item.image
.bber-container-img
each iten, indey in item.image
a.bber-content-img(href=item.image[indey], target="_blank", data-fancybox="gallery", data-caption="")
img(src=item.image[indey])
.bber-content-noimg
.bber-content-noimg
.bber-content-noimg
if item.aplayer
.bber-music
.aplayer.no-destroy(data-id=item.aplayer.id data-server=item.aplayer.server data-type="song" data-order="list" data-preload="none" data-autoplay="false" data-mutex="true" data-theme='var(--icat-essay-main)')
hr
.bber-bottom
.bber-info
.bber-info-time
- var datedata = new Date(item.date).toISOString()
i.iconfont.icat-time-fill
time.datatime(datetime= item.date)= datedata
if item.link
a.bber-content-link(target="_blank", title="跳转到短文指引的链接", href=item.link, rel="external nofollow")
i.fas.fa-link
| 链接
if item.from
.bber-info-from
i.far.fa-popsicle
span=item.from
.bber-reply(onclick="icat.commentText(" + `'${item.content}'` + ")")
i.iconfont.icat-message
#bber-tips(style='color: var(--icat-essay-secondtext);')
| - 已展开所有短文 -
  • 修改 [blogRoot]/themes/butterfly/layout/page.pug 来使页面匹配
    + 号直接删除 即是正常缩进)
1
2
3
4
5
6
7
8
9
    ···
case page.type
+ when 'essay'
+ include includes/page/essay.pug
when 'photo'
include includes/page/photo.pug
when 'tags'
include includes/page/tags.pug
···
  • 新建 [blogRoot]/source/css/essay_page/essay_page.css 样式文件,并新增以下内容
    (也可以在自建的css文件里新增内容)
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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
#page:has(#essay_page) {
border: 0;
box-shadow: none !important;
padding: 0 !important;
background: transparent !important;
}
#page:has(#essay_page) .page-title {
display: none;
}
#web_bg ~ .page:has(#essay_page) {
background: var(--icat-essay-background);
}
#bber .bber-container-img {
display: flex;
align-items: center;
justify-content: space-around;
width: 100%;
flex-wrap: wrap;
margin-bottom: 0.3rem;
}
#bber .bber-container-img .bber-content-noimg {
width: calc(100% / 4 - 5px);
}

#bber .bber-content-img img {
object-fit: cover;
max-height: 100%;
border-radius: 12px;
}

#bber .bber-content-img {
height: 100px;
border-radius: 12px;
overflow: hidden;
display: flex;
position: relative;
margin-bottom: 10px;
}

#bber .bber-content .datacont {
order: 0;
font-size: 0.8rem;
font-weight: 700;
color: var(--icat-essay-fontcolor);
width: 100%;
line-height: 1.38;
border-radius: 12px;
margin-bottom: 0.8rem;
display: flex;
flex-direction: column;
text-align: justify;
padding: 0px 8px;
}
#bber p {
margin: 0px;
}
#bber div.bber-content {
display: flex;
flex-flow: wrap;
border-radius: 12px;
width: 100%;
height: 100%;
}
#bber .timeline ul li.bber-item {
position: relative;
width: 32%;
border: var(--icat-style-border-always);
border-radius: 12px;
padding: 1rem 1rem 0.5rem;
transition: all 0.3s ease 0s;
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: flex-start;
background: var(--icat-essay-card-bg);
box-shadow: var(--icat-essay-shadow-border);
margin-right: 2%;
}
#bber .timeline #waterfall.show {
opacity: 1;
}
#bber .timeline #waterfall {
opacity: 0;
transition: all 0.3s ease 0s;
}
#bber ul.list {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
#bber {
margin-top: 1rem;
width: 100%;
}
#bber > section > ul > li.bber-item {
margin-bottom: 1rem;
}

#bber-tips {
font-size: 14px;
display: flex;
justify-content: center;
margin-top: 1rem;
}

#bber .timeline ul li.bber-item hr {
display: flex;
position: relative;
margin: 8px 0px;
border: 1px dashed var(--icat-essay-hr);
width: 100%;
}

#bber .bber-info {
display: flex;
}

#bber > section > ul > li > div .bber-info-time,
#bber > section > ul > li > div .bber-info-from {
color: var(--icat-essay-fontcolor);
font-size: 0.7rem;
background-color: var(--icat-essay-gray-op);
padding: 0px 8px;
border-radius: 20px;
cursor: default;
display: flex;
align-items: center;
padding-right: 10px;
}

#bber > section > ul > li > div .bber-info-time > i {
padding-right: 2px;
}

#bber .bber-info .far.fa-clock {
margin-right: 4px;
}
#bber > section > ul > li > div .bber-info-from span,
#bber > section > ul > li > div .bber-info-from {
margin-left: 4px;
}

#bber .bber-bottom {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 10px;
}

#bber .timeline ul li.bber-item:hover {
border: var(--icat-style-border-hover);
}

#bber .bber-content-link {
display: flex;
margin-left: 0.5rem;
font-size: 0.7rem;
align-items: center;
background-color: rgba(245, 108, 108, 0.13);
color: rgb(245, 108, 108);
padding: 0px 8px;
border-radius: 20px;
padding-right: 10px;
}
#bber .bber-content-link i {
margin-right: 3px;
}
#bber .bber-content-link:hover {
background-color: var(--icat-essay-main);
color: var(--icat-essay-white);
}
#bber .bber-music {
width: 100%;
height: 90px;
margin: 0.5rem 0;
border-radius: 8px;
overflow: hidden;
border: var(--icat-style-border-always);
background: var(--icat-essay-secondbg);
}
#bber .aplayer {
margin: 0;
}

#bber .aplayer.aplayer-withlrc .aplayer-pic {
height: 82px;
width: 82px;
margin: 4px;
border-radius: 4px;
}
.bber-music .aplayer.aplayer-withlrc .aplayer-info {
padding: 5px 7px 0;
}
#bber .aplayer .aplayer-info .aplayer-music {
height: 23px;
}
#bber .aplayer .aplayer-info .aplayer-music .aplayer-title {
font-size: 0.8rem;
font-weight: 700;
margin: 0;
color: var(--icat-essay-fontcolor);
}

#bber .aplayer .aplayer-info .aplayer-controller {
align-items: center;
}
#bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap {
padding: 0;
}
#bber .aplayer .aplayer-info .aplayer-controller .aplayer-time {
position: initial;
}
#bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar {
background: var(--icat-essay-gray);
height: 8px;
border-radius: 12px;
transition: 0.3s;
overflow: hidden;
}
#bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-loaded {
height: 100%;
border-radius: 12px;
}
#bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played {
height: 100%;
border-radius: 12px;
}
#bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played .aplayer-thumb {
display: none;
}
#bber .aplayer .aplayer-info .aplayer-controller .aplayer-time {
position: initial;
}

/* 顶部样式 */
.author-content.author-content-item.essayPage {
height: 19rem;
background: url(https://s1.ax1x.com/2023/05/02/p9GRHqe.jpg) left 28% / cover no-repeat;
color: var(--icat-essay-white);
overflow: hidden;
margin-top: 0px;
border-radius: 8px;
}
#page:has(#essay_page) .author-content-item .card-content .banner-button-group .banner-button:hover {
font-size: var(--icat-essay-font-color-op);
border-radius: 20px !important;
}

.author-content-item .card-content {
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 2;
display: flex;
flex-direction: column;
padding: 1rem 2rem;
}
.author-content-item .author-content-item-tips {
opacity: .8;
font-size: .6rem;
margin-bottom: 0.5rem;
}
.author-content-item .card-content .author-content-item-title {
margin-bottom: 0.5rem;
}
.author-content-item .author-content-item-title {
font-size: 36px;
font-weight: 700;
line-height: 1;
}
.author-content-item .content-bottom {
margin-top: auto;
display: flex;
align-items: center;
justify-content: space-between;
}
.author-content-item .card-content .banner-button-group .banner-button {
height: 40px;
width: 124px;
border-radius: 20px;
justify-content: center;
background: var(--icat-essay-card-bg);
color: var(--icat-essay-font-color);
display: flex;
align-items: center;
z-index: 1;
transition: .3s;
cursor: pointer;
border-bottom: 0!important;
}
.author-content-item .card-content .banner-button-group .banner-button i {
margin-right: 4px;
font-size: 1rem;
}
.banner-button-text {
padding-right: 5px;
}
.banner-button-group {
margin-top: 10px;
}

/* 响应式 */
@media screen and (max-width: 1300px) {
#bber .timeline ul li.bber-item {
width: 49%;
margin-right: 1%;
}
}
@media screen and (max-width: 768px) {
#bber .timeline ul li.bber-item {
width: 100%;
margin-right: 0px;
}
.author-content-item .card-content .banner-button-group .banner-button {
width: 40px;
}
.author-content-item .card-content .banner-button-group .banner-button i {
margin-right: 2px;
}
}
[data-theme="dark"] #bber .bber-music .aplayer,
[data-theme="dark"] #bber .aplayer .aplayer-lrc:before,
[data-theme="dark"] #bber .aplayer .aplayer-lrc:after {
background: var(--icat-essay-card-bg);
color: var(--icat-essay-fontcolor);
}
#bber .aplayer .aplayer-lrc p {
color: var(--icat-essay-fontcolor);
}
  • _config.butterfly.yml 主题配置文件中 inject 下的 head 引入 essay_page.css 样式文件
1
2
3
4
5
6
7
8
9
  ···

inject:
head:
- <link rel="stylesheet" href="/css/essay_page/essay_page.css"> # 即刻短文样式
bottom:
- ···

···
  • _config.butterfly.yml 主题配置文件中开启站点的 pjax
1
2
3
4
5
6
7
8
9
10
# Pjax
# https://github.com/MoOx/pjax
# 当用户点击链接,通过ajax更新页面需要变化的部分,然后使用HTML5的pushState修改浏览器的URL地址;这样可以不用重复加载相同的资源(css/js), 从而提升网页的加载速度
# 使用pjax后,一些自己DIY的js可能会无效,跳转页面时需要重新调用;使用pjax后,一些个别页面加载的js/css,将会改为所有页面都加载
# --------------------------------------
pjax:
enable: true
exclude:
# - xxxx
# - xxxx
  • 创建 [blogRoot]/source/js/custom.js 文件,并新增以下内容,用来处理即刻短文的逻辑
    (或写在自建的公共 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
var percentFlag = false; // 节流阀
function essayScroll() {
let a = document.documentElement.scrollTop || window.pageYOffset; // 卷去高度
const waterfallResult = a % document.documentElement.clientHeight; // 卷去一个视口
result <= 99 || (result = 99);

if (
!percentFlag &&
waterfallResult + 100 >= document.documentElement.clientHeight &&
document.querySelector("#waterfall")
) {
// console.info(waterfallResult, document.documentElement.clientHeight);
setTimeout(() => {
waterfall("#waterfall");
}, 500);
} else {
setTimeout(() => {
document.querySelector("#waterfall") && waterfall("#waterfall");
}, 500);
}

const r = window.scrollY + document.documentElement.clientHeight;

let p = document.getElementById("post-comment") || document.getElementById("footer");

(p.offsetTop + p.offsetHeight / 2 < r || 90 < result) && (percentFlag = true);
}
function replaceAll(e, n, t) {
return e.split(n).join(t);
}
var icat = {
diffDate: function (d, more = false) {
const dateNow = new Date();
const datePost = new Date(d);
const dateDiff = dateNow.getTime() - datePost.getTime();
const minute = 1000 * 60;
const hour = minute * 60;
const day = hour * 24;
const month = day * 30;

let result;
if (more) {
const monthCount = dateDiff / month;
const dayCount = dateDiff / day;
const hourCount = dateDiff / hour;
const minuteCount = dateDiff / minute;

if (monthCount >= 1) {
result = datePost.toLocaleDateString().replace(/\//g, "-");
} else if (dayCount >= 1) {
result = parseInt(dayCount) + " " + GLOBAL_CONFIG.date_suffix.day;
} else if (hourCount >= 1) {
result = parseInt(hourCount) + " " + GLOBAL_CONFIG.date_suffix.hour;
} else if (minuteCount >= 1) {
result = parseInt(minuteCount) + " " + GLOBAL_CONFIG.date_suffix.min;
} else {
result = GLOBAL_CONFIG.date_suffix.just;
}
} else {
result = parseInt(dateDiff / day);
}
return result;
},
changeTimeInEssay: function () {
document.querySelector("#bber") &&
document.querySelectorAll("#bber time").forEach(function (e) {
var t = e,
datetime = t.getAttribute("datetime");
(t.innerText = icat.diffDate(datetime, true)), (t.style.display = "inline");
});
},
reflashEssayWaterFall: function () {
document.querySelector("#waterfall") &&
setTimeout(function () {
waterfall("#waterfall");
document.getElementById("waterfall").classList.add("show");
}, 500);
},
commentText: function (e) {
if (e == "undefined" || e == "null") e = "好棒!";
var n = document.getElementsByClassName("el-textarea__inner")[0],
t = document.createEvent("HTMLEvents");
if (!n) return;
t.initEvent("input", !0, !0);
var o = replaceAll(e, "\n", "\n> ");
(n.value = "> " + o + "\n\n"), n.dispatchEvent(t);
var i = document.querySelector("#post-comment").offsetTop;
window.scrollTo(0, i - 80),
n.focus(),
n.setSelectionRange(-1, -1),
document.getElementById("comment-tips") && document.getElementById("comment-tips").classList.add("show");
},
};

icat.changeTimeInEssay();
icat.reflashEssayWaterFall();
  • 创建 [blogRoot]/source/js/waterfall/waterfall.js 文件,并新增以下内容,用于处理瀑布流
    (或写在公共 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
function waterfall(a) {
function b(a, b) {
var c = window.getComputedStyle(b);
return parseFloat(c["margin" + a]) || 0;
}
function c(a) {
return a + "px";
}
function d(a) {
return parseFloat(a.style.top);
}
function e(a) {
return parseFloat(a.style.left);
}
function f(a) {
return a.clientWidth;
}
function g(a) {
return a.clientHeight;
}
function h(a) {
return d(a) + g(a) + b("Bottom", a);
}
function i(a) {
return e(a) + f(a) + b("Right", a);
}
function j(a) {
a = a.sort(function (a, b) {
return h(a) === h(b) ? e(b) - e(a) : h(b) - h(a);
});
}
function k(b) {
f(a) != t && (b.target.removeEventListener(b.type, arguments.callee), waterfall(a));
}
"string" == typeof a && (a = document.querySelector(a));
var l = [].map.call(a.children, function (a) {
return (a.style.position = "absolute"), a;
});
a.style.position = "relative";
var m = [];
l.length && ((l[0].style.top = "0px"), (l[0].style.left = c(b("Left", l[0]))), m.push(l[0]));
for (var n = 1; n < l.length; n++) {
var o = l[n - 1],
p = l[n],
q = i(o) + f(p) <= f(a);
if (!q) break;
(p.style.top = o.style.top), (p.style.left = c(i(o) + b("Left", p))), m.push(p);
}
for (; n < l.length; n++) {
j(m);
var p = l[n],
r = m.pop();
(p.style.top = c(h(r) + b("Top", p))), (p.style.left = c(e(r))), m.push(p);
}
j(m);
var s = m[0];
a.style.height = c(h(s) + b("Bottom", s));
var t = f(a);
window.addEventListener ? window.addEventListener("resize", k) : (document.body.onresize = k);
}
  • _config.butterfly.yml 主题配置文件中 inject 下的 bottom 引入 custom.jswaterfall.js
1
2
3
4
5
6
7
8
9
10
  ···

inject:
head:
- ···
bottom:
- <script async data-pjax src="/js/custom.js"></script> # 即刻逻辑文件
- <script async data-pjax src="/js/waterfall/waterfall.js"></script> # 即刻瀑布流JS

···
  • 创建 [blogRoot]/source/_data/essay.yml 文件,并新增以下内容
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
- class_name: 即刻短文
essay_list:
- content: 完噜 还剩一天让我咋准备 😭
date: 2023/07/31 15:30:50
from: iPhone XR
video:
player: /video/1.mp4

- content: 完噜 还剩一天让我咋准备 😭
date: 2023/07/31 15:30:50
from: iPhone XR
video:
bilibili: //player.bilibili.com/player.html?aid=913951276&bvid=BV1RM4y1p75T&cid=1211165267&page=1

- content: 完噜 还剩一天让我咋准备 😭
date: 2023/05/11 20:35:42
from: iPhone XR
image:
- https://s1.ax1x.com/2023/05/11/p9sKEh8.jpg

- content: 如果要定义 那就是下班后的日落和在家等我下班的她~
date: 2023/05/10 16:16:15
aplayer:
server: netease
id: 1949516216

- content: Melancholia - | 一款纯记录写作类Hexo主题 ✍️
date: 2023/04/23 22:27:22
from: Macbook Pro
link: https://github.com/yife68/Hexo-Theme-Melancholia

- content: 爱看 但还是得吃我一拳
date: 2023/04/22 15:10:30
from: iPhone XR
image:
- https://s1.ax1x.com/2023/05/03/p9JqGXd.jpg
- https://s1.ax1x.com/2023/05/03/p9Jq86H.jpg

- content: iCat 新启程
date: 2023/03/24 16:54:25
from: iPhone XR
link: https://meuicat.com/blog/14/
image:
- https://s1.ax1x.com/2023/05/02/p9GosYQ.jpg

- content: 各种观影史集于一体!人生足迹页诞生咯~
date: 2023/02/19 14:50:17
from: Macbook Pro
link: /collect/

数据参数释义

参数备选值/类型释义
class_nameString【可选】标识符,无实际意义,选填
essay_listArray【必选】即刻短文数据列表
essay_list.contentString【必选】短文 文字内容
essay_list.dateTime【必选】短文发布时间 格式建议为 2022/10/26 08:00:00
essay_list.imageArray【可选】短文图片内容, 可填写多张图片
essay_list.fromString【可选】短文 来自何处, 当然也可以填任何你想填写的标识
essay_list.linkString【可选】外部链接
essay_list.aplayerArray【可选】aplayer 播放器的单曲音乐, 需 aplayer 支持
essay_list.aplayer.serverString【essay_list.aplayer 后必选】aplayer 服务商
essay_list.aplayer.idString【essay_list.aplayer 后必选】单曲 id