alist美化
alist作为一个优秀的开源网盘程序,其用户基数是非常庞大的,所以这其中也就不乏有我这样的美化小王子(无敌大闲逼)的存在。因此,现在网上已经有了很多文章贴出了alist自定义头部与内容的美化代码,例如Alist V3 美化教程(4)(这哥们貌似是alist美化的鼻祖),这种美化的代码大概如下所示:
1 2 3 4 5 6 7 8 9 10 11 12
| <style>
.hope-c-PJLV.hope-c-PJLV-ikSuVsl-css { background-color: rgba(255, 255, 255, 0.2) !important; }
.hope-c-PJLV.hope-c-PJLV-iiuDLME-css { background-color:rgb(0 0 0 / 20%) !important; }
</style>
|
提出问题
这种美化方式有一个明显的问题。alist作为一个webapp,页面的内容是动态生成的,并且不像静态网站,其元素名是不保证其相对稳定的。因此,使用这种方式美化alist的代码也是不可靠的,可能在alist更新之后,类名发生更改,部分美化就失效了。更何况,alist每次更新都会带来一些新的特性,虽然其大部分都是功能性的,但有时也会有一些新的前段元素与样式变动出现,因此,使用这种方式美化alist的代码需要不断地维护。
我随便找了个一个月前的美化代码(来自Alist美化教程),发现其已经过时。
应有效果:

实际效果:

