惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
博客园_首页
H
Help Net Security
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
GbyAI
GbyAI
Scott Helme
Scott Helme
D
Docker
Hacker News: Ask HN
Hacker News: Ask HN
P
Privacy & Cybersecurity Law Blog
Jina AI
Jina AI
雷峰网
雷峰网
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Spread Privacy
Spread Privacy
G
GRAHAM CLULEY
C
Cisco Blogs
The Hacker News
The Hacker News
F
Full Disclosure
Y
Y Combinator Blog
Blog — PlanetScale
Blog — PlanetScale
Recent Announcements
Recent Announcements
G
Google Developers Blog
量子位
K
Kaspersky official blog
Cisco Talos Blog
Cisco Talos Blog
The Cloudflare Blog
A
About on SuperTechFans
C
Cybersecurity and Infrastructure Security Agency CISA
Last Week in AI
Last Week in AI
博客园 - 三生石上(FineUI控件)
Microsoft Security Blog
Microsoft Security Blog
Martin Fowler
Martin Fowler
T
Tenable Blog
P
Palo Alto Networks Blog
H
Heimdal Security Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
Schneier on Security
Schneier on Security
The Register - Security
The Register - Security
F
Fortinet All Blogs
Stack Overflow Blog
Stack Overflow Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
The Blog of Author Tim Ferriss
N
News and Events Feed by Topic
Hugging Face - Blog
Hugging Face - Blog
小众软件
小众软件
V
V2EX
爱范儿
爱范儿

山岳库博

自建虚拟局域网实现文明六稳定联机 追光者 快手面经(二〇二四年五月九日) 一文搞懂伪代码 2023 级新生周赛第二周题解 Swpp Backends 官方文档 Butterfly 友链魔改教程 在 MavenCentral 上发布你的项目 控制台游戏引擎开发文档 MI——高级合成表模块 人狼羊菜过河详细题解 蓝桥杯 2023 训练四 Java 全解 蓝桥杯 2023 训练三 Java 全解 蓝桥杯 2023 训练二 Java 全解 全自动博客部署方案 小白也能用的 SW 构建插件 MI—电力系统工作原理 MI文档——自动化GUI绘制 网站加载速度优化方案总结 给博客添加自定义的通知悬浮窗
给博客添加追番页面
空梦 · 2022-06-26 · via 山岳库博

注意:如果你的博客开启了 pjax,请务必使用 pjax 兼容的方案

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
!=page.content

#bangumis
#bangumi-top
.multi#cats
p 分类
.list
.wantWatch 想看
.watching 在看
.watched 已看
.multi#tags
p 标签
.list
.all.active 所有

div#inner

.bangumi-tabs#bangumi-bottom
button#bottom-first 首页
button#bottom-pre 上一页
p#bottom-num 0/0
button#bottom-next 下一页
button#bottom-end 尾页

