您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
共読 at Bangumi
当前为
// ==UserScript== // @name Bangumi shared book collections // @namespace http://tampermonkey.net/ // @version 0.1 // @description 共読 at Bangumi // @description Ref: https://github.com/bangumi/scripts/tree/b0113743743dba35accb28e9b7b9da8cbbea6952/yonjar#%E7%94%A8%E6%88%B7%E8%AF%A6%E6%83%85%E7%88%AC%E5%8F%96 // @license MIT // @author txfs19260817 // @require https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.18.2/babel.js // @require https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.16.0/polyfill.js // @match http*://*.bangumi.tv/ // @match http*://*.bgm.tv/ // @match http*://*.chii.in/ // @icon https://bangumi.tv/img/favicon.ico // ==/UserScript== const parseTimestamp = (s) => { if (!s.includes("ago")) { return new Date(s); } const now = new Date(); const d = s.match(/(\d+)d/i)?.[1] || 0; const h = s.match(/(\d+)h/i)?.[1] || 0; const m = s.match(/(\d+)m/i)?.[1] || 0; now.setDate(now.getDate() - parseInt(d)); now.setHours(now.getHours() - parseInt(h)); now.setMinutes(now.getMinutes() - parseInt(m)); return now; } const getUID = () => { return document .querySelector("#headerNeue2 > div > div.idBadgerNeue > a") .href.split("user/")[1]; } const fetchHTMLDocument = (url, fetchMethod = "GET") => { const fetchInit = { method: fetchMethod, cache: "default", credentials: "include" }; return fetch(new Request(url, fetchInit)).then( (r) => r.text(), (err) => Promise.reject(err) ).then((t) => { const parser = new DOMParser(); return parser.parseFromString(t, "text/html"); }); }; const fetchComments = async (uid) => { const url = `${location.origin}/book/list/${uid}/collect`; const page1 = await fetchHTMLDocument(url); const maxPageNum = page1.getElementsByClassName('page_inner')[0].childElementCount - 1; const pageURLs = Array.from({length: maxPageNum}, (_, i) => i + 1).map((i) => `${url}?page=${i}`) pageURLs.shift(); // [2, ..., maxPageNum] const pages = await Promise.all(pageURLs.map((u) => fetchHTMLDocument(u))); pages.unshift(page1); const subjectUrls = pages .flatMap((page) => Array.from(page.getElementById("browserItemList").children).map((c) => c.firstElementChild.href + "/comments")); const subjectCovers = pages .flatMap((page) => Array.from(page.getElementById("browserItemList").children).map((c) => c.getElementsByTagName('img')[0].src)); const commentDOMs = await Promise.all(subjectUrls.map((u) => fetchHTMLDocument(u))); const commentElements = commentDOMs.map((p) => Array.from(p.getElementsByClassName("text"))); const subjectTitles = pages .flatMap((page) => Array.from(page.getElementById("browserItemList").children).map((c) => c.getElementsByTagName('h3')[0].textContent.trim())); const data = commentElements.flatMap((cs, i) => { return cs.map((c) => { return { subjectUrl: subjectUrls[i], subjectTitle: subjectTitles[i], subjectCover: subjectCovers[i], userUrl: c.firstElementChild.href, username: c.firstElementChild.text, date: parseTimestamp(c.getElementsByTagName('small')[0].textContent.slice(2)), comment: c.getElementsByTagName('p')[0].textContent, } } )}); data.sort((a,b)=>b.date-a.date); return data } const createTabAnchor = () => { const li = document.createElement("li"); const a = document.createElement("a"); a.text = '共读'; a.style.cursor = 'pointer'; li.appendChild(a) document.getElementById('timelineTabs').appendChild(li); return a; } const commentDataToTLList = (data) => { const ul = document.createElement("ul"); const lis = data.map((d) => { const li = document.createElement("li"); li.classList.add("clearit"); li.classList.add("tml_item"); // avatar const avatar = document.createElement("span"); const userAvatarAnchor = document.createElement("a"); const userAvatarSpan = document.createElement("span"); userAvatarSpan.classList.add("avatarNeue"); userAvatarSpan.classList.add("avatarReSize40"); userAvatarSpan.classList.add("ll"); userAvatarSpan.style.backgroundImage = 'url("//lain.bgm.tv/pic/user/l/icon.jpg")' userAvatarAnchor.href = d.userUrl; userAvatarAnchor.appendChild(userAvatarSpan); avatar.classList.add("avatar"); avatar.appendChild(userAvatarAnchor); li.appendChild(avatar); // info const info = document.createElement("span"); info.classList.add("clearit"); info.classList.add("info"); // info - cover const coverAnchor = document.createElement("a"); const coverImg = document.createElement("img"); coverImg.classList.add("rr"); coverImg.src = d.subjectCover; coverImg.height = "48"; coverImg.width = "48"; coverAnchor.appendChild(coverImg); info.appendChild(coverAnchor); // info - username const userAnchor = document.createElement("a"); userAnchor.href = d.userUrl; userAnchor.textContent = d.username; userAnchor.classList.add("l"); info.appendChild(userAnchor); const connector = document.createElement("span"); connector.textContent = " 读过 "; info.appendChild(connector); // info - subject const subjectAnchor = document.createElement("a"); subjectAnchor.href = d.subjectUrl; subjectAnchor.textContent = d.subjectTitle; subjectAnchor.classList.add("l"); info.appendChild(subjectAnchor); // info - comment const collectInfo = document.createElement("div"); collectInfo.classList.add("collectInfo"); const quoteDiv = document.createElement("div"); quoteDiv.classList.add("quote"); const quoteQ = document.createElement("q"); quoteQ.textContent = d.comment; quoteDiv.appendChild(quoteQ); collectInfo.appendChild(quoteDiv); info.appendChild(collectInfo); // info - date const dateP = document.createElement("p"); dateP.classList.add("date"); dateP.textContent = d.date.toLocaleString(); info.appendChild(dateP); // info done li.appendChild(info); return li }); lis.forEach((l) => {ul.appendChild(l)}); return ul; } var inline_src = ` // Your code here... const uid = getUID(); fetchComments(uid) .then((r) => { const tabAnchor = createTabAnchor(); const tl = document.getElementById("timeline"); // TODO: pagination? tabAnchor.onclick = function() { tabAnchor.classList.add("focus"); tl.replaceChildren(commentDataToTLList(r.slice(0, 100))); }; }); `; var c = Babel.transform(inline_src, { presets: [ "es2015", "es2016" ] }); eval(c.code);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址