图片列表转换为画廊
Version au
Ce script ne doit pas être installé directement. C'est une librairie destinée à être incluse dans d'autres scripts avec la méta-directive // @require https://update.sleazyfork.org/scripts/545309/1645854/GM_Gallery.js
(function () {
class GM_Gallery {
#storageKey = "gallery_mode";
#gallery_mode = false;
#gallery;
constructor({ getGallery }) {
this.#gallery_mode = localStorage.getItem(this.#storageKey) === "on";
if (this.#gallery_mode) {
this.#gallery = getGallery();
this.#initStyle();
this.#initHead();
this.#initBody();
this.#initProgress();
this.#initPreview();
}
}
#initHead() {
// head只保留title,保存页面时不会下载一堆乱七八糟的css和js
document.head.innerHTML = `<title>${document.title}</title>`;
}
#initBody() {
document.body.innerHTML = `
<!-- 图片列表 -->
<div id="gallery">
${this.#gallery
.map((src, index) => {
return `
<span class="item" data-src="${src}">
<img src="${src}" onload="window.onImgLoaded()">
<div style="text-align: center;">${index + 1}</div>
</span>
`;
})
.join("")}
</div>
<!-- 加载进度 -->
<div id="progress">0/${this.#gallery.length}</div>
<!-- 开关 -->
<div id="switch">画廊模式:${this.#gallery_mode ? "开" : "关"}</div>
<!-- 大图预览 -->
<div id="mask">
<img id="preview">
</div>
`;
document.body.parentElement.scrollTop = 0;
}
#initProgress() {
const $progress = document.querySelector("#progress");
let loaded = 0;
document.querySelectorAll("#gallery img").forEach(($img) => {
$img.onload = () => {
$progress.innerHTML = `${++loaded} / ${this.#gallery.length}`;
};
});
}
#initPreview() {
const $mask = document.querySelector("#mask");
const $preview = document.querySelector("#preview");
$mask.onclick = () => {
document.body.parentElement.classList.remove("is-preview");
$preview.src = "#";
};
document.querySelector("#gallery").onclick = (e) => {
const src = e.target.dataset.src;
if (src) {
document.body.parentElement.classList.add("is-preview");
$preview.src = src;
$mask.scrollTop = 0;
}
};
}
#initSwitch() {
const $switch = document.querySelector("#switch");
$switch.onclick = () => {
if (this.#gallery_mode) localStorage.removeItem(this.#storageKey);
else localStorage.setItem(this.#storageKey, "on");
location.reload();
};
}
#initStyle() {
const style = document.createElement("style");
document.head.appendChild(style);
style.innerHTML = `
#gallery {
display: flex;
flex-flow: row wrap;
gap: 10px;
padding-bottom: 50px;
& .item {
align-self: flex-end;
cursor: pointer;
& * {
pointer-events: none;
}
& img {
width: 100px;
min-height: 100px;
object-fit: contain;
background-color: #ccc;
transition: all 0.1s;
border: 0.5px solid #ccc;
}
&:hover img {
opacity: 0.5;
}
}
}
#progress {
position: fixed;
left: 10px;
bottom: 10px;
background-color: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 4px;
padding: 4px 8px;
font-size: 16px;
pointer-events: none;
}
#switch {
position: fixed;
right: 10px;
top: 10px;
padding: 4px 8px;
cursor: pointer;
background-color: rgba(0, 0, 0, 0.8);
color: #fff;
font-size: 16px;
opacity: 0.5;
transition: all 0.3s;
&:hover {
opacity: 1;
}
}
#mask {
display: none;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
z-index: 1;
overflow: auto;
text-align: center;
& #preview {
border: 0.5px solid #ccc;
}
}
html.is-preview {
overflow: hidden;
& #mask {
display: block;
}
}
`;
}
}
window.GM_Gallery = GM_Gallery;
})();