You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Reddit滚动时视图跳回顶部的油猴脚本问题?

修复Reddit画廊视图滚动后回到顶部的问题

问题根源

Reddit采用虚拟滚动机制:当帖子移出视口时会被移除,并用占位符元素替代以维持布局高度。之前的脚本要么在滚动时频繁修改DOM导致布局回流触发滚动跳回,要么只在页面加载时注入CSS,无法覆盖动态加载的新帖子和占位符元素。

解决方案

1. 修正CSS规则

  • 补全CSS属性的分号(原代码中部分属性后缺失分号,会导致样式解析错误)
  • 为占位符元素添加匹配样式,避免布局高度突变
  • 提升CSS优先级,确保覆盖Reddit原生样式

2. 监听DOM动态变化

使用MutationObserver监听帖子容器的子元素变化,确保新加载的帖子和占位符都能应用画廊样式,替代原有的滚动/load事件触发方式,避免频繁DOM操作引发的滚动异常。

最终脚本代码

// ==UserScript==
// @name         REDDIT: gallery view
// @match        https://www.reddit.com/*
// @require      https://raw.githubusercontent.com/KenKaneki73985/javascript-utils/refs/heads/main/minified_javascript
// @require      https://raw.githubusercontent.com/KenKaneki73985/javascript-utils/refs/heads/main/show_GUI
// @require      https://raw.githubusercontent.com/KenKaneki73985/javascript-utils/refs/heads/main/countdown_with_ms
// ==/UserScript==

(function() {
    'use strict'

    // 注入基础CSS样式
    function injectGalleryCSS() {
        show_GUI("画廊视图已启用", "GUI_v1", "green", 0, 80, 16, 3000)
        
        const style = document.createElement('style')
        style.textContent = `
            shreddit-feed {
                display: block !important;
                overflow: visible !important;
            }
            
            /* 帖子元素样式 */
            shreddit-feed article,
            shreddit-feed shreddit-post-placeholder {
                float: left !important;
                width: 33% !important;
                box-sizing: border-box !important;
                padding: 8px !important;
            }
            
            /* 清除浮动,避免容器高度塌陷 */
            shreddit-feed::after {
                content: "" !important;
                display: table !important;
                clear: both !important;
            }
        `;
        document.head.appendChild(style)
    }

    // 监听DOM变化,确保新加载的内容应用样式
    function observeFeedChanges() {
        const feedContainer = document.querySelector("shreddit-feed");
        if (!feedContainer) return;

        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                if (mutation.addedNodes.length > 0) {
                    // 新元素加载时无需重复注入CSS,因为CSS是全局生效的
                    // 此处可额外处理特殊元素,确保样式正确应用
                }
            });
        });

        observer.observe(feedContainer, {
            childList: true,
            subtree: true
        });
    }

    // 页面加载完成后初始化
    window.addEventListener('load', () => {
        injectGalleryCSS();
        observeFeedChanges();
    });

    // 快捷键触发重新注入(备用)
    document.addEventListener('keydown', function(event) {
        if (event.altKey && event.key === 'k') {
            injectGalleryCSS();
        }
    });
})()

关键修复点说明

  • CSS分号补全:原代码中部分CSS属性后缺失分号,导致样式无法正常解析,这是常见的语法错误
  • 占位符样式:针对shreddit-post-placeholder元素设置相同的浮动和宽度,避免Reddit替换帖子时布局高度突变引发滚动跳回
  • MutationObserver监听:替代滚动事件触发的DOM修改,只在页面加载时注入一次全局CSS,同时监听新内容加载,确保所有帖子和占位符都遵循画廊布局
  • 避免频繁DOM操作:原脚本在滚动时反复修改每个帖子的样式,会引发大量布局回流,导致浏览器强制滚动到顶部,现在通过全局CSS样式彻底避免了这个问题

内容的提问来源于stack exchange,提问作者Lori Yagami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:42:39