如何修复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
相关产品推荐
相关产品推荐

