チャンネルごとにコメント欄の表示・非表示を切り替え、設定を保存します。
// ==UserScript==
// @name YouTube Comment Toggle
// @name:ja YouTube コメント欄トグル (チャンネル別設定保存)
// @namespace http://tampermonkey.net/
// @version 1.1
// @description Hides or shows the comment section per channel with a dedicated toggle button.
// @description:ja チャンネルごとにコメント欄の表示・非表示を切り替え、設定を保存します。
// @author tac-tac-go
// @match https://www.youtube.com/watch*
// @license MIT
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// ==/UserScript==
(function() {
'use strict';
// ★ Default Blacklist: Add channel handles (e.g., '/@handle') to hide by default.
const defaultBlacklist = ['/@official_channel_id'];
let sessionBlacklist = GM_getValue('commentBlacklist', []);
let blacklist = Array.from(new Set([...defaultBlacklist, ...sessionBlacklist]));
// ■ 1. Define Persistent Hidden Style
// When the "yt-comments-hidden" class is present on the html tag,
// the comment section is strictly hidden regardless of YouTube's internal UI updates.
const css = `
html.yt-comments-hidden #comments,
html.yt-comments-hidden ytd-comments {
display: none !important;
}
`;
if (typeof GM_addStyle !== 'undefined') {
GM_addStyle(css);
} else {
const style = document.createElement('style');
style.textContent = css;
document.head.appendChild(style);
}
// ■ 2. Helper to fetch the current channel's handle
const getChannelHandle = () => {
const link = document.querySelector('#owner ytd-video-owner-renderer a.yt-simple-endpoint') ||
document.querySelector('#upload-info ytd-video-owner-renderer a.yt-simple-endpoint');
return link ? link.getAttribute('href') : null;
};
// ■ 3. Main Logic
const updateUI = () => {
const handle = getChannelHandle();
if (!handle) return;
const isBlacklisted = blacklist.includes(handle);
const htmlTag = document.documentElement;
// --- A. Sync Visibility (CSS Class) ---
if (isBlacklisted) {
if (!htmlTag.classList.contains('yt-comments-hidden')) {
htmlTag.classList.add('yt-comments-hidden');
}
} else {
if (htmlTag.classList.contains('yt-comments-hidden')) {
htmlTag.classList.remove('yt-comments-hidden');
}
}
// --- B. Sync Toggle Button ---
const ownerContainer = document.querySelector('#owner');
if (!ownerContainer) return;
let btn = ownerContainer.querySelector('#toggle-comment-btn');
const btnText = isBlacklisted ? '📢 Show Comments' : '🔇 Hide Comments';
if (!btn) {
btn = document.createElement('button');
btn.id = 'toggle-comment-btn';
btn.style.cssText = `
display: inline-flex; align-items: center; margin-left: 12px; padding: 0 16px;
height: 36px; border-radius: 18px; border: none; cursor: pointer;
font-size: 14px; font-weight: 500;
background-color: var(--yt-spec-badge-chip-background, rgba(255, 255, 255, 0.1));
color: var(--yt-spec-text-primary, white);
white-space: nowrap; vertical-align: middle;
`;
btn.onclick = (e) => {
e.preventDefault();
const currentHandle = getChannelHandle();
if (!currentHandle) return;
if (blacklist.includes(currentHandle)) {
blacklist = blacklist.filter(id => id !== currentHandle);
} else {
blacklist.push(currentHandle);
}
GM_setValue('commentBlacklist', blacklist);
updateUI();
};
ownerContainer.appendChild(btn);
}
// Update button text if it doesn't match the current state
if (btn.innerText !== btnText) {
btn.innerText = btnText;
}
};
// ■ 4. Triggering
setInterval(updateUI, 500);
window.addEventListener('yt-navigate-finish', updateUI);
})();