预览
相比自带卡片占用更小的展示面积,能查看所有月份的文章数量,点击年份可以查看对应年份的所有文章,左右两个按钮可以切换年份。
实现
找到
\themes\butterfly\scripts\helpers\aside_archives.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
hexo.extend.helper.register('aside_archives', function (options = {}) {
const { config } = this
const archiveDir = config.archive_dir
const { timezone } = config
const lang = toMomentLocale(this.page.lang || this.page.language || config.language)
let { format } = options
const type = options.type || 'monthly'
const order = options.order || -1
const compareFunc = type === 'monthly'
? (yearA, monthA, yearB, monthB) => yearA === yearB && monthA === monthB
: (yearA, monthA, yearB, monthB) => yearA === yearB
let result = ''
if (!format) {
format = type === 'monthly' ? 'MMMM YYYY' : 'YYYY'
}
const posts = this.site.posts.sort('date', order)
if (!posts.length) return result
const data = []
let length = 0
posts.forEach(post => {
// Clone the date object to avoid pollution
let date = post.date.clone()
if (timezone) date = date.tz(timezone)
const year = date.year()
const month = date.month() + 1
const lastData = data[length - 1]
if (!lastData || !compareFunc(lastData.year, lastData.month, year, month)) {
if (lang) date = date.locale(lang)
const name = date.format(format)
length = data.push({
name,
year,
month,
count: 1
})
} else {
lastData.count++
}
})
// 按年份分组
const groupedData = data.reduce((acc, { name, year, month, count }) => {
if (!acc[year]) {
acc[year] = { year, sum: 0, data: [] }; // 初始化年份条目
}
acc[year].sum += count; // 累加年份的总文章数
acc[year].data.push({ name, month, count }); // 将月份数据加入对应年份
return acc;
}, {});
// 转换为目标数组格式
const newData = Object.values(groupedData);
result += `<div class="item-headline"><i class="fas fa-archive"></i><span>${this._p('aside.card_archives')}</span>`
result += '</div>'
result += `<div class="card-archive-calendar">
<div class="card-archive-calendar-head">
<button class="card-archive-calendar-left`
if (newData.length === 1) result += ' no-event'
result +=
`" onclick="ctrl.card_archive_calendar_prev()">
<i class="fas fa-angle-left"></i>
</button>
<div class="card-archive-calendar-center">
<div class="card-archive-calendar-years" style="transform: translateX(0px);">`
for (let i = 0; i < newData.length; i++) {
let url = `${archiveDir}/${newData[i].year}/`
result +=
`<a class="card-archive-calendar-year-item" href="${this.url_for(url)}">
<span class="card-archive-calendar-year">${newData[i].year}</span>
<span class="card-archive-calendar-year-count">[${newData[i].sum}]</span>
</a>`
}
result +=
`</div>
</div>
<button class="card-archive-calendar-right no-event" onclick="ctrl.card_archive_calendar_next()">
<i class="fas fa-angle-right"></i>
</button>
</div>
<div class="card-archive-calendar-body">
<div class="card-archive-calendar-pages" style="transform: translateX(0px);">`
for (let i = 0; i < newData.length; i++) {
let item = newData[i]
let m = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
let k = item.data.length - 1
result +=
`<div class="card-archive-calendar-page">`
for (let j = 0; j < 12; j++) {
let c = 0
if (k >= 0 && j == item.data[k].month - 1) {
c = item.data[k].count
let url = `${archiveDir}/${item.year}/`
if (type === 'monthly') {
if (item.data[k].month < 10) url += '0'
url += `${item.data[k].month}/`
}
result +=
`<a class="card-archive-calendar-month-item" href="${this.url_for(url)}">`
k--
} else {
result +=
`<a class="card-archive-calendar-month-item no-link">`
}
result +=
`<span class="card-archive-calendar-month">${m[j]}</span>
<span class="card-archive-calendar-month-count">${c}篇</span>
</a>`
}
result +=
`</div>`
}
result +=
`</div>
</div>
</div>`
return result
})
const toMomentLocale = function (lang) {
if (lang === undefined) {
return undefined
}
// moment.locale('') equals moment.locale('en')
// moment.locale(null) equals moment.locale('en')
if (!lang || lang === 'en' || lang === 'default') {
return 'en'
}
return lang.toLowerCase().replace('_', '-')
}补充逻辑函数
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
56var ctrl = {
card_archive_calendar_prev() {
let a = document.querySelector(".card-archive-calendar-years")
let b = document.querySelector(".card-archive-calendar-pages")
let count = a.childElementCount
let prev = document.querySelector(".card-archive-calendar-left")
let next = document.querySelector(".card-archive-calendar-right")
let t = a.style.transform
if (t) {
let m = parseFloat(t.match(/translateX\((-?\d+\.?\d*)(px|%)?\)/)[1])
let n = m / 100
if (n > 0 && n < count - 2) {
a.style.transform = "translateX(" + 100 * (n+1) + "px)"
b.style.transform = "translateX(" + 298 * (n+1) + "px)"
} else if (n == count - 2) {
a.style.transform = "translateX(" + 100 * (n+1) + "px)"
b.style.transform = "translateX(" + 298 * (n+1) + "px)"
prev.classList.add("no-event")
} else if (n == 0) {
a.style.transform = "translateX(" + 100 + "px)"
b.style.transform = "translateX(" + 298 + "px)"
if (count == 2) {
prev.classList.add("no-event")
next.classList.remove("no-event")
} else if (count > 2) {
next.classList.remove("no-event")
}
}
}
},
card_archive_calendar_next() {
let a = document.querySelector(".card-archive-calendar-years")
let b = document.querySelector(".card-archive-calendar-pages")
let count = a.childElementCount
let prev = document.querySelector(".card-archive-calendar-left")
let next = document.querySelector(".card-archive-calendar-right")
let t = a.style.transform
if (t) {
let m = parseFloat(t.match(/translateX\((-?\d+\.?\d*)(px|%)?\)/)[1])
let n = m / 100
if (n > 1 && n < count - 1) {
a.style.transform = "translateX(" + 100 * (n-1) + "px)"
b.style.transform = "translateX(" + 298 * (n-1) + "px)"
} else if (n == count - 1) {
a.style.transform = "translateX(" + 100 * (n-1) + "px)"
b.style.transform = "translateX(" + 298 * (n-1) + "px)"
prev.classList.remove("no-event")
} else if (n == 1) {
a.style.transform = "translateX(0px)"
b.style.transform = "translateX(0px)"
next.classList.add("no-event")
}
}
}
}添加样式代码
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.card-archive-calendar-head {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 5px;
}
.card-archive-calendar-head button {
height: 30px;
width: 30px;
color: var(--font-color);
transition: .3s;
}
.card-archive-calendar-head button,
.card-archive-calendar-center {
background: var(--gavin-widget-bg1);
border-radius: 8px;
}
.card-archive-calendar-head button:hover,
.card-archive-calendar-year-item:hover {
background: var(--gavin-widget-bg2);
color: var(--dis-f-0);
}
.card-archive-calendar-year-item span,
.card-archive-calendar-month-item span {
line-height: 1.3;
}
.card-archive-calendar-center {
height: 30px;
width: 100px;
display: flex;
overflow: hidden;
justify-content: flex-end;
}
.card-archive-calendar-years {
display: flex;
flex-direction: row;
transition: .3s ease;
}
.card-archive-calendar-year-item {
display: flex;
align-items: center;
justify-content: center;
width: 100px;
}
.card-archive-calendar-year {
font-weight: bold;
}
.card-archive-calendar-year-count {
margin-left: 5px;
}
.card-archive-calendar-year-count,
.card-archive-calendar-month-count {
font-size: 85%;
font-weight: bold;
opacity: .4;
}
.card-archive-calendar-body {
height: 100%;
width: 100%;
display: flex;
overflow: hidden;
justify-content: flex-end;
padding: 5px 0;
}
.card-archive-calendar-pages {
display: flex;
flex-direction: row;
transition: .3s ease;
}
.card-archive-calendar-page {
height: 100%;
width: calc(298px - 10px);
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 10px;
margin: 0 5px;
}
.card-archive-calendar-month-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: calc((100% - 30px) / 4);
height: 50px;
cursor: pointer;
background: var(--gavin-widget-bg1);
border-radius: 8px;
font-weight: bold;
}
.card-archive-calendar-month-item:hover {
background: var(--gavin-nav-hover);
color: #fff;
}
.card-archive-calendar-head button.no-event,
.card-archive-calendar-month-item.no-link {
opacity: 0.3;
pointer-events: none;
}
侧边栏组件 - 年月历文章归档卡片
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 参星阁!
评论