script.
document.addEventListener('DOMContentLoaded', async function fun() {
/**
* 分离Json的读取器
*
* @param root {string} 根目录,不以`/`结尾
* @param amount {number} 每页的数量
* @param dataAmount {number} 每个文件中数据的数量
* @param size {number} 项目总量
* @constructor
*/

function ApartJson(root, amount, dataAmount, size) {
// 下一个要读取项目编号
let readIndex = 0
// 读取的文件列表
const fileList = new Map()
// 标记最后一个index
const lastIndex = Math.ceil(size / dataAmount) - 1

/**
* 读取指定下标的文件
* @param index {number} 文件下标
* @return {Promise}
*/
const readFile = index => new Promise(resolve => {
if (index > lastIndex || index < 0) throw `${index} not in [0, ${lastIndex}]`
if (fileList.has(index)) {
let id
const task = () => {
const cache = fileList.get(index)
if (cache) {
if (id) clearInterval(id)
resolve(cache)
}
}
task()
id = setInterval(task, 100)
} else {
fileList.set(index, null)
fetch(`${root}/${index}.json`)
.then(response => response.json().then(json => {
fileList.set(index, json)

resolve(json)
}))
}
})

const readHelper = id => new Promise(resolve => {
if (size && id > size) return resolve(null)
const fileIndex = Math.floor(id / dataAmount)
const innerIndex = id % dataAmount
readFile(fileIndex).then(json => {
// noinspection JSCheckFunctionSignatures
const keys = Object.keys(json)
resolve(json[keys[innerIndex]])
})
})

// noinspection JSUnusedGlobalSymbols
/**
* 读取上一项
* @return {Promise}
*/
this.readNext = () => readHelper(readIndex++)

/**
* 读取上一项
* @return {Promise}
*/
//this.readPrev = () => readHelper(readIndex--)

// noinspection CommaExpressionJS,JSUnusedGlobalSymbols
/**
* 设置页码,从0开始
* @param page {number} 页面编号
*/
this.setPage = page => {
readIndex = page * amount
}

/** 获取页码数量 */
this.size = () => Math.ceil(size / amount)

/** 获取数据总量 */
this.amount = () => size

// noinspection JSUnusedGlobalSymbols
/**
* 判断指定页面是否为末页
* @param page {number|null} 指定页面编号,留空为当前页面编号
* @return {boolean}
*/
this.isLastPage = (page = null) => {
if (page === null) page = Math.floor(readIndex / amount)
return page === this.size() - 1
}
}

const isSupportWebp = (() => {
try {
return document.createElement('canvas').toDataURL('image/webp', 0.5).indexOf('data:image/webp') === 0;
} catch (ignore) {
return false;
}
})()
const root = '/bilibili/'
const config = await (await fetch(`${root}config.json`)).json()
const sizeList = config.size
// 单页卡片数量限制
const maxCount = 10
const dataAmount = config.amount
// JSON
const jsonMap = {
wantWatch: new ApartJson(`${root}wantWatch`, maxCount, dataAmount, sizeList.wantWatch),
watching: new ApartJson(`${root}watching`, maxCount, dataAmount, sizeList.watching),
watched: new ApartJson(`${root}watched`, maxCount, dataAmount, sizeList.watched)
}

/** 处理参数 */
const parseArg = () => {
const url = location.href
let arg
if (url.endsWith('/')) {
arg = {id: 'watching', page: 1}
} else {
arg = JSON.parse(decodeURIComponent(location.hash.substring(1)))
// 校对参数
if (!arg.id || (arg.id !== 'watching' &&
arg.id !== 'wantWatch' && arg.id !== 'watched'))
arg.id = 'watching'
if (!arg.page || arg.page < 1) arg.page = 1
}
sessionStorage.setItem('bangumis', JSON.stringify(arg))
return arg
}

const arg = await parseArg()
let tagFilter = null
const top = document.querySelector('#bangumi-top')
const cats = top.querySelector('#cats')
const tags = top.querySelector('#tags')
const tabs = document.querySelector('.bangumi-tabs')

/** 更新列表内容 */
async function update(updateURL = true) {
tabs.querySelectorAll('button').forEach(button => button.classList.add('disable'))
top.querySelectorAll('div').forEach(div => div.classList.add('disable'))
for (let value of cats.querySelector('.list').children) {
if (value.classList.contains(arg.id)) value.classList.add('active')
else value.classList.remove('active')
}
const json = jsonMap[arg.id]
json.setPage(arg.page - 1)

function buildCard(title, img, href, follow, type, area, play, coin, danmaku, score, tagList, index) {
if (!img.startsWith('http')) img = `https://i0.hdslb.com/bfs/bangumi/${img}${isSupportWebp ? '@220w_280h.webp' : ''}`
let tags = ''
for (let name of tagList) tags += `<p>${name}</p>`
// noinspection HtmlUnknownAttribute,HtmlRequiredAltAttribute
return `<div class="card" link="${href}" index="${index}"><img src="${img}" referrerpolicy="no-referrer"><div class="info"><a class="title">${title}</a><div class="details"><span class="area"><p>${type}</p><em>${area}</em></span><span class="play"><p>播放量</p><em>${play}</em></span><span class="follow"><p>追番</p><em>${follow}</em></span><span class="coin"><p>硬币</p><em>${coin}</em></span><span class="danmaku"><p>弹幕</p><em>${danmaku}</em></span><span class="score"><p>评分</p><em>${score}</em></span></div><div class="tags">${tags}</div></div></div>`
}

const inner = document.getElementById('inner')
inner.innerHTML = ''
if (updateURL) location.hash = JSON.stringify(arg)
for (let i = 0; i !== maxCount;) {
const value = await json.readNext()
if (!value) break
if (tagFilter && !tagFilter(value)) continue
const id = value.id ?? 0
const href = id === 0 ? '' : (typeof id !== 'number' ? id : `https://www.bilibili.com/bangumi/media/md${id}/`)
inner.innerHTML += buildCard(value.title, value.cover, href ?? 0,
value.follow ?? '-', value.type ?? '番剧', value.area ?? '日本', value.view ?? '-',
value.coin ?? '-', value.danmaku ?? '-', value.score ?? '-', value.tags ?? [], value.index ?? 0)
++i
}

const pageNum = document.getElementById('bottom-num')
appendText(pageNum, tagFilter ? 'disabled' : `${arg.page} / ${json.size()}`, true)
tabs.querySelectorAll('button').forEach(button => button.classList.remove('disable'))
top.querySelectorAll('div').forEach(div => div.classList.remove('disable'))

const pre = document.getElementById('bottom-pre').classList
const next = document.getElementById('bottom-next').classList
if (arg.page === 1) pre.add('disable')
if (json.isLastPage(arg.page - 1)) next.add('disable')
}

const init = () => {
const buildTag = (name) => `<div class="${name}">${name}</div>`
cats.addEventListener('click', event => {
const target = event.target
const classList = target.classList
if (!target.parentNode?.classList?.contains('list') ||
classList.contains('active') || classList.contains('disable')) return
arg.id = target.className
arg.page = 1
update()
})
const tagList = tags.querySelector('.list')
for (let tag of config.tags) {
tagList.innerHTML += buildTag(tag)
}
tagList.onclick = event => {
const target = event.target
const parent = target.parentNode
const classList = target.classList
if (!parent.classList?.contains('list') ||
classList.contains('active') || classList.contains('disable')) return
for (let node of parent.children) {
node.classList.remove('active')
}
const name = target.className
tagFilter = name === 'all' ? null : card => card.tags?.includes(name)
classList.add('active')
update(false)
}
}

/** 追加文本 */
function appendText(element, text, clean) {
text = `(${text})`
if (navigator.userAgent.includes('Firefox')) {
if (!clean && element.textContent.endsWith(')')) return
element.textContent = clean ? text : element.textContent + text
} else {
if (!clean && element.innerText.endsWith(')')) return
element.innerText = clean ? text : element.innerText + text
}
}

/** 注册点击事件 */
function initClick(arg) {
const top = document.getElementById('bangumi-top')
top.addEventListener('click', event => {
const element = event.target.id ? event.target : event.target.parentNode
if (element.nodeName !== 'BUTTON') return
const classList = element.classList
if (classList.contains('active') || classList.contains('disable')) return
classList.add('active')
for (let value of top.children) {
if (value.id !== element.id) value.classList.remove('active')
}
arg.id = element.id
arg.page = 1
sessionStorage.setItem('bangumis', JSON.stringify(arg))
update()
})
const bottom = document.getElementById('bangumi-bottom')
const height = document.getElementById('page-header').clientHeight
bottom.addEventListener('click', event => {
const element = event.target.id ? event.target : event.target.parentNode
if (element.nodeName !== 'BUTTON' || element.classList.contains('disable')) return
btf.scrollToDest(height)
switch (element.id) {
case 'bottom-first':
arg.page = 1
break
case 'bottom-end':
arg.page = jsonMap[arg.id].size()
break
case 'bottom-next':
++arg.page
break
case 'bottom-pre':
--arg.page
break
}
setTimeout(() => update(arg), 200)
})
const card = document.getElementById('inner')
card.addEventListener('click', event => {
let element = event.target.id ? event.target : event.target.parentNode
if (!element.classList.contains('descr')) {
while (!element.classList.contains('card')) element = element.parentElement
const link = element.getAttribute('link')
if (link.length > 1) open(link)
else btf.snackbarShow('博主没有为这个番剧设置链接~')
}
})
}

init()
const hashchangeTask = () => {
const newArg = parseArg()
if (newArg.id !== arg.id && newArg.page !== arg.page) {
arg.id = newArg.id
arg.page = newArg.page
update(false)
}
}
addEventListener('hashchange', hashchangeTask)
for (let key in sizeList) {
appendText(cats.querySelector(`.${key}`), sizeList[key], false)
}
initClick(arg)
// noinspection ES6MissingAwait
update(false)
})

