您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Limit comments, stop infinite scroll, and remove 3rd recommendation (random low view count video)
当前为
// ==UserScript== // @name Youtube reduced // @namespace http://tampermonkey.net/ // @version 0.1 // @description Limit comments, stop infinite scroll, and remove 3rd recommendation (random low view count video) // @author You // @match https://www.youtube.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com // @grant none // @license MIT // ==/UserScript== var commentCount = 5; var url = ''; var readyInterval; var commentRefresher; const config = { attributes: true, childList: true, subtree: false }; (async function() { setInterval(checkPageChanged, 500); })(); function checkPageChanged(){ if(document.location != url){ console.log("[yt-reduced] - new vid"); url = document.location.toString(); readyInterval = setInterval(checkPageReady, 500); } } function checkPageReady(){ const comments = document.getElementsByTagName("YTD-COMMENTS")[0]; if(comments?.children.length > 0 && comments?.querySelector("#contents").children?.length > 1 && document.getElementsByTagName("YTD-ITEM-SECTION-RENDERER")?.[2]?.querySelector("#contents").children?.length > 0) { // check the comments and recommendations have fully loaded first clearInterval(readyInterval); console.log("[yt-reduced] - limiting comments to ["+commentCount+"]"); removeComments(); removeThirdRecommendation(); //onlyRelevant(); } } /* // was thinking about removing all recommendations that don't match with the main video title function titleMatch(main, rec) { return main.some(t => { return rec.includes(t.toLowerCase()); }) } function onlyRelevant() { const container = document.getElementsByClassName("ytd-watch-next-secondary-results-renderer")[1]; const contents = container.querySelector("#contents"); const title = document.getElementsByClassName("ytd-video-primary-info-renderer")[5].textContent.split(" ").map(l => l.toLowerCase()); contents.removeChild(contents.lastElementChild); console.log("updates", title, contents.children.length); var child; for(let i=contents.children.length; i>0;i--) { child = contents.lastElementChild; const recTitle = child.getElementsByTagName("H3")[0]?.textContent.trim().split(" ").map(l => l.toLowerCase()); const match = titleMatch(title, recTitle); console.log('checking', child.tagName, match); if(!match || child.tagName == "YTD-CONTINUATION-ITEM-RENDERER") { console.log("removing", recTitle); contents.removeChild(child); } } } */ function removeThirdRecommendation() { const contents = document.getElementsByTagName("YTD-ITEM-SECTION-RENDERER")[2].querySelector("#contents"); const extra = contents.getElementsByTagName("YTD-PROMOTED-SPARKLES-WEB-RENDERER"); const third = contents.getElementsByTagName("YTD-COMPACT-VIDEO-RENDERER"); console.log("[yt-reduced] - removing 3rd video"); // sometimes this video isn't in the 3rd slot? I think because of the playlists around that area contents.removeChild(third[2]); contents.removeChild(third[1]); contents.removeChild(contents.lastElementChild); // last child fetches more videos so that's removed too } function removeComments() { const comments = document.getElementsByTagName("YTD-COMMENTS")[0].querySelector("#contents"); const callback = function(mutationsList, observer) { //console.log("update", mutationsList); if(mutationsList?.[0].target.firstChild.tagName == "YTD-CONTINUATION-ITEM-RENDERER") { console.log("[yt-reduced] - resetting comments"); const renderer = mutationsList?.[0].target.firstChild; renderer.style.display = "unset"; return; } var child = comments.firstElementChild; for(let i=comments.children.length; i>0;i--) { child = comments.lastElementChild; if(i > commentCount || child.tagName == "YTD-CONTINUATION-ITEM-RENDERER") { if(child.tagName == "YTD-CONTINUATION-ITEM-RENDERER") { child.style.display = "none"; // last child in comments fetches more, so gets hidden, and then gets reset on a new video commentRefresher = child; } else comments.removeChild(child); } } }; const bodyObserver = new MutationObserver(callback); // runs the comments check when the container changes bodyObserver.observe(comments, config); }