Note
图源:
https://www.bilibili.com/video/BV11dNE6LEkr(左)
https://www.bilibili.com/video/BV1dawuzuETu(右)
注:作者安装了氢洛谷 & 主页显示收藏题单,此图仅供参考。
某日作者突发奇想想给洛谷换一个背景,但查找了很久无果,遂写了一个。感谢 @CrystalCore 的 启发。
起初我尝试过在 body 内插入背景版然后将 .background 元素设为透明,但是脚本并没有发挥作用,后来我发现是洛谷主页面的 nav 和 main 这两个主容器自带了不透明背景色,那问题就很好解决了,将 nav 和 main 的背景色调为透明即可。其他界面也是相同调整。
简单来说就是把页面初始的底色透明化,然后在页面最后端固定一个背景板。
这里参考了 @CrystalCore 的 插件,引入 Cropper.js 库,这个库可以非常方便地实现图片的缩放、拖动、裁剪等操作,简单高效。
上传的图片通过 Cropper.js 库转成 Base64 缓存到本地,但是这里有一个问题:GM_setValue 的存储空间通常限制在
UPD
有时候背景图过亮、过暗,或者颜色过于鲜艳,会影响正文阅读,因此脚本加入了背景滤镜功能。
这里并没有重新处理图片,而是直接利用 CSS 的 filter 属性,在背景层上叠加 blur()、brightness() 和 saturate() 三种滤镜。由于这些滤镜均由浏览器实时渲染,因此拖动滑块时能够立即看到效果,也不会增加额外的图片处理开销。
既然背景已经放到了页面最底层,那么接下来要做的就是让它能够"露出来"。
实现时并没有直接删除所有背景,而是分别调整导航栏、主内容区、侧边栏、卡片、顶部横幅以及页脚等区域的背景颜色,将原本的纯白背景改为带透明度的 rgba() 颜色。这样既能够保留原有的层次感,也可以根据背景图片灵活调节透明程度,不至于影响阅读体验。
不过在适配过程中也遇到了一些问题,例如文章页面部分区域的背景色直接写在元素上,无法通过修改公共样式解决,因此额外使用 CSS 将这些白色背景强制覆盖,否则总会留下几块"白板"。
总不能每次修改参数都打开脚本改代码吧()
因此脚本实现了一个独立的设置面板,所有组件均由 JavaScript 动态创建,不依赖洛谷原有页面结构。各种滑块、输入框通过事件监听实时修改配置,每当用户调整参数时,都会立即刷新页面效果,并同步保存配置,实现真正的"所见即所得"。
为了尽量不影响页面整体风格,面板默认隐藏,通过"更多功能"菜单即可打开。
所有配置都会通过 Tampermonkey 提供的 GM_getValue 与 GM_setValue 保存到本地,包括背景图片、透明度、模糊程度、亮度以及饱和度等参数。
脚本启动时首先读取这些配置,如果不存在则自动使用默认值,因此即使刷新页面或者重新打开浏览器,也能够恢复到上一次的设置,无需重新调整。
为了保持与洛谷原生界面一致,脚本没有额外添加悬浮按钮,而是将"背景设置"入口直接插入到"更多功能"菜单中。
实现方式比较简单:复制已有菜单项的 DOM 结构,仅修改显示文字和点击事件。这样不仅能够自动继承洛谷原有的样式和动画效果,也避免了重新设计按钮带来的风格不统一问题。
另外,由于洛谷新旧版本页面结构有所不同,脚本分别适配了两套菜单结构,在不同页面下都会自动寻找对应位置完成插入。
洛谷目前采用的是单页应用(SPA)架构,页面切换时通常不会重新加载整个网页,而是动态替换页面内容。
如果背景层、菜单等元素只在初始化时创建一次,那么切换页面后它们很容易被新的 DOM 覆盖掉。因此脚本使用 MutationObserver 持续监听页面结构变化,一旦检测到背景层或菜单入口被移除,就自动重新创建对应元素。
借助这一机制,无论是在题目、讨论、博客还是个人主页之间切换,背景始终能够正常显示,无需手动刷新页面。
脚本中的所有参数修改都会实时生效,不需要额外点击"保存"按钮。
此外,为了尽可能降低对洛谷原有页面的影响,整个脚本基本采用"新增元素 + 覆盖样式 + 监听页面变化"的实现方式,而不是直接修改网页源码。因此,即使洛谷后续进行小规模页面更新,脚本通常也能够正常工作,后续维护起来也相对容易。
版本号有点神秘,凑合看吧。
请确定主题为洛谷后使用。
AI 使用说明:插件的开发曾使用 DeepSeek 辅助,本文使用 Chat GPT 润色,保证本人贡献不小于 AI。


