tvwiki · tvmon · sbxh3 광고 제거 & 클린 뷰어
// ==UserScript==
// @name CleanJun
// @namespace http://tampermonkey.net/
// @version 2026-05-28
// @description tvwiki · tvmon · sbxh3 광고 제거 & 클린 뷰어
// @author Seo
// @include /^https?:\/\/[^/]*tvwiki[^/]*\/.*$/
// @include /^https?:\/\/[^/]*tvmon[^/]*\/.*$/
// @include /^https?:\/\/[^/]*sbxh3[^/]*\/.*$/
// @grant GM_addStyle
// ==/UserScript==
(function () {
'use strict';
GM_addStyle(`
/* tvwiki 그리드 배너 */
ul.banner2, #bannerList { display: none !important; }
/* tvwiki 플레이어 아래 가로 배너 */
#bo_v li.full,
#bo_v > ul,
.bo_v_mov + ul { display: none !important; }
/* tvmon 상단 그리드 배너 */
.banner_wrap2 { display: none !important; }
#banner-row-1, #banner-row-2,
#banner-row-3, #banner-row-4 { display: none !important; }
#fixed-banner-container-1,
#fixed-banner-container-2,
#fixed-banner-container-3 { display: none !important; }
/* tvmon 플레이어 아래 가로 배너 */
.banner-area { display: none !important; }
.banner-item { display: none !important; }
.pc-banner { display: none !important; }
.mobile-banner { display: none !important; }
/* 공지, 팝업, 오버레이 */
.notice { display: none !important; }
.emer-content { display: none !important; }
.over { display: none !important; }
.modal-backdrop { display: none !important; }
.ad-wrap, .ad-box, .ad-layer { display: none !important; }
.popup-wrap, .layer-popup { display: none !important; }
#popupLayer, #adLayer, #modal-ad { display: none !important; }
.fixed-banner, .float-ad, .float-banner { display: none !important; }
.bottom-fixed, .side-banner, .corner-ad { display: none !important; }
.sticky-ad, .sticky-banner { display: none !important; }
/* 줄거리, 배우, 댓글 */
#bo_v_atc { display: none !important; }
.cast { display: none !important; }
.view-comment-area { display: none !important; }
/* 기존 이전화/다음화 버튼 강제 표시 */
.bo_v_nb, .bo_v_nb_mobile {
display: flex !important;
visibility: visible !important;
opacity: 1 !important;
}
/* ===== CleanStream 커스텀 네비 버튼 ===== */
#cs-nav-buttons {
display: flex !important;
justify-content: center;
align-items: center;
gap: 12px;
width: 100%;
max-width: 1249px;
margin: 8px auto 0;
padding: 0 8px;
box-sizing: border-box;
}
#cs-nav-buttons a {
display: flex !important;
align-items: center;
justify-content: center;
gap: 8px;
flex: 1;
max-width: 300px;
padding: 12px 20px;
background: linear-gradient(135deg, #1e1e2e 0%, #16213e 100%);
border: 1px solid rgba(255,255,255,0.12);
border-radius: 10px;
color: rgba(255,255,255,0.9) !important;
font-size: 14px;
font-weight: 600;
text-decoration: none !important;
transition: all 0.2s ease;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
cursor: pointer;
}
#cs-nav-buttons a:hover {
background: linear-gradient(135deg, #2a2a3e 0%, #1e2d4e 100%);
border-color: rgba(255,255,255,0.25);
transform: translateY(-2px);
box-shadow: 0 6px 18px rgba(0,0,0,0.4);
color: #fff !important;
}
#cs-nav-buttons a.cs-disabled {
opacity: 0.3;
pointer-events: none;
cursor: not-allowed;
}
#cs-nav-buttons .cs-prev {
border-left: 3px solid #4a9eff;
}
#cs-nav-buttons .cs-next {
border-right: 3px solid #4a9eff;
}
#cs-nav-buttons .cs-arrow {
font-size: 18px;
line-height: 1;
}
@media (max-width: 768px) {
#cs-nav-buttons a {
padding: 10px 14px;
font-size: 13px;
}
}
`);
// 팝업 새탭 광고 차단
window.open = function (url) {
console.log('[CleanStream] 팝업 차단:', url);
return null;
};
// 광고 도메인 키워드
const adKeywords = [
'cdn3k.site', 'tvmon1.com/data/banner',
'/data/banner/', 'banner', 'advert', '/ads/',
'adsystem', 'doubleclick', 'googlesyndication',
'adsbygoogle', 'tracking', 'clickadu',
'exoclick', 'juicyads', 'trafficjunky', 'propellerads'
];
function isAdUrl(src) {
if (!src) return false;
return adKeywords.some(k => src.toLowerCase().includes(k));
}
function removeAdElements() {
document.querySelectorAll('ul.banner2, #bannerList').forEach(el => el.remove());
document.querySelectorAll('#bo_v > ul, .bo_v_mov + ul').forEach(el => {
if (el.querySelector('li.full, li.pc-only, li.mobile-only')) el.remove();
});
document.querySelectorAll(
'.banner_wrap2, #banner-row-1, #banner-row-2, #banner-row-3, #banner-row-4,' +
'#fixed-banner-container-1, #fixed-banner-container-2, #fixed-banner-container-3'
).forEach(el => el.remove());
document.querySelectorAll('.banner-area, .banner-item, .pc-banner, .mobile-banner').forEach(el => el.remove());
document.querySelectorAll('img').forEach(el => {
if (isAdUrl(el.src)) {
el.closest('li, a, div.banner-item, div')?.remove() || el.remove();
}
});
document.querySelectorAll('iframe').forEach(el => {
if (isAdUrl(el.src)) el.remove();
});
document.querySelectorAll('a[target="_blank"]').forEach(el => {
if (isAdUrl(el.href)) {
el.removeAttribute('href');
el.style.pointerEvents = 'none';
el.style.display = 'none';
}
});
[
'.modal-backdrop', '.ad-wrap', '.ad-box', '.ad-layer',
'.popup-wrap', '.layer-popup', '#popupLayer', '#adLayer',
'#modal-ad', '.fixed-banner', '.float-ad', '.float-banner',
'.bottom-fixed', '.side-banner', '.corner-ad',
'.sticky-ad', '.sticky-banner', '.over',
].forEach(sel => {
document.querySelectorAll(sel).forEach(el => el.remove());
});
document.querySelectorAll('*').forEach(el => {
const tag = el.tagName.toLowerCase();
if (['script','style','html','body','video','head'].includes(tag)) return;
if (tag === 'iframe' && el.closest('.frame-video, .playstart, .embed-container')) return;
const s = window.getComputedStyle(el);
if (s.position === 'fixed' || s.position === 'sticky') {
if (el.offsetWidth > window.innerWidth * 0.9 &&
el.offsetHeight > window.innerHeight * 0.9) return;
el.remove();
}
});
document.querySelectorAll('.bo_v_nb, .bo_v_nb_mobile').forEach(el => {
el.style.display = 'flex';
el.style.visibility = 'visible';
el.style.opacity = '1';
});
}
// ===== 플레이어 바로 아래 이전화/다음화 버튼 생성 =====
function createNavButtons() {
if (document.getElementById('cs-nav-buttons')) return;
const playerArea = document.getElementById('playerArea')
|| document.querySelector('.bo_v_mov')
|| document.querySelector('.embed-container');
if (!playerArea) return;
let prevUrl = null, nextUrl = null;
// ── tvwiki: .bo_v_nb / .bo_v_nb_mobile ──
document.querySelectorAll('.bo_v_nb a, .bo_v_nb_mobile a').forEach(a => {
const li = a.closest('li');
if (!li) return;
const href = a.href || '';
if (href.startsWith('javascript:')) return;
if (li.classList.contains('btn_prv')) prevUrl = href;
if (li.classList.contains('btn_next')) nextUrl = href;
});
// ── tvmon: #other_list 회차 목록 ──
if (!prevUrl && !nextUrl) {
const epItems = Array.from(
document.querySelectorAll('#other_list ul li[data-ep-idx]')
);
if (epItems.length) {
const currentHref = location.href.replace(/\/$/, '');
let curPos = -1;
epItems.forEach((item, i) => {
const a = item.querySelector('a');
if (a && a.href.replace(/\/$/, '') === currentHref) curPos = i;
});
if (curPos === -1 && typeof window.currentEpIdx !== 'undefined') {
curPos = epItems.findIndex(el =>
parseInt(el.getAttribute('data-ep-idx')) === parseInt(window.currentEpIdx)
);
}
if (curPos !== -1) {
if (curPos > 0) {
const a = epItems[curPos - 1].querySelector('a');
if (a) nextUrl = a.href;
}
if (curPos < epItems.length - 1) {
const a = epItems[curPos + 1].querySelector('a');
if (a) prevUrl = a.href;
}
}
}
}
// 버튼 컨테이너 생성
const nav = document.createElement('div');
nav.id = 'cs-nav-buttons';
const prevBtn = document.createElement('a');
prevBtn.className = 'cs-prev' + (prevUrl ? '' : ' cs-disabled');
prevBtn.href = prevUrl || '#';
prevBtn.innerHTML = `<span class="cs-arrow">◀</span> 이전화`;
if (prevUrl) prevBtn.addEventListener('click', e => {
e.preventDefault(); location.href = prevUrl;
});
const nextBtn = document.createElement('a');
nextBtn.className = 'cs-next' + (nextUrl ? '' : ' cs-disabled');
nextBtn.href = nextUrl || '#';
nextBtn.innerHTML = `다음화 <span class="cs-arrow">▶</span>`;
if (nextUrl) nextBtn.addEventListener('click', e => {
e.preventDefault(); location.href = nextUrl;
});
nav.appendChild(prevBtn);
nav.appendChild(nextBtn);
playerArea.parentNode.insertBefore(nav, playerArea.nextSibling);
}
document.addEventListener('DOMContentLoaded', function () {
// 상단 메뉴 높이 수정 (tvwiki)
const header = document.getElementById('header');
if (header) header.style.height = '80px';
document.querySelectorAll('.top-menus').forEach(el => el.style.height = '150px');
document.querySelectorAll('.coordinates').forEach(el => el.style.height = '50px');
document.querySelectorAll('.title').forEach(el => el.style.height = '50px');
document.querySelectorAll('.main-ranking').forEach(el => el.style.height = '474px');
// 재생 플레이어 스타일 (tvwiki)
document.querySelectorAll('.playstart').forEach(el => el.style.padding = '0');
document.querySelectorAll('.frame-video').forEach(el => el.style.marginTop = '0');
document.querySelectorAll('.player-header').forEach(el => el.style.padding = '10px 0');
// 다음화 항상 보이게 (tvwiki)
document.querySelectorAll('.video-remote').forEach(el => {
el.style.display = 'block';
el.style.bottom = '60px';
el.style.width = '150px';
});
// 광고 제거 첫 실행
removeAdElements();
// 동적 광고 지속 감지
const observer = new MutationObserver(removeAdElements);
observer.observe(document.body, { childList: true, subtree: true });
window.addEventListener('unload', () => observer.disconnect());
// 전체화면
document.documentElement.requestFullscreen().catch(() => {});
});
// 이전화/다음화 버튼 — window.load 이후 실행 (모든 요소 준비 후)
window.addEventListener('load', function () {
createNavButtons();
setTimeout(createNavButtons, 1000);
setTimeout(createNavButtons, 3000);
});
})();