您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
簡單粗暴地為每個動畫封面添加評分顯示,並排序
当前为
// ==UserScript== // @name 動畫瘋評分顯示 // @namespace Anong0u0 // @version 0.1 // @description 簡單粗暴地為每個動畫封面添加評分顯示,並排序 // @author Anong0u0 // @match https://ani.gamer.com.tw/animeList.php* // @match https://ani.gamer.com.tw/mygather.php* // @match https://ani.gamer.com.tw/* // @icon https://i.imgur.com/2aijUa9.png // @grant GM_xmlhttpRequest // @connect api.gamer.com.tw // @connect wall.gamer.com.tw // @license MIT // ==/UserScript== const delay = (ms = 0) => {return new Promise((r)=>{setTimeout(r, ms)})} const waitElementLoad = (elementSelector, selectCount = 1, tryTimes = 1, interval = 0) => { return new Promise(async (resolve, reject)=> { let t = 1, result; while(true) { if(selectCount != 1) {if((result = document.querySelectorAll(elementSelector)).length >= selectCount) break;} else {if(result = document.querySelector(elementSelector)) break;} if(tryTimes>0 && ++t>tryTimes) return reject(new Error("Wait Timeout")); await delay(interval); } resolve(result); }) } const requests = (method, url, data = null, headers = {}) => { return new Promise(resolve => { GM_xmlhttpRequest({ method: method, url: url, headers: headers, data: data, onload: resolve }); }) } Node.prototype.prependChild = function(element) {return this.insertBefore(element, this.firstChild)} (async ()=> { const lists = await waitElementLoad("div.theme-list-block", 0, 10, 200) for (const list of lists) { const label = document.createElement("label") label.style="padding-left:1em;" label.innerHTML=`<input checked="true" type="checkbox" style="width:1.5em;height:1.5em;">依評分排序` list.parentElement.querySelector(".theme-title-block").firstElementChild.append(label) const elements = [...list.querySelectorAll("a.theme-list-main[href^='animeRef.php?sn=']")] const tip = document.createElement("span") tip.style="padding-left:1em;" let count = 0 tip.innerText = `讀取評分中(${count}/${elements.length})` label.insertAdjacentElement("beforebegin", tip) for (const element of elements) { const refID = element.href.match(/(?<=sn=)\d+/g); const videoID = (await requests("head", `https://ani.gamer.com.tw/animeRef.php?sn=${refID}`)).finalUrl.match(/(?<=sn=)\d+/g); const reviewID = JSON.parse((await requests("get", `https://wall.gamer.com.tw/app/v2/comment_detail.php?service=4&serviceId=${videoID}`)).responseText).to.id; const avgRating = JSON.parse((await requests("get", `https://api.gamer.com.tw/acg/v1/reviews_list.php?sn=${reviewID}`)).responseText).data.rating.avg.toFixed(1); //console.log(refID); //console.log(videoID); //console.log(reviewID); //const name = element.querySelector(".theme-name") //console.log(avgRating, name.innerText); const ratingBlock = document.createElement("div") ratingBlock.className = "anime-label-block" ratingBlock.style = "top: 6px;bottom: unset;" ratingBlock.innerHTML = `<span class="label-edition color-paid" style="background-color: var(--anime-primary-color);">${avgRating}</span>` element.querySelector(".theme-img-block").append(ratingBlock) element.rating = avgRating element.videoID = videoID element.refID = refID tip.innerText = `讀取評分中(${++count}/${elements.length})` } tip.remove() label.onclick = ()=> { if(label.firstElementChild.checked) elements.sort((a, b)=> a.rating-b.rating || a.videoID-b.videoID).forEach((e)=>{list.prependChild(e)}) else elements.sort((a, b)=> a.refID-b.refID).forEach((e)=>{list.prependChild(e)}) } if(label.firstElementChild.checked) label.onclick() } // TODO: homepage timeline anime // TODO: homepage load more button // TODO: cache rating in ls = [rating, refID, videoID, imgID] // TODO: sort anime by rating (read all page) })()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址