Greasy Fork is available in English.

IThome Pro fix

优化ithome网页端浏览效果-修复版

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         IThome Pro fix
// @version      4.8.0
// @description  优化ithome网页端浏览效果-修复版
// @match        *://*.ithome.com/*
// @run-at       document-start
// @namespace    https://github.com/wang93wei/IThome-Pro-fix
// @supportURL   https://github.com/wang93wei/IThome-Pro-fix/issues
// @license MIT
// ==/UserScript==

(function () {
  "use strict";

  /**
   * 全局配置对象
   * 可以根据需要修改这些选项来启用或禁用特定功能
   */
  const CONFIG = {
    // 是否显示评论框(true:显示,false:隐藏)
    showCommentBox: false,
    
    // 是否自动加载更多内容(true:启用,false:禁用)
    autoLoadMore: true,
    
    // 是否自动加载图片(true:启用,false:禁用)
    autoLoadImages: true,
    
    // 是否启用图片圆角效果(true:启用,false:禁用)
    roundedImages: true,
    
    // 是否隐藏广告(true:隐藏,false:显示)
    hideAds: true,
    
    // 鼠标移动事件触发间隔(毫秒)
    MOUSEMOVE_INTERVAL: 100,
    
    // 保持页面活跃的持续时间(毫秒)
    MOUSEMOVE_DURATION: 5000,
    
    // 初始延迟时间(毫秒)
    INITIAL_DELAY: 1000,
    
    // 滚动延迟时间(毫秒)
    SCROLL_DELAY: 100,
    
    // 处理延迟时间(毫秒)
    PROCESSING_DELAY: 200,
    
    // MutationObserver防抖时间(毫秒)
    MUTATION_DEBOUNCE: 300,
    
    // 自动点击加载更多按钮的防抖时间(毫秒)
    AUTO_CLICK_DEBOUNCE: 500
  };

  // 使用Set代替WeakSet,避免元素被垃圾回收导致重复处理
  const processedImages = new Set();
  const processedElements = new Set();
  const originalStyles = new Map();

  /**
   * 创建隐藏样式的style元素
   * 用于在页面加载完成前隐藏原始内容,避免闪烁
   */
  const hideStyle = document.createElement("style");
  hideStyle.id = "ithome-pro-fix-style";
  hideStyle.innerHTML = `
    body { opacity: 0; }
    #rm-login-modal, #rm-login-modal *, #login-guide-box { display: none !important; }
  `;
  
  /**
   * 添加隐藏样式到页面
   * 检查是否已存在,避免重复添加
   */
  const addHideStyle = () => {
    if (!document.getElementById("ithome-pro-fix-style")) {
      document.head.appendChild(hideStyle);
    }
  };

  // 立即添加隐藏样式
  addHideStyle();

  /**
   * 首页重定向逻辑
   * 自动跳转到blog页面,提升浏览体验
   */
  if (
    window.location.href === "https://www.ithome.com" ||
    window.location.href === "https://www.ithome.com/"
  ) {
    window.location.replace("https://www.ithome.com/blog/");
    return;
  }

  // blog页面加载完成前隐藏原始内容
  if (window.location.href.startsWith("https://www.ithome.com/blog/")) {
    addHideStyle();
  }

  /**
   * 保持页面活跃
   * 通过定期触发mousemove事件来防止登录弹窗出现
   */
  function keepPageActive() {
    const event = new Event("mousemove", { bubbles: true, cancelable: true });

    // 设置定时器,定期触发mousemove事件
    const intervalId = setInterval(() => {
      document.dispatchEvent(event);
    }, CONFIG.MOUSEMOVE_INTERVAL);

    // 指定时间后停止触发
    setTimeout(() => {
      clearInterval(intervalId);
      console.log("Stopped keeping page active.");
    }, CONFIG.MOUSEMOVE_DURATION);
  }

  // 启动页面活跃保持机制
  keepPageActive();

  /**
   * 强制加载图片
   * 移除懒加载属性,立即加载图片
   * @param {HTMLImageElement} img - 要处理的图片元素
   */
  const forceLoadImage = (img) => {
    // 移除loading属性
    if (img.hasAttribute("loading")) {
      img.removeAttribute("loading");
    }
    // 移除lazy类
    if (img.classList.contains("lazy")) {
      img.classList.remove("lazy");
    }
    // 从data-src加载图片
    if (img.dataset.src) {
      img.src = img.dataset.src;
    }
    // 从data-original加载图片
    if (img.dataset.original) {
      img.src = img.dataset.original;
    }
    // 设置为立即加载
    img.loading = "eager";
  };

  /**
   * 隐藏页面上的广告和不需要的元素
   * 通过CSS display: none隐藏指定的选择器元素
   */
  const hideElements = () => {
    try {
      // 定义要隐藏的元素选择器
      const selectors = [
        // 导航栏和顶部元素
        "#nav, #top, #tt, #side_func, #fls, #fi, #lns",
        
        // 首页侧边栏
        "#list > div.fr.fx:last-child",
        
        // 文章页面的各种元素
        "#dt > div.fl.content:first-child > div.cv:first-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)",
        "#dt > div.fl.content:first-child > div.related_post:nth-child(8)",
        "#dt > div.fl.content:first-child > div.newserror:nth-child(5)",
        
        // 登录弹窗
        "#rm-login-modal > div.modal.has-title.loaded",
        "#login-guide-box",
        
        // 广告元素
        "#paragraph > p.ad-tips:last-child",
        "#paragraph > p.ad-tips",
        '[id^="ad-id-"]',
        "div.-hongbao-container.bb:nth-child(6)",
        
        // 其他不需要的元素
        "#paragraph > div.tougao-user:nth-child(2)",
        ".dajia",
        "#paragraph > div.tagging1:last-child",
        "#dt > div.fr.fx:last-child"
      ];

      // 根据配置决定是否隐藏评论框
      if (!CONFIG.showCommentBox) {
        selectors.push("#postcomment3");
      }

      // 遍历所有选择器并隐藏匹配的元素
      selectors.forEach((selector) => {
        document.querySelectorAll(selector).forEach((element) => {
          element.style.display = "none";
        });
      });
    } catch (error) {
      console.error("Error in hideElements:", error);
    }
  };

  /**
   * 图片样式配置
   * 定义不同类型图片的样式
   */
  const imageStyles = new Map([
    // 首页图片样式
    ['home', {
      border: "3px solid #CCC",
      borderRadius: "12px",
      display: "inline-block",
      overflow: "hidden"
    }],
    // 视频播放器样式
    ['video', {
      border: "3px solid #CCC",
      borderRadius: "12px",
      overflow: "hidden",
      maxWidth: "100%",
      display: "block",
      margin: "0 auto"
    }],
    // 长图样式
    ['longImage', {
      borderRadius: "12px",
      border: "3px solid #CCC",
      width: "400px",
      maxWidth: "400px",
      height: "auto",
      objectFit: "cover",
      overflow: "hidden"
    }],
    // 普通图片样式
    ['regular', {
      borderRadius: "12px",
      border: "3px solid #CCC",
      maxWidth: "450px"
    }]
  ]);

  /**
   * 处理单个图片元素
   * 根据图片类型应用相应的样式
   * @param {HTMLImageElement} image - 要处理的图片元素
   */
  const processImage = (image) => {
    try {
      // 生成唯一标识符,避免重复处理
      const imageId = image.getAttribute('data-id') || image.src || Math.random().toString();
      if (processedImages.has(imageId)) return;
      
      // 跳过评论区的图片
      if (image.closest("#post_comm")) return;
      // 跳过标题logo
      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;

      // 处理首页图片(在a.img标签内)
      if (image.closest("a.img")) {
        const anchor = image.closest("a.img");
        if (!anchor.classList.contains("processed")) {
          Object.assign(anchor.style, imageStyles.get('home'));
          anchor.classList.add("processed");
          processedImages.add(imageId);
        }
      } 
      // 处理视频播放器中的图片
      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");
          Object.assign(wrapper.style, imageStyles.get('video'));
          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`;
            }
          }
          processedImages.add(imageId);
        }
      } 
      // 处理普通图片
      else {
        // 根据高度判断是否为长图
        if (image.height > 1000) {
          Object.assign(image.style, imageStyles.get('longImage'));
        } else {
          Object.assign(image.style, imageStyles.get('regular'));
        }
        processedImages.add(imageId);
      }
    } catch (error) {
      console.error("Error in processImage:", error);
    }
  };

  /**
   * 设置所有图片的圆角样式
   * 遍历页面上的所有img元素并应用样式
   */
  function setRoundedImages() {
    try {
      document.querySelectorAll("img").forEach((image) => processImage(image));
    } catch (error) {
      console.error("Error in setRoundedImages:", error);
    }
  }

  /**
   * 样式配置
   * 定义各种元素的样式
   */
  const styleConfig = new Map([
    // 头部图片样式
    ['headerImage', {
      borderRadius: "12px",
      border: "3px solid #CCC"
    }],
    // 圆角样式
    ['rounded', {
      borderRadius: "12px"
    }],
    // 评论框样式
    ['addComm', {
      borderRadius: "0px 0px 12px 12px"
    }],
    // 卡片样式
    ['card', {
      borderRadius: "12px",
      transform: "scale(0.8)"
    }]
  ]);

  /**
   * 设置头部图片的样式
   * 为列表页面的头部图片添加圆角和边框
   */
  const styleHeaderImage = () => {
    try {
      const headerImages = document.querySelectorAll(".list .entry .headerimage");

      headerImages.forEach((image) => {
        const imageId = image.getAttribute('data-id') || image.src || Math.random().toString();
        if (!processedImages.has(imageId)) {
          Object.assign(image.style, styleConfig.get('headerImage'));
          processedImages.add(imageId);
        }
      });
    } catch (error) {
      console.error("Error in styleHeaderImage:", error);
    }
  };

  /**
   * 将图片包装在p标签中
   * 用于多图连续排列时插入间隔
   */
  function wrapImagesInP() {
    try {
      // blog页面不需要处理
      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;
        // 跳过已经在p标签中且是唯一子元素的图片
        if (
          image.parentNode.tagName.toLowerCase() === "p" &&
          image.parentNode.children.length === 1
        )
          return;
        // 跳过过小的图片(可能是图标)
        if (image.width < 25 || image.height < 20) return;

        // 创建p标签并包装图片
        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);
      });
    } catch (error) {
      console.error("Error in wrapImagesInP:", error);
    }
  }

  /**
   * 处理iframe元素
   * 为视频iframe添加圆角和边框
   */
  const processIframes = () => {
    try {
      // 选择所有视频iframe(包括IThome和Bilibili)
      const iframes = document.querySelectorAll(
        '.content .post_content iframe.ithome_video, .content .post_content iframe[src*="player.bilibili.com"]',
      );

      iframes.forEach((iframe) => {
        const iframeId = iframe.getAttribute('data-id') || iframe.src || Math.random().toString();
        if (!processedElements.has(iframeId) && !iframe.classList.contains("processed")) {
          // 应用样式
          Object.assign(iframe.style, {
            borderRadius: "12px",
            border: "3px solid #CCC",
            display: "block",
            margin: "0 auto",
            overflow: "hidden"
          });
          iframe.classList.add("processed");
          processedElements.add(iframeId);
        }
      });
    } catch (error) {
      console.error("Error in processIframes:", error);
    }
  };

  /**
   * 设置元素的圆角样式
   * 为评论框、引用块、卡片等元素添加圆角
   */
  const setRounded = () => {
    try {
      // 选择所有需要圆角的元素
      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) => Object.assign(rounded.style, styleConfig.get('rounded')));

      // 设置评论框的圆角
      document.querySelectorAll(".add_comm").forEach((addCommElement) => {
        Object.assign(addCommElement.style, styleConfig.get('addComm'));
      });

      // 设置卡片的样式
      document.querySelectorAll(".card, span.card").forEach((card) => {
        Object.assign(card.style, styleConfig.get('card'));
      });
    } catch (error) {
      console.error("Error in setRounded:", error);
    }
  };

  /**
   * 移除首页信息流广告
   * 移除内容为空的广告元素
   */
  function removeAds() {
    try {
      document
        .querySelectorAll("div.bb.clearfix > div.fl > ul.bl > li")
        .forEach((element) => {
          // 如果内容为空,则移除该元素
          if (element.querySelector("div.c > div.m:empty")) element.remove();
        });
    } catch (error) {
      console.error("Error in removeAds:", error);
    }
  }

  /**
   * 防抖函数
   * 延迟执行函数,避免频繁调用
   * @param {Function} fn - 要防抖的函数
   * @param {number} delay - 延迟时间(毫秒)
   * @returns {Function} 防抖后的函数
   */
  const debounce = (fn, delay = 500) => {
    let timer = null;
    return (...args) => {
      clearTimeout(timer);
      timer = setTimeout(() => fn(...args), delay);
    };
  };

  /**
   * 自动点击"加载更多"按钮
   * 当按钮进入视口时自动点击
   */
  const autoClickLoadMore = async () => {
    try {
      // 根据配置决定是否启用
      if (!CONFIG.autoLoadMore) return;

      // 查找"加载更多"按钮
      const loadMoreButton = document.querySelector("a.more");

      if (!loadMoreButton) return;

      // 检查按钮是否在视口中
      const rect = loadMoreButton.getBoundingClientRect();
      const isVisible = rect.top < window.innerHeight && rect.bottom > 0;

      // 如果可见,则点击按钮
      if (isVisible) {
        loadMoreButton.click();
      }
    } catch (error) {
      console.error("Error in autoClickLoadMore:", error);
    }
  };

  // 创建防抖版本的自加载函数
  const debouncedAutoClickLoadMore = debounce(autoClickLoadMore, CONFIG.AUTO_CLICK_DEBOUNCE);

  // 监听滚动事件,自动加载更多内容
  window.addEventListener("scroll", debouncedAutoClickLoadMore);

  // 初始化时执行一次自动加载
  (async () => {
    try {
      await new Promise(resolve => setTimeout(resolve, CONFIG.INITIAL_DELAY));
      await autoClickLoadMore();
    } catch (error) {
      console.error("Error in initial auto load:", error);
    }
  })();

  /**
   * 强制加载评论区
   * 通过滚动到底部触发评论区的加载
   */
  const forceLoadComments = async () => {
    try {
      // 创建一个不可见的spacer元素
      const spacer = document.createElement("div");
      Object.assign(spacer.style, {
        height: "100vh",
        visibility: "hidden"
      });
      document.body.appendChild(spacer);

      // 滚动到底部
      window.scrollTo(0, document.body.scrollHeight);

      // 等待一段时间让评论区加载
      await new Promise(resolve => setTimeout(resolve, CONFIG.SCROLL_DELAY));

      // 移除spacer并滚动回顶部
      spacer.remove();
      window.scrollTo(0, 0);

      // 隐藏不需要的元素
      hideElements();
    } catch (error) {
      console.error("Error in forceLoadComments:", error);
    }
  };

  /**
   * 包装器样式配置
   * 定义列表项包装器的样式
   */
  const wrapperStyles = new Map([
    // 包装器基础样式
    ['hoverWrapper', {
      position: "relative",
      padding: "12px 16px",
      borderRadius: "12px",
      overflow: "hidden",
      margin: "16px 0"
    }],
    // 鼠标悬停样式
    ['hover', {
      boxShadow: "0px 6px 15px rgba(0, 0, 0, 0.2)"
    }],
    // 正常状态样式
    ['normal', {
      boxShadow: "none",
      backgroundColor: "transparent"
    }]
  ]);

  /**
   * 获取背景颜色
   * 根据系统的深色模式设置返回相应的背景色
   * @returns {string} 背景颜色值
   */
  const getBackgroundColor = () => {
    return window.matchMedia && 
           window.matchMedia("(prefers-color-scheme: dark)").matches
      ? "#333333"
      : "#f9f9f9";
  };

  /**
   * 使列表项可点击
   * 将列表项包装在div中,点击整个区域可以跳转到文章
   */
  const makeListItemsClickable = () => {
    try {
      const listItems = document.querySelectorAll(".bl > li");

      listItems.forEach((li) => {
        // 跳过已经包装过的列表项
        if (li.closest('.hover-wrapper')) return;

        // 创建包装器
        const wrapper = document.createElement("div");
        wrapper.classList.add("hover-wrapper");
        Object.assign(wrapper.style, wrapperStyles.get('hoverWrapper'));

        // 将列表项插入到包装器中
        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", () => {
            Object.assign(wrapper.style, wrapperStyles.get('hover'));
            wrapper.style.backgroundColor = getBackgroundColor();
          });

          // 鼠标移出效果
          wrapper.addEventListener("mouseout", () => {
            Object.assign(wrapper.style, wrapperStyles.get('normal'));
          });
        }
      });
    } catch (error) {
      console.error("Error in makeListItemsClickable:", error);
    }
  };

  /**
   * 设置首页布局
   * 调整首页元素的宽度
   */
  const setHome = () => {
    try {
      const divs = document.querySelectorAll("div.fl");
      divs.forEach((div) => {
        div.style.width = "870px";
      });
    } catch (error) {
      console.error("Error in setHome:", error);
    }
  };

  /**
   * 移除列表项的上边距
   * 使列表项紧密排列
   */
  const removeMarginTop = () => {
    try {
      const hoverWrappers = document.querySelectorAll(".hover-wrapper");
      hoverWrappers.forEach((hoverWrapper) => {
        const listItems = hoverWrapper.querySelectorAll("li");
        listItems.forEach((item) => {
          item.style.marginTop = "0";
        });
      });
    } catch (error) {
      console.error("Error in removeMarginTop:", error);
    }
  };

  /**
   * 设置内容区域宽度
   * 调整文章内容区域的宽度
   */
  const setDivWidthTo590 = () => {
    try {
      const divs = document.querySelectorAll("div.c");
      divs.forEach((div) => {
        div.style.width = "640px";
      });
    } catch (error) {
      console.error("Error in setDivWidthTo590:", error);
    }
  };

  /**
   * 初始化页面
   * 执行所有页面初始化操作
   */
  const initializePage = () => {
    makeListItemsClickable();
    setHome();
    removeMarginTop();
    setDivWidthTo590();
  };

  /**
   * 替换图片包装器
   * 将图片包装器改为可点击缩放的形式
   */
  const replaceImageWrapper = () => {
    try {
      const imageWrappers = document.querySelectorAll(
        ".post-img-list a.img-wrapper",
      );

      imageWrappers.forEach((wrapper) => {
        const img = wrapper.querySelector("img");
        if (img) {
          const imageId = img.getAttribute('data-id') || img.src || Math.random().toString();
          if (!processedImages.has(imageId)) {
            const parent = wrapper.parentElement;

            // 修改类名
            wrapper.classList.remove("img-wrapper");
            wrapper.classList.add("img-click");

            // 移除href属性,阻止默认跳转
            wrapper.removeAttribute("href");

            // 保存原始尺寸
            const originalWidth = img.style.width;
            const originalHeight = img.style.height;
            originalStyles.set(imageId, { width: originalWidth, height: originalHeight });

            // 设置初始样式(缩小显示)
            Object.assign(img.style, {
              width: "30%",
              height: "auto",
              borderRadius: "12px",
              border: "3px solid #CCC"
            });

            // 添加点击缩放功能
            let isZoomed = false;

            img.addEventListener("click", () => {
              try {
                if (isZoomed) {
                  // 恢复原始尺寸
                  const original = originalStyles.get(imageId);
                  Object.assign(img.style, {
                    width: original?.width || "30%",
                    height: original?.height || "auto"
                  });
                } else {
                  // 放大到100%
                  img.style.width = "100%";
                }
                img.style.height = "auto";
                isZoomed = !isZoomed;
              } catch (error) {
                console.error("Error in image click handler:", error);
              }
            });

            processedImages.add(imageId);
          }
        }
      });
    } catch (error) {
      console.error("Error in replaceImageWrapper:", error);
    }
  };

  /**
   * 处理新添加的内容
   * 当DOM发生变化时,对新内容应用所有样式
   */
  const processNewContent = () => {
    try {
      wrapImagesInP();
      setRounded();
      removeAds();
      hideElements();
      setRoundedImages();
      styleHeaderImage();
      initializePage();
      replaceImageWrapper();
    } catch (error) {
      console.error("Error in processNewContent:", error);
    }
  };

  /**
   * 监听DOM变化
   * 使用MutationObserver监听DOM变化,自动处理新添加的内容
   */
  const observeDOM = () => {
    let isProcessing = false;
    let debounceTimer = null;

    const observer = new MutationObserver((mutationsList) => {
      // 如果正在处理,则跳过
      if (isProcessing) return;

      // 清除之前的定时器
      clearTimeout(debounceTimer);
      debounceTimer = setTimeout(async () => {
        isProcessing = true;

        try {
          // 遍历所有变化
          for (const mutation of mutationsList) {
            // 只处理子节点变化
            if (mutation.type === "childList" && mutation.addedNodes.length > 0) {
              // 检查是否有新内容
              const hasNewContent = Array.from(mutation.addedNodes).some(node => {
                if (node.nodeType === Node.ELEMENT_NODE) {
                  return !node.classList.contains('hover-wrapper') &&
                         !node.classList.contains('processed') &&
                         (node.querySelector && (
                           node.querySelector('.bl > li') ||
                           node.querySelector('img') ||
                           node.querySelector('.content')
                         ));
                }
                return false;
              });

              // 如果有新内容,则处理
              if (hasNewContent) {
                processNewContent();

                // 强制加载新内容中的图片
                mutation.addedNodes.forEach(node => {
                  if (node.nodeType === Node.ELEMENT_NODE) {
                    const images = node.querySelectorAll ? node.querySelectorAll('img') : [];
                    images.forEach(img => {
                      forceLoadImage(img);
                    });
                  }
                });
              }
            }
          }
        } catch (error) {
          console.error("Error in MutationObserver callback:", error);
        } finally {
          // 延迟重置处理标志
          setTimeout(() => {
            isProcessing = false;
          }, CONFIG.PROCESSING_DELAY);
        }
      }, CONFIG.MUTATION_DEBOUNCE);
    });

    // 监听整个body的子节点变化
    observer.observe(document.body, { childList: true, subtree: true });
  };

  /**
   * 页面加载完成后的初始化
   * 执行所有初始化操作并显示页面
   */
  window.addEventListener("load", async () => {
    try {
      // 执行所有初始化操作
      hideElements();
      forceLoadComments();
      removeAds();
      wrapImagesInP();
      setRounded();
      processIframes();
      setRoundedImages();
      styleHeaderImage();
      initializePage();
      replaceImageWrapper();
      observeDOM();

      // 显示页面
      document.body.style.opacity = "1";

      // 根据配置决定是否自动加载图片
      if (CONFIG.autoLoadImages) {
        document.querySelectorAll("img").forEach((img) => {
          forceLoadImage(img);
        });
      }
    } catch (error) {
      console.error("Error in window load handler:", error);
      // 即使出错也要显示页面
      document.body.style.opacity = "1";
    }
  });
})();