首先在你的某一个所有页面都需要加载的 JS 文件中写入如下代码:

1
2
3
4
5
document.addEventListener('DOMContentLoaded', () => {
const pushEvent = () => document.dispatchEvent(new Event('kms:loaded'))
document.addEventListener('pjax:complete', pushEvent)
pushEvent()
})

然后编写 PUG 文件:

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
!=page.content

#bangumis
#bangumi-top
.multi#cats
p 分类
.list
.wantWatch 想看
.watching 在看
.watched 已看
.multi#tags
p 标签
.list
.all.active 所有

div#inner

.bangumi-tabs#bangumi-bottom
button#bottom-first 首页
button#bottom-pre 上一页
p#bottom-num 0/0
button#bottom-next 下一页
button#bottom-end 尾页

script.
document.addEventListener('kms:loaded', async function fun() {
document.removeEventListener('kms:loaded', fun)

/**
* 分离Json的读取器
*
* @param root {string} 根目录,不以`/`结尾
* @param amount {number} 每页的数量
* @param dataAmount {number} 每个文件中数据的数量
* @param size {number} 项目总量
* @constructor
*/

function ApartJson(root, amount, dataAmount, size) {

// 下一个要读取项目编号
let readIndex = 0
// 读取的文件列表
const fileList = new Map()
// 标记最后一个index
const lastIndex = Math.ceil(size / dataAmount) - 1

/**
* 读取指定下标的文件
* @param index {number} 文件下标
* @return {Promise}
*/
const readFile = index => new Promise(resolve => {
if (index > lastIndex || index < 0) throw `${index} not in [0, ${lastIndex}]`
if (fileList.has(index)) {
let id
const task = () => {
const cache = fileList.get(index)
if (cache) {
if (id) clearInterval(id)
resolve(cache)
}
}
task()
id = setInterval(task, 100)
} else {
fileList.set(index, null)
fetch(`${root}/${index}.json`)
.then(response => response.json().then(json => {
fileList.set(index, json)

resolve(json)
}))
}
})

const readHelper = id => new Promise(resolve => {
if (size && id > size) return resolve(null)
const fileIndex = Math.floor(id / dataAmount)
const innerIndex = id % dataAmount
readFile(fileIndex).then(json => {
// noinspection JSCheckFunctionSignatures
const keys = Object.keys(json)
resolve(json[keys[innerIndex]])
})
})

// noinspection JSUnusedGlobalSymbols
/**
* 读取上一项
* @return {Promise}
*/
this.readNext = () => readHelper(readIndex++)

/**
* 读取上一项
* @return {Promise}
*/
//this.readPrev = () => readHelper(readIndex--)

// noinspection CommaExpressionJS,JSUnusedGlobalSymbols
/**
* 设置页码,从0开始
* @param page {number} 页面编号
*/
this.setPage = page => {
readIndex = page * amount
}

/** 获取页码数量 */
this.size = () => Math.ceil(size / amount)

/** 获取数据总量 */
this.amount = () => size

// noinspection JSUnusedGlobalSymbols
/**
* 判断指定页面是否为末页
* @param page {number|null} 指定页面编号,留空为当前页面编号
* @return {boolean}
*/
this.isLastPage = (page = null) => {
if (page === null) page = Math.floor(readIndex / amount)
return page === this.size() - 1
}
}

const isSupportWebp = (() => {
try {
return document.createElement('canvas').toDataURL('image/webp', 0.5).indexOf('data:image/webp') === 0;
} catch (ignore) {
return false;
}
})()
const root = '/bilibili/'
const config = await (await fetch(`${root}config.json`)).json()
const sizeList = config.size
// 单页卡片数量限制
const maxCount = 10
const dataAmount = config.amount
// JSON
const jsonMap = {
wantWatch: new ApartJson(`${root}wantWatch`, maxCount, dataAmount, sizeList.wantWatch),
watching: new ApartJson(`${root}watching`, maxCount, dataAmount, sizeList.watching),
watched: new ApartJson(`${root}watched`, maxCount, dataAmount, sizeList.watched)
}

/** 处理参数 */
const parseArg = () => {
const url = location.href
let arg
if (url.endsWith('/')) {
arg = {id: 'watching', page: 1}
} else {
arg = JSON.parse(decodeURIComponent(location.hash.substring(1)))
// 校对参数
if (!arg.id || (arg.id !== 'watching' &&
arg.id !== 'wantWatch' && arg.id !== 'watched'))
arg.id = 'watching'
if (!arg.page || arg.page < 1) arg.page = 1
}
sessionStorage.setItem('bangumis', JSON.stringify(arg))
return arg
}

const arg = await parseArg()
let tagFilter = null
const top = document.querySelector('#bangumi-top')
const cats = top.querySelector('#cats')
const tags = top.querySelector('#tags')
const tabs = document.querySelector('.bangumi-tabs')

/** 更新列表内容 */
async function update(updateURL = true) {
tabs.querySelectorAll('button').forEach(button => button.classList.add('disable'))
top.querySelectorAll('div').forEach(div => div.classList.add('disable'))
for (let value of cats.querySelector('.list').children) {
if (value.classList.contains(arg.id)) value.classList.add('active')
else value.classList.remove('active')
}
const json = jsonMap[arg.id]
json.setPage(arg.page - 1)

function buildCard(title, img, href, follow, type, area, play, coin, danmaku, score, tagList, index) {
if (!img.startsWith('http')) img = `https://i0.hdslb.com/bfs/bangumi/${img}${isSupportWebp ? '@220w_280h.webp' : ''}`
let tags = ''
for (let name of tagList) tags += `<p>${name}</p>`
// noinspection HtmlUnknownAttribute,HtmlRequiredAltAttribute
return `<div class="card" link="${href}" index="${index}"><img src="${img}" referrerpolicy="no-referrer"><div class="info"><a class="title">${title}</a><div class="details"><span class="area"><p>${type}</p><em>${area}</em></span><span class="play"><p>播放量</p><em>${play}</em></span><span class="follow"><p>追番</p><em>${follow}</em></span><span class="coin"><p>硬币</p><em>${coin}</em></span><span class="danmaku"><p>弹幕</p><em>${danmaku}</em></span><span class="score"><p>评分</p><em>${score}</em></span></div><div class="tags">${tags}</div></div></div>`
}

const inner = document.getElementById('inner')
inner.innerHTML = ''
if (updateURL) location.hash = JSON.stringify(arg)
for (let i = 0; i !== maxCount;) {
const value = await json.readNext()
if (!value) break
if (tagFilter && !tagFilter(value)) continue
const id = value.id ?? 0
const href = id === 0 ? '' : (typeof id !== 'number' ? id : `https://www.bilibili.com/bangumi/media/md${id}/`)
inner.innerHTML += buildCard(value.title, value.cover, href ?? 0,
value.follow ?? '-', value.type ?? '番剧', value.area ?? '日本', value.view ?? '-',
value.coin ?? '-', value.danmaku ?? '-', value.score ?? '-', value.tags ?? [], value.index ?? 0)
++i
}

const pageNum = document.getElementById('bottom-num')
appendText(pageNum, tagFilter ? 'disabled' : `${arg.page} / ${json.size()}`, true)
tabs.querySelectorAll('button').forEach(button => button.classList.remove('disable'))
top.querySelectorAll('div').forEach(div => div.classList.remove('disable'))

const pre = document.getElementById('bottom-pre').classList
const next = document.getElementById('bottom-next').classList
if (arg.page === 1) pre.add('disable')
if (json.isLastPage(arg.page - 1)) next.add('disable')
}

const init = () => {
const buildTag = (name) => `<div class="${name}">${name}</div>`
cats.addEventListener('click', event => {
const target = event.target
const classList = target.classList
if (!target.parentNode?.classList?.contains('list') ||
classList.contains('active') || classList.contains('disable')) return
arg.id = target.className
arg.page = 1
update()
})
const tagList = tags.querySelector('.list')
for (let tag of config.tags) {
tagList.innerHTML += buildTag(tag)
}
tagList.onclick = event => {
const target = event.target
const parent = target.parentNode
const classList = target.classList
if (!parent.classList?.contains('list') ||
classList.contains('active') || classList.contains('disable')) return
for (let node of parent.children) {
node.classList.remove('active')
}
const name = target.className
tagFilter = name === 'all' ? null : card => card.tags?.includes(name)
classList.add('active')
update(false)
}
}

/** 追加文本 */
function appendText(element, text, clean) {
text = `(${text})`
if (navigator.userAgent.includes('Firefox')) {
if (!clean && element.textContent.endsWith(')')) return
element.textContent = clean ? text : element.textContent + text
} else {
if (!clean && element.innerText.endsWith(')')) return
element.innerText = clean ? text : element.innerText + text
}
}

/** 注册点击事件 */
function initClick(arg) {
const top = document.getElementById('bangumi-top')
top.addEventListener('click', event => {
const element = event.target.id ? event.target : event.target.parentNode
if (element.nodeName !== 'BUTTON') return
const classList = element.classList
if (classList.contains('active') || classList.contains('disable')) return
classList.add('active')
for (let value of top.children) {
if (value.id !== element.id) value.classList.remove('active')
}
arg.id = element.id
arg.page = 1
sessionStorage.setItem('bangumis', JSON.stringify(arg))
update()
})
const bottom = document.getElementById('bangumi-bottom')
const height = document.getElementById('page-header').clientHeight
bottom.addEventListener('click', event => {
const element = event.target.id ? event.target : event.target.parentNode
if (element.nodeName !== 'BUTTON' || element.classList.contains('disable')) return
btf.scrollToDest(height)
switch (element.id) {
case 'bottom-first':
arg.page = 1
break
case 'bottom-end':
arg.page = jsonMap[arg.id].size()
break
case 'bottom-next':
++arg.page
break
case 'bottom-pre':
--arg.page
break
}
setTimeout(() => update(arg), 200)
})
const card = document.getElementById('inner')
card.addEventListener('click', event => {
let element = event.target.id ? event.target : event.target.parentNode
if (!element.classList.contains('descr')) {
while (!element.classList.contains('card')) element = element.parentElement
const link = element.getAttribute('link')
if (link.length > 1) open(link)
else btf.snackbarShow('博主没有为这个番剧设置链接~')
}
})
}

init()
const hashchangeTask = () => {
const newArg = parseArg()
if (newArg.id !== arg.id && newArg.page !== arg.page) {
arg.id = newArg.id
arg.page = newArg.page
update(false)
}
}
addEventListener('hashchange', hashchangeTask)
for (let key in sizeList) {
appendText(cats.querySelector(`.${key}`), sizeList[key], false)
}
initClick(arg)
// noinspection ES6MissingAwait
update(false)
})