本WIKI由旅行者酒馆于2021年10月05日申请开通。内容按CC BY-NC-SA 4.0协议提供,编辑权限开放。
本WIKI仍在努力完善中,欢迎收藏。编辑组为非官方民间组织,为爱发电,欢迎各路能人异士加入。
免责声明 • 编辑教程 • 反馈留言 • 收藏方法 • 交流群:1017604603
本WIKI由旅行者酒馆于2021年10月05日申请开通。内容按CC BY-NC-SA 4.0协议提供,编辑权限开放。本WIKI仍在努力完善中,欢迎收藏。编辑组为非官方民间组织,为爱发电,欢迎各路能人异士加入。
Widget:ShowCount
<script> /**
* 传递给勾勾册的回调函数
* 勾选或者取消勾选后,Bikit 会调用一次本函数
*
* @param {string} listName
**/
function showCompute(listName) {
const collectionSelector = "#CardSelectTr tr.bwiki-collection";
const achievements = document.querySelectorAll(collectionSelector);
let length = achievements.length;
let sumCheck = 0;
let remainingStella = 0;
for (const achievement of achievements) {
if (achievement.style.display === "none") {
length -= 1;
continue;
}
let checked = achievement.classList.contains("checked");
if (checked) {
sumCheck += 1;
} else {
const content = achievement.lastChild.textContent.trim().replace("星琼 x ", "");
remainingStella += parseInt(content.trim());
}
}
const totalNumClass = "bwiki-collection-totalnum-" + listName;
for (let totalnum of document.getElementsByClassName(totalNumClass)) {
totalnum.textContent = length;
}
const checkNumClass = "bwiki-collection-checknum-" + listName;
for (let checknum of document.getElementsByClassName(checkNumClass)) {
checknum.textContent = sumCheck;
}
const uncheckNumClass = "bwiki-collection-unchecknum-" + listName;
for (let unchecknum of document.getElementsByClassName(uncheckNumClass)) {
unchecknum.textContent = length - sumCheck;
}
for (let stellaNum of document.getElementsByClassName("stellaNum")) {
stellaNum.textContent = `剩余可获取星琼:${remainingStella}个`;
}
}
/**
* 勾勾册初始化执行完成之后,会设置几个 class 的 textContent 为统计数字
* 因此我们使用这个来判断勾勾册是否初始化成功
*
* Bikit 初始化阶段,首先会请求一次 mw.Api() 的 option 接口获取保存的勾选数据
* 根据保存数据对每一行进行判断是否已勾选,然后每一行都会调用一次 window.afterCollectionItemClick
* 而我们的回调函数又会扫一遍整张表然后更新成就完成数量,也就是如果提前设置回调函数,会导致初始化 O(N²) 时间复杂度
* 这就导致勾勾册初始化极其缓慢,因此为了避免空耗性能,我们必须等 Bikit 初始化完成后再设置回调
*
* @param {string} listName
*/
async function waitBikitInit(listName) {
const indicatorClass = "bwiki-collection-unchecknum-achievement";
const indicator = document.getElementsByClassName(indicatorClass);
if (indicator.length === 0) return;
while (isNaN(parseInt(indicator[0].textContent))) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
// 检测到初始化完成
window.afterCollectionItemClick = showCompute;
showCompute(listName);
}
document.addEventListener("DOMContentLoaded", async function () {
const listName = "achievement"; // 勾勾册的自定义ID
// 为成就筛选项增加事件监听以调用 showCompute 重新计算成就完成数量
// 等 50ms 大概是为了等整个页面的 display: none 设置完成再执行,具体不清楚为什么当时这么写
for (let button of document.getElementsByClassName("cardSelectOption")) {
button.addEventListener("click", () =>
setTimeout(showCompute, 50, listName),
);
}
// 为「隐藏已完成成就」按钮增加事件监听以调用 showCompute 重新计算成就完成数量
for (let button of document.getElementsByClassName("hideFinish")) {
button.addEventListener("click", () =>
setTimeout(showCompute, 50, listName),
);
}
await waitBikitInit(listName);
}); </script>

沪公网安备 31011002002714 号