您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Labels English dubbed titles on MyAnimeList.net and adds dub only filtering to search, seasonal and top anime pages.
当前为
// ==UserScript== // @name MAL (MyAnimeList) Dubs // @namespace https://github.com/MAL-Dubs // @version 0.9.03 // @description Labels English dubbed titles on MyAnimeList.net and adds dub only filtering to search, seasonal and top anime pages. // @author MAL Dubs // @supportURL https://github.com/MAL-Dubs/MAL-Dubs/issues // @match http://myanimelist.net/* // @match https://myanimelist.net/* // @match http://*.myanimelist.net/* // @match https://*.myanimelist.net/* // @iconURL https://raw.githubusercontent.com/MAL-Dubs/MAL-Dubs/main/images/icon.png // @license GPL version 3.0; http://www.gnu.org/licenses/gpl-3.0.txt // @resource CSS https://raw.githubusercontent.com/MAL-Dubs/MAL-Dubs/main/css/style.css // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_getResourceText // @connect githubusercontent.com // @connect github.com // @run-at document-end // @noframes // ==/UserScript== (function() { const dubbedLinks = document.querySelectorAll("p.title-text>a,content-result .information>a:first-child,.list>.information>a:first-child,table.anime_detail_related_anime a[href^='/anime'],p.data a.title,td.data.title a:first-child,.list td:nth-child(2)>a.hoverinfo_trigger,#content>table>tbody>tr>td>table>tbody>tr>td.borderClass>a[href*='myanimelist.net/anime/'],#content>div>div>table>tbody>tr>td>a[href*='/anime'],#content>table>tbody>tr>td:nth-child(2)>div.js-scrollfix-bottom-rel>div>table>tbody>tr>td:nth-child(2)>div:nth-child(2)>a:nth-child(1),.news-container h2 a[href*='/anime/'],li.ranking-unit>div>h3>a,tr.ranking-list>td:nth-child(2)>div>div>h3>a,div.borderClass>a,#content>table>tbody>tr>td:nth-child(1)>a:nth-child(1),[id^='#revAreaItemTrigger'],.news-container a[href^='https://myanimelist.net/anime/'],.animeography>.title>a,#content>div:nth-child(3)>a"), dubbedRecs = document.querySelectorAll("div#anime_recommendation>div.anime-slide-outer>.anime-slide>li.btn-anime>a.link:not([href*='suggestion'])"), dubbedThumbs = "div.auto-recommendations>div.items>a.item,div.recommendations div.items>a.item,div#widget-seasonal-video li.btn-anime>a.link,div#anime_recommendation li.btn-anime.auto>a.link,.js-seasonal-anime>.image>a:nth-child(1)", rgx = /^(https?:\/\/myanimelist\.net)?\/?anime\/(\d+)\/?.*/, recrgx = /^(https?:\/\/myanimelist\.net)?\/recommendations\/anime\/(\d+\-\d+)\/?.*/, filteruri = /.*\/(((anime\.php\?(?!id).+|topanime\.php.*))|anime\/(genre|producer|season)\/?.*)/; const IDURL = `https://raw.githubusercontent.com/MAL-Dubs/MAL-Dubs/main/data/dubIDs.json`, incompleteDubs = [122,170,235,250,516,687,738,918,966,967,1486,2280,7674,8687,10033,40010]; GM_addStyle(GM_getResourceText('CSS')); var dubbedIDs = JSON.parse(localStorage.getItem('dubIDs')); if(dubbedIDs === null){ GM_xmlhttpRequest({ method: "GET", nocache: true, url: IDURL, onload: function(response) { dubbedIDs = JSON.parse(response.responseText); localStorage.setItem('dubIDs',response.responseText); onComplete(); localStorage.setItem('dubCacheDate',Date.now()); } }); } else { onComplete(); dubCache(); } function onComplete() { if (document.location.href.match(/.*\/animelist\/.*/)) { setTimeout(()=>parseList(),0); } else { parseSite(); if (document.location.href.match(filteruri)) {searchFilter();} if (document.location.href.match(rgx)) {animePages();} setTimeout(()=>labelThumbnails(),400); } } function dubCache() { if (localStorage.getItem('dubCacheDate') === null){localStorage.setItem('dubCacheDate',Date.now());} if(parseInt(localStorage.getItem('dubCacheDate'))+600000<Date.now()){ GM_xmlhttpRequest({ method: "GET", url: IDURL, nocache: true, revalidate: true, onload: function(response) { localStorage.setItem('dubIDs',response.responseText); localStorage.setItem('dubCacheDate',Date.now()); } }); } } function labelDub(anime) { if (rgx.test(anime.href)) { var linkID = parseInt(anime.href.match(/\/(\d+)\//)[1]); if (dubbedIDs.includes(linkID)) { anime.title = "Dubbed"; if (incompleteDubs.includes(linkID)) {anime.title = "Incomplete Dub";} } else {anime.title = "Undubbed";} } } function parseSite() { labelThumbnails(); dubbedLinks.forEach (e => {labelDub(e);}); } function animePages() { var thispage = rgx.exec(document.location.href)[2]; if (dubbedIDs.includes(parseInt(thispage))) { var pagetitle = document.querySelectorAll("h1.title-name")[0]; pagetitle.title = "Dubbed"; if (incompleteDubs.includes(parseInt(thispage))) {pagetitle.title = "Incomplete Dub";} } dubbedRecs.foreach ( e => { var recID = parseInt(recrgx.exec(e)[2].replace(thispage+"-", "").replace("-"+thispage,"")); if (dubbedIDs.includes(recID)) { e.title = "Dubbed"; e.classList.add("imagelink"); if (incompleteDubs.includes(recID)) {e.title = "Incomplete Dub";} } }); } function scanList() { let listEntries = document.querySelectorAll('#list-container>div.list-block>div>table>tbody[class=list-item]>tr.list-table-data>td.data.title>a.link,div#list_surround>table>tbody>tr>td>a.animetitle'); listEntries.forEach( e => { if (e.classList.contains('checked')) { return true; } else { labelDub(e); e.classList.add('checked'); } }); } function addScrollListener() { document.addEventListener("scroll", function scroll(event) { event.currentTarget.removeEventListener(event.type, scroll); scanList(); setTimeout(() => addScrollListener(), 1000); }); } function parseList() { setTimeout(function() { scanList(); addScrollListener(); }, 50); } function labelThumbnails() { document.querySelectorAll(dubbedThumbs).forEach(e => { labelDub(e); e.classList.add("imagelink"); }); } function hideUndubbed(links) { links.forEach(e => { if(document.location.href.match(/.*\/topanime\.php.*/)){ e.parentNode.parentNode.parentNode.parentNode.parentNode.classList.add("hidden"); } else {e.parentNode.parentNode.classList.add("hidden");} }); } function showUndubbed(links) { links.forEach(e => { if(document.location.href.match(/.*\/topanime\.php.*/)){ e.parentNode.parentNode.parentNode.parentNode.parentNode.classList.remove("hidden"); } else {e.parentNode.parentNode.classList.remove("hidden");} }); } function searchFilter() { let undubbed = document.querySelectorAll('[title="Undubbed"]'), filterTarget = document.querySelector('.js-search-filter-block>div.fl-r.di-ib.mt4.mr12,div.horiznav-nav-seasonal>span[data-id="sort"],h2.top-rank-header2>span.fs10.fw-n.ff-Verdana.di-ib.ml16,.normal_header.js-search-filter-block>.di-ib,.normal_header>div.fl-r.di-ib.fs11.fw-n'), filterCheckbox = document.createElement('input'), label = document.createElement('label'); if(filterTarget !== null){ filterCheckbox.type = 'checkbox'; filterCheckbox.id = 'undubbed-filter'; label.setAttribute('for','undubbed-filter'); label.className = 'fs11 fl-r btn-show-undubbed mr12 fw-n'; label.appendChild(document.createTextNode('Dub Only')); filterTarget.after(filterCheckbox); filterCheckbox.after(label); } let filter = true; let filterUndubbed = (localStorage.getItem('dubOnlySearch') === "true"); if(filterUndubbed === null){ filterUndubbed = false; localStorage.setItem('dubOnlySearch', filterUndubbed); filterCheckbox.checked = filterUndubbed; filter = false; } if (filter) { filterCheckbox.checked = filterUndubbed; if(filterCheckbox.checked === true) {hideUndubbed(undubbed);} } filterCheckbox.addEventListener('change',function () { if(filterCheckbox.checked === true){hideUndubbed(undubbed);} if(filterCheckbox.checked === false){showUndubbed(undubbed);} localStorage.setItem('dubOnlySearch', filterCheckbox.checked); },false); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址