Limit comments, stops infinite scroll, and removes the 3rd recommendation (random low view count video)
当前为
// ==UserScript==
// @name YouTube Reduced
// @namespace http://tampermonkey.net/
// @version 0.3.0
// @description Limit comments, stops infinite scroll, and removes the 3rd recommendation (random low view count video)
// @author mewen25
// @match https://www.youtube.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @grant none
// @license MIT
// ==/UserScript==
/*
Aiming to reduce time spent on each video, whether that be drastically fewer commments or videos on the side.
I found options to completely remove those elements to be too much.
The method for selecting the elements is not very good, probably some inconsistency.
And other extensions affecting the dom will probably just make this break.
There's a fair bit of bloat just to handle navigating to videos without a full refresh
*/
var commentCount = 5;
var recommendedCount = 11;
var verbose = true;
var url = '';
var readyInterval;
var thirdRemoved = false;
var commentsLimited = false;
var recommendedLimited = false;
var commentRefresher;
var recommendRefresher;
const config = { attributes: true, childList: true, subtree: false };
(async function() {
setInterval(checkPageChanged, 500);
})();
//window.addEventListener('resize', () => {
// console.log("resized?");
// checkPageReady();
//});
function checkPageChanged(){
if(document.location.toString() != url && document.location.toString().startsWith("https://www.youtube.com/watch?v")){
if(verbose) console.log("[yt-reduced] - new vid");
thirdRemoved = false;
commentsLimited = false;
recommendedLimited = false;
url = document.location.toString();
readyInterval = setInterval(checkPageReady, 100);
}
}
function checkPageReady(){
const comments = document.getElementsByTagName("YTD-COMMENTS")?.[0];
const vids = document.getElementsByTagName("YTD-ITEM-SECTION-RENDERER")?.[2]?.querySelector("#contents");
if(comments?.children.length > 0 && comments?.querySelector("#contents").children?.length > 1 && vids?.children?.length > 0) {
removeComments();
limitRecommendations();
clearInterval(readyInterval);
}
}
/*
// 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 limitRecommendations() {
const contents = document.getElementsByTagName("YTD-ITEM-SECTION-RENDERER")[2];
const vids = document.getElementsByTagName("YTD-ITEM-SECTION-RENDERER")[2].querySelector("#contents");
if(verbose) console.log("[yt-reduced] - Limiting recommendations to ["+recommendedCount+"]");
const callback = function(mutationsList, observer) {
//console.log("update", mutationsList);
const extra = vids.getElementsByTagName("YTD-PROMOTED-SPARKLES-WEB-RENDERER");
//if(extra.length > 0) extra.forEach(e => vids.removeChild(e));
if(mutationsList?.[0].target.firstChild.tagName == "YTD-CONTINUATION-ITEM-RENDERER") {
const vids = document.getElementsByTagName("YTD-ITEM-SECTION-RENDERER")[2].querySelector("#contents");
const renderer = mutationsList?.[0].target.firstChild;
renderer.style.display = "unset";
const contents = document.getElementsByTagName("YTD-ITEM-SECTION-RENDERER")[2].querySelector("#contents");
vids.lastElementChild.style.display = "unset";
recommendedLimited = false;
return;
}
let child;
if(!recommendedLimited) {
for(let i=vids.children.length; i>0;i--) {
child = vids.lastElementChild;
if(i > recommendedCount || child.tagName == "YTD-CONTINUATION-ITEM-RENDERER") {
if(child.tagName == "YTD-CONTINUATION-ITEM-RENDERER") {
//if(verbose) console.log("[yt-reduce] - removed recommended auto refresh");
child.style.display = "none"; // last child in recommended fetches more, so gets hidden, and then gets reset on a new video
recommendRefresher = child;
recommendedLimited = true;
}
else vids.removeChild(child);
}
}
}
//}
};
const bodyObserver = new MutationObserver(callback); // runs the comments check when the container changes
bodyObserver.observe(vids, config);
removeThirdRecommendation();
}
function removeThirdRecommendation() {
const contents = document.getElementsByTagName("YTD-ITEM-SECTION-RENDERER")[2].querySelector("#contents");
const third = contents.getElementsByTagName("YTD-COMPACT-VIDEO-RENDERER");
if(!thirdRemoved) {
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]);
thirdRemoved = true;
}
}
function removeComments() {
const comments = document.getElementsByTagName("YTD-COMMENTS")[0].querySelector("#contents");
if(verbose) console.log("[yt-reduced] - limiting comments to ["+commentCount+"]");
const callback = function(mutationsList, observer) {
//console.log("update", mutationsList);
if(mutationsList?.[0].target.firstChild.tagName == "YTD-CONTINUATION-ITEM-RENDERER") {
if(verbose) console.log("[yt-reduced] - resetting page");
const vids = document.getElementsByTagName("YTD-ITEM-SECTION-RENDERER")[2].querySelector("#contents");
const renderer = mutationsList?.[0].target.firstChild;
renderer.style.display = "unset";
const contents = document.getElementsByTagName("YTD-ITEM-SECTION-RENDERER")[2].querySelector("#contents");
contents.lastElementChild.style.display = "unset";
vids.lastElementChild.style.display = "unset";
commentsLimited = false;
recommendedLimited = false;
thirdRemoved = false;
return;
}
//if(!commentsLimited) {
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") {
//if(verbose) console.log("[yt-reduce] - removed comments auto refresh");
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);
}
}
commentsLimited = true;
//}
};
const bodyObserver = new MutationObserver(callback); // runs the comments check when the container changes
bodyObserver.observe(comments, config);
}