显然,地址栏、功能栏与展示方式切换按钮的美化都失效了。事实上,原版截图的搜索栏美化应该已经失效了。
解决问题
我反正是懒得每次都去维护这些代码,所以我就想到了个一劳永逸的美化方案。这个方案的核心思想是:关注alist元素中的一些特征,使用javascript捕获它们,然后动态替换样式。这样一来,就不需要担心alist更新后,类名发生变化导致美化失效的问题了。找了一圈,发现没有已有的方案,遂决定自己动手撸一个。
alist js美化方案
代码我已贴在了我的github存储库上,你也可以直接在下方查看。
代码
注意!要想使用这段代码,你必须将代码最尾部的themeColor
变量设置为你alist的主题色(如果没有设置主题色,可以不填),而且需要写成rgb(r, g, b)的标准格式。
推荐一起使用我的自定义头部代码,这样效果更佳(不然没有背景)。
自定义内容
不过好像放自定义头部也能跑…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
<style> .hope-ui-light, .hope-ui-dark { --hope-colors-background: transparent; } </style>
<script type="module"> (() => { const wrapHistoryMethod = (type) => { const orig = history[type]; return function (...args) { const rv = orig.apply(this, args); const event = new CustomEvent(type, { detail: args }); window.dispatchEvent(event); return rv; }; }; history.pushState = wrapHistoryMethod('pushState'); history.replaceState = wrapHistoryMethod('replaceState'); })();
class Beautifier {
static themeColor = 'rgb(24, 144, 255)'; static lightBgColor = 'rgba(255, 255, 255, 0.8)'; static darkBgColor = 'rgb(32, 36, 37)';
static lightSelector = '.hope-ui-light :not(.hope-tooltip):not(.hope-close-button):not(a)'; static darkSelector = '.hope-ui-dark :not(.hope-tooltip):not(.hope-close-button):not(a)'; static ignoredColors = [ 'rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0.65)', 'rgba(0, 0, 0, 0.09)' ];
constructor(themeColor = Beautifier.themeColor, lightBgColor = Beautifier.lightBgColor, darkBgColor = Beautifier.darkBgColor) { this.themeColor = themeColor; this.lightBgColor = lightBgColor; this.darkBgColor = darkBgColor;
this.ignoredColors = [...Beautifier.ignoredColors, this.themeColor];
this.observer = null; }
#rewriteBgColor(theme) { let selector = theme === 'light' ? Beautifier.lightSelector : Beautifier.darkSelector; let bgColor = theme === 'light' ? this.lightBgColor : this.darkBgColor;
document.querySelectorAll(selector).forEach(element => { const computedStyle = getComputedStyle(element);
if (computedStyle.backgroundImage !== 'none') { return; }
if (!this.ignoredColors.includes(computedStyle.backgroundColor)) { element.style.backgroundColor = bgColor; element.setAttribute('data-beautified', 'true'); } }); }
#beautify() { if (!location.pathname.startsWith('/@manage') && !location.pathname.startsWith('/@login')) { this.#rewriteBgColor('light'); this.#rewriteBgColor('dark'); } }
observe() { this.observer = new MutationObserver(this.#beautify.bind(this)); this.observer.observe(document.body, { childList: true, subtree: true });
this.#beautify(); }
disconnect() { if (this.observer) { this.observer.disconnect(); } }
undo() { this.disconnect();
document.body.querySelectorAll('[data-beautified]').forEach(element => { element.style.backgroundColor = ''; element.removeAttribute('data-beautified'); }); } }
const beautifier = new Beautifier('rgb(240, 128, 128)'); window.beautifier = beautifier; beautifier.observe();
(() => { function fixLogin(pathname) { if (pathname.startsWith('/@login')) { beautifier.undo(); } else { beautifier.disconnect(); beautifier.observe(); } }
['popstate', 'pushState', 'replaceState'].forEach(eventType => { addEventListener(eventType, () => { fixLogin(location.pathname); }); }); })(); </script>
|
自定义头部
建议一起使用,效果更佳。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
<link rel="stylesheet" href="https://s4.zstatic.net/ajax/libs/lxgw-wenkai-webfont/1.7.0/lxgwwenkai-regular.min.css">
<style> video::-webkit-media-controls { display: none; }
body { background-repeat: no-repeat; background-size: cover; background-attachment: fixed; background-position: center; }
body.hope-ui-dark { background-color: rgb(32, 36, 37); background-image: linear-gradient(rgba(32, 36, 37, 0.8), rgba(32, 36, 37, 0.8)), url('https://t.alcy.cc/moez'); }
body.hope-ui-light { background-image: url('https://t.alcy.cc/moez'); }
.hope-ui-light .hope-c-PJLV-ikJQsXT-css { background: rgba(255, 255, 255, 0.8) !important; backdrop-filter: blur(0) !important; }
.hope-ui-dark .hope-c-PJLV-ikJQsXT-css { background: rgb(32, 36, 37) !important; backdrop-filter: blur(0) !important; }
* { font-family: "LXGW WenKai", sans-serif; } </style>
<script>if (localStorage.getItem('modelId') === null) { localStorage.setItem('modelId', '9'); localStorage.setItem('modelTexturesId', '0'); } </script> <script src="https://cdn.mmoe.work/live2d-widget/autoload.js"></script>
<script src="https://s4.zstatic.net/ajax/libs/js-polyfills/0.1.43/polyfill.min.js?features=String.prototype.replaceAll"></script>
|
从cdn引入
如果你只需要美化alist背景色,而不需要自定义头部,可以直接从CDN引入这段代码(如果有自定义主题色,记得fork一份,填入主题色后,再改成你自己的仓库)(itdog了一下速度竟出奇的可观):
1
| <script type="module" src="https://fastly.jsdelivr.net/gh/adogecheems/alist-beautification@latest/src/beautifier.js"></script>
|
代码说明
这段代码提供了一个Beautifier
类,用于自动修改alist的背景色,其创建的实例会监听DOM的变化,并在页面变动时自动对有背景色的元素应用样式(当然是有选择的)。在控制台中,你可以通过window.beautifier
访问这个实例。
它暴露了以下方法:
observe()
: 开始监听页面变化并应用美化
disconnect()
: 停止监听页面变化
undo()
: 恢复元素背景色到默认状态
还有一个愚蠢到有点无敌的修复机制,用于修复登录页面的背景色。
这些方法工作的效果:

效果
使用这段代码后,你的alist元素将会有一个统一的背景色。并且在alist版本更新之后,美化器也会工作得相当良好。
不说了上图:

最后
如果你有任何问题与建议,欢迎在评论区与Github issues中提出(去github给我点一个star是再好不过的了)。希望这个美化方案能给你一个良好而统一的视觉体验,如要转载,也请希望务必注明出处。