您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
经济的同步率查询
当前为
// ==UserScript== // @name 时光机查询特定条目评价 // @namespace https://bgm.tv/group/topic/411925 // @version 0.0.1 // @description 经济的同步率查询 // @author mmv // @include /^https?:\/\/(((fast\.)?bgm\.tv)|chii\.in|bangumi\.tv)\/user\/[^/]+$/ // @icon https://www.google.com/s2/favicons?sz=64&domain=bgm.tv // @license MIT // @grant none // ==/UserScript== (function() { 'use strict'; const username = location.pathname.split('/').pop(); const synchronize = document.querySelector('.userSynchronize'); if (!synchronize) return; const frag = document.createDocumentFragment(); const box = document.createElement('div'); box.classList.add('userSynchronize'); const inner = document.createElement('div'); const title = document.createElement('h3'); title.textContent = '特定同步率'; const searchPanel = document.createElement('div'); const dataPanel = document.createElement('div'); const searchInputs = document.createElement('div'); const input = document.createElement('input'); input.classList.add('inputtext'); input.type = 'text'; input.placeholder = '条目ID查看或条目名搜索'; input.style.width = 'auto'; input.style.fontSize = '1em'; const searchResult = document.createElement('div'); searchResult.classList.add('subjectListWrapper'); searchResult.style = ` max-height: 200px; overflow-y: scroll; `; const dataResult = document.createElement('div'); const searchSelect = document.createElement('select'); const searchBtn = makeBtn('搜索'); searchBtn.onclick = async () => { const keyword = input.value; if (keyword === '') return; searchResult.innerText = '搜索中……'; const data = await search(keyword, searchSelect.value); renderList(data, searchResult, async (href) => { const subject_id = href.split('/').pop(); console.log(subject_id) renderCollection((await getUserCollection(subject_id)), dataResult); }); } const dataBtn = makeBtn('查看评价'); dataBtn.onclick = async () => { const subject_id = input.value; if (!/\d+/.test(subject_id)) return; renderCollection((await getUserCollection(subject_id)), dataResult); } frag.append(box); box.append(title, inner); inner.append(searchPanel, dataPanel); searchPanel.append(searchInputs, searchResult); searchInputs.append(searchSelect, input, searchBtn, dataBtn); dataPanel.append(dataResult); searchSelect.innerHTML = `<option value="all">全部</option> <option value="2">动画</option> <option value="1">书籍</option> <option value="4">游戏</option> <option value="3">音乐</option> <option value="6">三次元</option>`; inner.style = ` display: flex; flex-wrap: wrap; `; searchPanel.style.flex = '0 1 300px'; dataPanel.style.flex = '1 1 200px'; searchSelect.style = ` background: transparent; border: none; padding: 0 5px; font-size: 1em; `; synchronize.after(frag); function makeBtn(text) { const btn = document.createElement('a'); btn.classList.add('chiiBtn'); btn.href = 'javascript:;'; btn.innerText = text; btn.style.textWrap = 'nowrap'; return btn; } async function search(keyword, type) { const response = await fetch(`https://api.bgm.tv/search/subject/${encodeURI(keyword)}?type=${type}`); if (!response.ok) throw new Error('API request failed'); return await response.json(); } function renderList(data, container, clickHandler) { const { list } = data; if (!list) { container.textContent = '搜索失败'; return; } const html = `<ul id="subjectList" class="subjectList ajaxSubjectList"> ${ list.reduce((m, { id, type, images, name, name_cn }) => { type = ['书籍', '动画', '音乐', '游戏', '', '三次元'][type - 1]; const grid = images?.grid; m += `<li class="clearit"> <a href="/subject/${id}" class="avatar h"> ${grid ? `<img src="${grid}" class="avatar ll">` : ''} </a> <div class="inner"> <small class="grey rr">${type}</small> <p><a href="/subject/${id}" class="avatar h">${name}</a></p> <small class="tip">${name_cn}</small> </div> </li>`; return m; }, '') } </ul>`; container.innerHTML = html; container.querySelectorAll('a').forEach(a => { a.addEventListener('click', e => { e.preventDefault(); clickHandler(a.href); }); }); } async function getUserCollection(subject_id) { const response = await fetch(`https://api.bgm.tv/v0/users/${username}/collections/${subject_id}`); if (response.ok) { const data = await response.json(); return data; } else if (response.status === 404) { const data = { not_found: true } return data; } else { throw new Error('Network response was not ok: ', response); } } function renderCollection(data, container) { const { not_found, rate, comment, updated_at, ep_status, vol_status, subject } = data; if (not_found) { container.textContent = '未找到本作标记'; return; } const { id, type, name, name_cn, volumes, eps } = subject; const verb = ['读', '看', '听', '玩', '', '看'][type - 1]; const html = `<li id="item_${id}" class="item even clearit"> <div class="inner" style="margin-left: 10px"> <h3> ${ name_cn ? `<a href="/subject/${id}" class="l">${name_cn}</a> <small class="grey">${name}</small>` : `<a href="/subject/${id}" class="l">${name}</a>` } </h3> <p class="collectInfo"> ${ rate ? `<span class="starstop-s"><span class="starlight stars${rate}"></span></span>` : '' } <span class="tip_j">${updated_at}</span> <span class="tip_i">/</span> <span class="tip"> ${[`想${verb}`, `${verb}过`, `在${verb}`, '搁置', '抛弃'][type-1]}</span> ${ ep_status ? ` <span class="tip_i">/</span> <span class="tip"> ${ ep_status }${ eps ? ` / ${eps}` : ''}话 </span> ` : ''} ${ vol_status ? ` <span class="tip_i">/</span> <span class="tip"> ${ vol_status }${ eps ? ` / ${volumes}` : ''}卷 </span> ` : ''} </p> ${ comment ? ` <div id="comment_box"><div class="item"><div class="text_main_even" style="float:none;width:unset"> <div class="text"> ${comment}</div> <div class="text_bottom"></div> </div></div></div></div> ` : '' } </li>`; container.innerHTML = html; } })();