將 Webtoons 網頁背景轉換為黑色,提供舒適的閱讀體驗
// ==UserScript==
// @name Webtoon Dark Mode
// @name:zh-TW Webtoon 深色模式
// @name:zh-CN Webtoon 深色模式
// @name:ja Webtoon ダークモード
// @name:ko 웹툰 다크 모드
// @namespace http://tampermonkey.net/
// @version 3.2
// @description Switch Webtoons background to black for a more comfortable reading experience.
// @description:zh-TW 將 Webtoons 網頁背景轉換為黑色,提供舒適的閱讀體驗
// @description:zh-CN 将 Webtoons 网页背景转换为黑色,提供舒适的阅读体验
// @description:ja Webtoonのウェブ背景を黒に変更し、快適な読書体験を提供します。
// @description:ko 웹툰 웹페이지 배경을 블랙으로 전환하여 더욱 편안한 감상 경험을 제공합니다.
// @author Hzbrrbmin + Gemini
// @match https://www.webtoons.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=webtoons.com
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const css = `
/* 1. 基礎背景與文字顏色設定 */
html, body, #wrap, #container, #content, .left_area, .right_area, .detail_body, .detail_header, .viewer_header {
background-color: #121212 !important;
color: #e0e0e0 !important;
}
/* 2. 頂部與底部導航 */
#header, #footer {
background-color: #000000 !important;
border-bottom: 1px solid #333 !important;
border-top: 1px solid #333 !important;
}
/* 3. 閱讀器背景 */
#viewer_wrapper, .viewer_lst .viewer_img, #viewer, .viewer_img {
background-color: #000000 !important;
}
/* 4. 確保圖片透明 */
img {
background-color: transparent !important;
}
/* 5. 文字與連結顏色 */
a, h1, h2, h3, h4, span, p, .subj, .sub_title, .author, .date, .tx, .info_area .title {
color: #e0e0e0 !important;
}
/* 6. 處理特定區塊白色殘留與背景漸層 */
#bottomEpisodeList.episode_area,
#noticeArea.notice_area,
.foot_app,
.snb_wrap,
.viewer_info_area,
#container.bg,
.cont_box,
.detail_body.banner,
.detail_body.challenge,
.detail_body.banner .detail_lst,
.detail_body.challenge .detail_lst,
.episode_lst,
.discover_lst,
.ct_box .cont_box2 .inner_wrap,
.redeem_wrap .redeem_area,
.notice_area2 {
background-color: #121212 !important;
background-image: none !important;
background: #121212 !important;
border-color: #333 !important;
}
.discover_lst li { background-color: #121212 !important; }
/* 7. 移除官方漸層遮罩 */
.bg_detail, .detail_body:before { background: none !important; }
/* =============== 集數列表懸浮反白問題 =============== */
.episode_lst li:hover, .episode_lst li a:hover, .episode_lst li.hover > a,
.discover_lst li:hover, .discover_lst li a:hover,
html body .detail_body .detail_lst ul#_listUl li._episodeItem:hover,
html body .detail_body .detail_lst ul#_listUl li._episodeItem:hover > a,
html body .detail_body .detail_lst ul#_listUl li._episodeItem a:hover,
html body .detail_body .detail_lst ul#_listUl li._episodeItem.on,
html body .detail_body .detail_lst ul#_listUl li._episodeItem.on > a {
background-color: #222222 !important;
background: #222222 !important;
background-image: none !important;
border-color: #333 !important;
}
/* 徹底關閉並清空官方藏在這裡的隱形遮罩 */
.episode_lst li:hover::after, .episode_lst li:hover::before,
.episode_lst li a:hover::after, .episode_lst li a:hover::before,
.discover_lst li:hover::after, .discover_lst li:hover::before,
html body .detail_body .detail_lst ul#_listUl li._episodeItem::after,
html body .detail_body .detail_lst ul#_listUl li._episodeItem::before,
html body .detail_body .detail_lst ul#_listUl li._episodeItem a::after,
html body .detail_body .detail_lst ul#_listUl li._episodeItem a::before {
display: none !important;
background: none !important;
content: none !important;
}
/* 強制懸浮時內部的文字也保持淺色 */
.episode_lst li:hover *, .episode_lst li a:hover *, .discover_lst li:hover *,
html body .detail_body .detail_lst ul#_listUl li._episodeItem:hover *,
html body .detail_body .detail_lst ul#_listUl li._episodeItem a:hover * {
color: #e0e0e0 !important;
}
/* =============== 彈出視窗 (Modals / Dialogs) =============== */
.ly_wrap .ly_box, .ly_box {
background-color: #1e1e1e !important;
border: 1px solid #333 !important;
box-shadow: 0 4px 12px rgba(0,0,0,0.5) !important;
}
.ly_wrap .ly_box *, .ly_box * { color: #e0e0e0 !important; }
/* =============== 帳號、登入與表單區塊 =============== */
.ly_loginbox, .ly_loginbox .loginbox_cont { background-color: #1e1e1e !important; border-color: #333 !important; }
.ly_loginbox .loginbox_cont li { border-color: #333 !important; }
.ly_loginbox .loginbox_cont li a, .ly_loginbox .loginbox_cont li button { color: #e0e0e0 !important; background-color: transparent !important; }
.ly_loginbox .loginbox_cont li:hover { background-color: #2a2a2a !important; }
.ly_loginbox .loginbox_cont li:hover a, .ly_loginbox .loginbox_cont li:hover button { color: #ffffff !important; }
.account_wrap, .account_wrap .account_area, #nicknameDefaultArea, #nicknameEditArea {
background-color: #121212 !important; background-image: none !important; border-color: #333 !important;
}
.account_wrap *, .account_area * { color: #e0e0e0 !important; }
.account_area .change_btn,
.account_area .edit_btn,
.account_area .check_btn {
color: #dddddd !important;
background-color: transparent !important;
border: 1px solid rgba(255, 255, 255, 0.4) !important;
transition: all 0.2s ease !important;
}
.account_area .change_btn:hover,
.account_area .edit_btn:hover,
.account_area .check_btn:hover {
color: #ffffff !important;
border-color: #ffffff !important;
background-color: rgba(255, 255, 255, 0.08) !important;
}
.input_box input,
input.input_account,
.redeem_area input[type="text"] {
background-color: #1a1a1a !important;
color: #ffffff !important;
border: 1px solid #444 !important;
}
.input_box input:focus, input.input_account:focus, .redeem_area input[type="text"]:focus {
outline: none !important;
border-color: #888 !important;
}
/* =============== 公告表格 (Notice Table) =============== */
.tb_notice, .tb_notice th, .tb_notice td, .tb_notice tbody tr {
background-color: #121212 !important;
border-color: #333 !important;
color: #e0e0e0 !important;
}
.tb_notice tbody tr:hover, .tb_notice tbody tr:hover td {
background-color: #2a2a2a !important;
}
/* =============== 側邊欄「評分區」 =============== */
#_asideDetail.aside.detail .grade_area, .aside .grade_area { background: transparent !important; }
#_asideDetail.aside.detail .grade_area *, .aside .grade_area * { color: #e0e0e0 !important; }
.aside .grade_area [class*="star"], .aside .grade_area [class*="ico"] { filter: invert(1) brightness(2) !important; }
/* =============== 分享區與各種「加入最愛」按鈕處理 =============== */
.spi_area { background: transparent !important; border: none !important; }
#likeItButton,
#footer_favorites,
.detail_header .btn_favorite {
color: #dddddd !important;
background-color: transparent !important;
border: 1px solid rgba(255, 255, 255, 0.4) !important;
opacity: 1 !important;
transition: all 0.2s ease !important;
box-sizing: border-box !important;
}
#likeItButton:not(.on) [class*="ico"],
#footer_favorites:not(.on) [class*="ico"],
.detail_header .btn_favorite:not(.on) [class*="ico"] { filter: brightness(0) invert(1) opacity(0.8) !important; }
#likeItButton:hover, #footer_favorites:hover, .detail_header .btn_favorite:hover {
color: #ffffff !important; border-color: #ffffff !important; background-color: rgba(255, 255, 255, 0.08) !important;
}
#likeItButton:hover [class*="ico"], #footer_favorites:hover [class*="ico"], .detail_header .btn_favorite:hover [class*="ico"] {
filter: brightness(0) invert(1) opacity(1) !important;
}
#likeItButton.on, #footer_favorites.on, .detail_header .btn_favorite.on {
color: #ffffff !important; border-color: #ffffff !important;
}
#likeItButton.on [class*="ico"], #footer_favorites.on [class*="ico"], #footer_favorites.on .ico_plus3, .detail_header .btn_favorite.on [class*="ico"] {
filter: brightness(0) invert(1) opacity(1) !important;
}
#likeItButton *, #footer_favorites *, .detail_header .btn_favorite * { color: inherit; }
/* =============== 留言區與編輯器 =============== */
.wcc_ReplyFolder__root { background-color: #121212 !important; border-top: 1px solid #333 !important; }
.wcc_ReplyFolder__root * { color: #e0e0e0 !important; }
.wcc_Editor__root, .TextEditor_EditorCore-module__root {
background-color: #1a1a1a !important; border: 1px solid #444 !important; border-radius: 6px !important;
}
.wcc_Editor__root *, .TextEditor_EditorCore-module__root * { color: #ffffff !important; }
.lk_lang._selectedLanguage, .wcc_ReplyFolderToggle__root, .wcc_CommentReaction__root, .wcc_CommentReaction__action {
color: #cccccc !important; opacity: 1 !important; background: transparent !important;
}
.lk_lang._selectedLanguage:hover, .wcc_ReplyFolderToggle__root:hover, .wcc_CommentReaction__action:hover { color: #ffffff !important; }
.wcc_CommentItem__root, .wcc_CommentList__list { border-color: #333 !important; }
/* =============== 底部語言選擇下拉選單 =============== */
html body #footer .foot_menu .language .ly_lang {
background-color: #1e1e1e !important;
border: 1px solid #333 !important;
box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.5) !important;
}
html body #footer .foot_menu .language .ly_lang li { border-color: #333 !important; }
html body #footer .foot_menu .language .ly_lang li a { color: #e0e0e0 !important; background-color: transparent !important; transition: all 0.2s ease !important; }
html body #footer .foot_menu .language .ly_lang li:hover { background-color: #2a2a2a !important; }
html body #footer .foot_menu .language .ly_lang li:hover a { color: #ffffff !important; }
/* =============== 頂部搜尋框 (Search Area) =============== */
/* 將搜尋框外層與背景黑化 */
html body #header .search_area,
html body #header .search_area._searchArea {
background-color: #1a1a1a !important;
border: 1px solid #444 !important;
}
/* 確保輸入框內打字的背景是透明/深色,且文字為白色 */
html body #header .search_area input[type="text"] {
background-color: transparent !important;
color: #ffffff !important;
}
/* 如果有自動完成的下拉選單 (Autocomplete list),一併黑化 */
html body #header .search_area .auto_lst {
background-color: #1e1e1e !important;
border: 1px solid #333 !important;
box-shadow: 0 4px 12px rgba(0,0,0,0.5) !important;
}
html body #header .search_area .auto_lst li a {
color: #e0e0e0 !important;
}
html body #header .search_area .auto_lst li:hover {
background-color: #2a2a2a !important;
}
/* 搜尋按鈕圖示 (通常是黑色的放大鏡雪碧圖),強制反白提亮 */
html body #header .search_area .btn_search,
html body #header .search_area [class*="ico_search"] {
filter: invert(1) brightness(2) !important;
}
/* =============== 搜尋框內層容器 (Input Box 夾心層) =============== */
/* 針對頂部搜尋框與獨立搜尋頁面的「內層輸入框容器」強制黑化 */
html body #searchWrap .big_search.search_area .input_box,
html body #header .search_area .input_box,
html body .search_area._searchArea .input_box._inputArea {
background-color: #1a1a1a !important; /* 配合外層的深灰色 */
background-image: none !important;
border-color: #444 !important;
}
/* 確保超大搜尋框 (big_search) 的輸入文字也是白色的 */
html body #searchWrap .big_search.search_area input[type="text"] {
background-color: transparent !important;
color: #ffffff !important;
}
/* 獨立搜尋頁面的超大放大鏡按鈕也一起反白提亮 */
html body #searchWrap .big_search.search_area .btn_search {
filter: invert(1) brightness(2) !important;
}
/* =============== 超大搜尋框啟動狀態 (Active/On 狀態) =============== */
/* 針對獨立搜尋頁面,當滑鼠點擊正在輸入時的背景強制黑化 */
html body #searchWrap .big_search.search_area.on {
background-color: #1a1a1a !important;
border-color: #555 !important; /* 邊框稍微亮一點點,提示正在輸入 */
box-shadow: 0 0 8px rgba(255, 255, 255, 0.1) !important; /* 加一點微弱的光暈代替原本的白底 */
}
/* =============== 搜尋自動完成下拉選單 (Autocomplete) 懸浮反白 =============== */
/* 1. 確保自動完成下拉選單整體的底色與邊框是深色 */
html body .search_area .ly_autocomplete._searchLayer {
background-color: #1e1e1e !important;
border: 1px solid #333 !important;
box-shadow: 0 4px 12px rgba(0,0,0,0.5) !important;
}
/* 2. 清除選單內選項預設的白底,並確保文字為淺色 */
html body .search_area .ly_autocomplete._searchLayer li {
background-color: transparent !important;
}
html body .search_area .ly_autocomplete._searchLayer li a.link {
color: #e0e0e0 !important;
}
/* 3. 針對你提供的精準路徑:強制覆蓋懸浮 (Hover) 狀態的背景為深灰色 */
html body .search_area .ly_autocomplete._searchLayer ul.list_autocomplete li:hover,
html body .search_area .ly_autocomplete._searchLayer ul.list_autocomplete li:hover > a,
html body .search_area .ly_autocomplete._searchLayer ul.list_autocomplete li a.link:hover {
background-color: #2a2a2a !important;
background-image: none !important;
}
/* 4. 確保懸浮時裡面的關鍵字 (包含被高亮標記的字) 不會反黑,且背景透明 */
html body .search_area .ly_autocomplete._searchLayer ul.list_autocomplete li:hover *,
html body .search_area .ly_autocomplete._searchLayer ul.list_autocomplete li a.link:hover * {
color: #ffffff !important;
background-color: transparent !important;
}
/* =============== 搜尋歷史紀錄與創作者清單懸浮反白 =============== */
/* 1. 確保歷史紀錄面板整體的底色與邊框是深色 */
html body #header .search_area ul#gnb_search_box.ly_autocomplete._searchLayer._searchHistory,
html body #searchWrap .search_area div#search_box.ly_autocomplete._searchLayer._searchHistory {
background-color: #1e1e1e !important;
border: 1px solid #333 !important;
box-shadow: 0 4px 12px rgba(0,0,0,0.5) !important;
}
/* 2. 針對創作者 (list_creator) 與歷史紀錄 (lst_history) 的選項強制懸浮黑化 */
html body .search_area .ly_autocomplete._searchLayer ul.list_creator li:hover,
html body .search_area .ly_autocomplete._searchLayer ul.list_creator li a:hover,
html body .search_area .ly_autocomplete._searchLayer ul.lst_history li:hover,
html body .search_area .ly_autocomplete._searchLayer ul.lst_history li a:hover {
background-color: #2a2a2a !important;
background-image: none !important;
}
/* 3. 確保這些清單內的文字 (包含歷史紀錄旁邊的刪除叉叉) 懸浮時依然是清晰的白色 */
html body .search_area .ly_autocomplete._searchLayer ul.list_creator li:hover *,
html body .search_area .ly_autocomplete._searchLayer ul.list_creator li a:hover *,
html body .search_area .ly_autocomplete._searchLayer ul.lst_history li:hover *,
html body .search_area .ly_autocomplete._searchLayer ul.lst_history li a:hover * {
color: #ffffff !important;
background-color: transparent !important;
}
`;
const style = document.createElement('style');
style.type = 'text/css';
style.appendChild(document.createTextNode(css));
document.head.appendChild(style);
/* =============== 解除右鍵與複製封印補丁 =============== */
// 1. 強制解除 CSS 的文字與圖片選取限制
const unblockCss = `
* {
-webkit-user-select: auto !important;
-moz-user-select: auto !important;
-ms-user-select: auto !important;
user-select: auto !important;
-webkit-touch-callout: default !important;
}
`;
const unblockStyle = document.createElement('style');
unblockStyle.type = 'text/css';
unblockStyle.appendChild(document.createTextNode(unblockCss));
document.head.appendChild(unblockStyle);
// 2. 在「捕獲階段 (Capture Phase)」攔截並消除官方的阻擋事件
const blockedEvents = ['contextmenu', 'selectstart', 'dragstart', 'copy', 'cut'];
blockedEvents.forEach(eventName => {
document.addEventListener(eventName, function(e) {
e.stopPropagation(); // 阻止事件傳遞給 Webtoon 的阻擋程式
}, true);
});
// 3. 清除直接綁定在 HTML 標籤上的舊式阻擋屬性
document.oncontextmenu = null;
document.body.oncontextmenu = null;
document.ondragstart = null;
document.body.ondragstart = null;
})();