// ==UserScript==
// @name IThome Pro
// @version 4.6
// @description 优化ithome网页端浏览效果
// @match *://*.ithome.com/*
// @run-at document-start
// @namespace https://greasyfork.org/users/1354671
// ==/UserScript==
(function () {
"use strict";
// 启用评论框:true:启用 false:关闭
const showCommentBox = false;
// 定义样式-hideStyle:不透明度 0
const hideStyle = document.createElement("style");
hideStyle.innerHTML = `body { opacity: 0; }`;
document.head.appendChild(hideStyle);
// 跳转到 blog 页面,加载完成前隐藏原始页面
if (
window.location.href === "https://www.ithome.com" ||
window.location.href === "https://www.ithome.com/"
) {
document.head.appendChild(hideStyle);
window.location.replace("https://www.ithome.com/blog/");
return;
}
// blog 页面加载完成前隐藏原始页面
if (window.location.href.startsWith("https://www.ithome.com/blog/")) {
document.head.appendChild(hideStyle);
}
// 函数:保持页面激活,这样可以去除弹出的登录框
function keepPageActive() {
const event = new Event("mousemove", { bubbles: true, cancelable: true });
// 设置定时器,每0.1秒触发一次事件
const intervalId = setInterval(() => {
document.dispatchEvent(event);
}, 100); // 0.1秒(100毫秒)
// 5秒后停止定时器
setTimeout(() => {
clearInterval(intervalId);
console.log("Stopped keeping page active.");
}, 5000); // 5秒(5000毫秒)
}
// [调用] 保持页面激活
keepPageActive();
// 函数:净化页面 利用 AdGuard 规则
function hideElements() {
const selectors = [
...(!showCommentBox ? ["#postcomment3"] : []),
"#nav",
"#top",
"#tt",
"#list > div.fr.fx:last-child",
"#side_func",
"#dt > div.fl.content:first-child > div.cv:first-child",
"#dt > div.fr.fx:last-child",
"#dt > div.fl.content:first-child > div.newsgrade:nth-child(6)",
"#dt > div.fl.content:first-child > div.shareto:nth-child(7)",
"#dt > div.fl.content:first-child > iframe.dajia:nth-child(10)",
"#dt > div.fl.content:first-child > div.newsgrade:nth-child(8)",
"#dt > div.fl.content:first-child > div.newserror:nth-child(7)",
"#dt > div.fl.content:first-child > div.newsreward:nth-child(6)",
"#dt > div.fl.content:first-child > div.shareto:nth-child(9)",
"#rm-login-modal > div.modal.has-title.loaded",
"#dt > div.fl.content:first-child > div.related_post:nth-child(8)",
"#dt > div.fl.content:first-child > div.newserror:nth-child(5)",
"#paragraph > p.ad-tips:last-child",
"#fls",
"#fi",
"#lns",
"#paragraph > div.tougao-user:nth-child(2)",
"#login-guide-box",
".dajia",
"#paragraph > div.tagging1:last-child",
"#paragraph > p.ad-tips",
'[id^="ad-id-"]',
"div.-hongbao-container.bb:nth-child(6)",
];
selectors.forEach((selector) => {
document.querySelectorAll(selector).forEach((element) => {
element.style.display = "none";
});
});
}
// 函数:图片处理 - 圆角、边框
function processImage(image) {
// 这部分匹配到的图片不处理
if (image.closest("#post_comm")) return;
if (image.classList.contains("titleLogo")) return;
if (image.classList.contains("lazy") && image.classList.contains("emoji"))
return;
if (
image.classList.contains("ruanmei-emoji") &&
image.classList.contains("emoji")
)
return;
if (image.id === "image-viewer" || image.classList.contains("zoomed"))
return;
if (image.classList.contains("comment-image")) return;
// 首页图片
if (image.closest("a.img")) {
const anchor = image.closest("a.img");
if (!anchor.classList.contains("processed")) {
anchor.style.border = "3px solid #CCC";
anchor.style.borderRadius = "12px";
anchor.style.display = "inline-block";
anchor.style.overflow = "hidden";
anchor.classList.add("processed");
}
// 视频预览图
} else if (image.closest(".ithome_super_player")) {
const videoPlayer = image.closest(".ithome_super_player");
if (!videoPlayer.parentNode.classList.contains("processed")) {
const wrapper = document.createElement("div");
wrapper.style.border = "3px solid #CCC";
wrapper.style.borderRadius = "12px";
wrapper.style.overflow = "hidden";
wrapper.style.maxWidth = "100%";
wrapper.style.display = "block";
wrapper.style.margin = "0 auto";
wrapper.classList.add("processed");
videoPlayer.parentNode.insertBefore(wrapper, videoPlayer);
wrapper.appendChild(videoPlayer);
// 视频预览图根据父元素高度调整
const img = videoPlayer.querySelector("img");
if (img) {
const imgWidth = img.getAttribute("w");
const imgHeight = img.getAttribute("h");
const parentHeight = wrapper.offsetHeight;
if (imgWidth > wrapper.offsetWidth) {
const aspectRatio = imgWidth / imgHeight;
img.style.height = `${parentHeight}px`;
img.style.width = `${parentHeight * aspectRatio}px`;
img.style.objectFit = "cover";
} else {
img.style.width = `${imgWidth}px`;
img.style.height = `${imgHeight}px`;
}
}
}
} else {
// 超长图片宽度 450px
if (image.height > 1000) {
image.style.borderRadius = "12px";
image.style.border = "3px solid #CCC";
image.style.width = "400px";
image.style.maxWidth = "400px";
image.style.height = "auto";
image.style.objectFit = "cover";
image.style.overflow = "hidden";
// 常规图片宽度 450px
} else {
image.style.borderRadius = "12px";
image.style.border = "3px solid #CCC";
image.style.maxWidth = "450px";
}
}
}
// [调用] 图片处理
function setRoundedImages() {
document.querySelectorAll("img").forEach((image) => processImage(image));
}
// 函数:头像处理
function styleHeaderImage() {
const headerImages = document.querySelectorAll(".list .entry .headerimage");
headerImages.forEach((image) => {
image.style.borderRadius = "12px";
image.style.border = "3px solid #CCC";
});
}
// 函数:多图连续排列时插入间隔
function wrapImagesInP() {
if (window.location.href.startsWith("https://www.ithome.com/blog/")) return;
document.querySelectorAll("img").forEach((image) => {
// 这部分匹配到的图片不处理
if (image.closest("#post_comm")) return;
if (image.closest(".ithome_super_player")) return;
if (
image.classList.contains("ruanmei-emoji") &&
image.classList.contains("emoji")
)
return;
if (image.classList.contains("ithome_super_player")) return;
if (
image.parentNode.tagName.toLowerCase() === "p" &&
image.parentNode.children.length === 1
)
return;
if (image.width < 25 || image.height < 20) return;
const p = document.createElement("p");
p.style.textAlign = "center";
p.style.margin = "0";
p.setAttribute("data-vmark", "f5e8");
image.parentNode.insertBefore(p, image);
p.appendChild(image);
});
}
// 函数:视频处理 - 圆角、边框
function processIframes() {
const iframes = document.querySelectorAll(
'.content .post_content iframe.ithome_video, .content .post_content iframe[src*="player.bilibili.com"]',
);
iframes.forEach((iframe) => {
if (!iframe.classList.contains("processed")) {
iframe.style.borderRadius = "12px";
iframe.style.border = "3px solid #CCC";
iframe.style.display = "block";
iframe.style.margin = "0 auto";
iframe.style.overflow = "hidden";
iframe.classList.add("processed");
}
});
}
// 函数:页面样式圆角
function setRounded() {
const roundeds = document.querySelectorAll(
".comm_list ul.list li.entry ul.reply, .content .post_content blockquote, " +
".add_comm input#btnComment, .card, span.card",
);
roundeds.forEach((rounded) => (rounded.style.borderRadius = "12px"));
document.querySelectorAll(".add_comm").forEach((addCommElement) => {
addCommElement.style.borderRadius = "0px 0px 12px 12px";
});
document.querySelectorAll(".card, span.card").forEach((card) => {
card.style.borderRadius = "12px";
card.style.transform = "scale(0.8)";
});
}
// 函数:移除首页信息流广告
function removeAds() {
document
.querySelectorAll("div.bb.clearfix > div.fl > ul.bl > li")
.forEach((element) => {
if (element.querySelector("div.c > div.m:empty")) element.remove();
});
}
// 函数:自动点击「加载更多」按钮
function autoClickLoadMore() {
const loadMoreButton = document.querySelector("a.more");
if (loadMoreButton) {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
loadMoreButton.click();
}
});
});
observer.observe(loadMoreButton);
// 监听DOM变化
const mutationObserver = new MutationObserver(() => {
const newLoadMoreButton = document.querySelector("a.more");
if (newLoadMoreButton && !observer.observe(newLoadMoreButton)) {
observer.observe(newLoadMoreButton);
}
});
mutationObserver.observe(document.body, {
childList: true,
subtree: true,
});
}
}
// 函数:评论加载
function forceLoadComments() {
const footer = document.querySelector("#post_comm");
const spacer = document.createElement("div");
spacer.style.height = "100vh";
spacer.style.visibility = "hidden";
document.body.appendChild(spacer);
window.scrollTo(0, document.body.scrollHeight);
spacer.remove();
window.scrollTo(0, 0);
}
// 函数:首页卡片样式
function initializePage() {
function makeListItemsClickable() {
const listItems = document.querySelectorAll(".bl > li");
listItems.forEach((li) => {
const wrapper = document.createElement("div");
wrapper.classList.add("hover-wrapper");
wrapper.style.position = "relative";
wrapper.style.padding = "12px 16px";
wrapper.style.borderRadius = "12px";
wrapper.style.overflow = "hidden";
wrapper.style.margin = "16px 0";
li.parentNode.insertBefore(wrapper, li);
wrapper.appendChild(li);
const titleLink = li.querySelector("h2 a");
if (titleLink) {
const titleText = document.createTextNode(titleLink.textContent);
titleLink.replaceWith(titleText);
wrapper.style.cursor = "pointer";
wrapper.addEventListener("click", () => {
window.open(titleLink.href, titleLink.target || "_self");
});
wrapper.addEventListener("mouseover", () => {
wrapper.style.boxShadow = "0px 6px 15px rgba(0, 0, 0, 0.2)";
wrapper.style.backgroundColor = getBackgroundColor();
});
wrapper.addEventListener("mouseout", () => {
wrapper.style.boxShadow = "none";
wrapper.style.backgroundColor = "transparent";
});
}
});
}
function setHome() {
const divs = document.querySelectorAll("div.fl");
divs.forEach((div) => {
div.style.width = "870px";
});
}
function removeMarginTop() {
const hoverWrappers = document.querySelectorAll(".hover-wrapper");
hoverWrappers.forEach((hoverWrapper) => {
const listItems = hoverWrapper.querySelectorAll("li");
listItems.forEach((item) => {
item.style.marginTop = "0";
});
});
}
function setDivWidthTo590() {
const divs = document.querySelectorAll("div.c");
divs.forEach((div) => {
div.style.width = "640px";
});
}
function getBackgroundColor() {
if (
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
) {
return "#333333";
} else {
return "#f9f9f9";
}
}
makeListItemsClickable();
setHome();
removeMarginTop();
setDivWidthTo590();
}
// 函数:评论区图片放大
function replaceImageWrapper() {
const imageWrappers = document.querySelectorAll(
".post-img-list a.img-wrapper",
);
imageWrappers.forEach((wrapper) => {
const img = wrapper.querySelector("img");
if (img) {
const parent = wrapper.parentElement;
wrapper.classList.remove("img-wrapper");
wrapper.classList.add("img-click");
wrapper.removeAttribute("href");
img.style.width = "30%";
img.style.height = "auto";
img.style.borderRadius = "12px";
img.style.border = "3px solid #CCC";
let isZoomed = false;
img.addEventListener("click", () => {
if (isZoomed) {
img.style.width = "30%";
} else {
img.style.width = "100%";
}
img.style.height = "auto";
isZoomed = !isZoomed;
});
}
});
}
// 函数:观察DOM变化,处理新刷出的内容
function observeDOM() {
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === "childList" && mutation.addedNodes.length > 0) {
wrapImagesInP();
setRounded();
removeAds();
hideElements();
setRoundedImages();
styleHeaderImage();
initializePage();
replaceImageWrapper();
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
// 监听事件
window.addEventListener("scroll", autoClickLoadMore);
window.addEventListener("load", function () {
hideElements();
forceLoadComments();
removeAds();
wrapImagesInP();
setRounded();
processIframes();
setRoundedImages();
styleHeaderImage();
initializePage();
replaceImageWrapper();
observeDOM();
document.body.style.opacity = "1";
// 处理图片懒加载
document.querySelectorAll("img").forEach((img) => {
if (img.hasAttribute("loading")) {
img.removeAttribute("loading");
}
if (img.classList.contains("lazy")) {
img.classList.remove("lazy");
}
if (img.dataset.src) {
img.src = img.dataset.src;
}
if (img.dataset.original) {
img.src = img.dataset.original;
}
img.loading = "eager";
});
});
})();