Greasy Fork is available in English.
对博看 图片 阅读体验进行优化
// ==UserScript==
// @name 博看 图片查看器
// @namespace http://tampermonkey.net/
// @version 2024-12-31
// @description 对博看 图片 阅读体验进行优化
// @author sssw
// @match https://zq.bookan.com.cn/*
// @match http://zq.bookan.com.cn/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=bookan.com.cn
// @grant none
// @license MIT
// ==/UserScript==
(function () {
'use strict';
let isMainExecuted = false;
// 获取当前网页的 URL
const currentUrl = window.location.href;
// 提取最后一个 # 后的数字
const hashValue = currentUrl.split('#').pop(); // 获取 # 后的部分
// 当前图片索引
let currentIndex = parseInt(hashValue, 10); // 转换为数字
// 预加载图片
function preloadImages(images) {
return images.map(src => {
const img = new Image();
img.src = src;
return img;
});
}
// 提取所有 .mg 图片链接
function extractMgImages() {
const images = [];
const imgElements = document.querySelectorAll('img.slide-img');
imgElements.forEach(img => {
const dataSrc = img.getAttribute('data-src');
if (dataSrc && dataSrc.endsWith('.mg')) {
images.push(dataSrc);
}
});
return images;
}
// 创建图片浏览器
function createImageBrowser(images) {
if (images.length === 0) {
// alert('未找到任何 .mg 图片!');
return;
}
// 创建容器
const container = document.createElement('div');
container.style.position = 'fixed';
container.style.top = '0';
container.style.left = '0';
container.style.width = '100%';
container.style.height = '100%';
container.style.backgroundColor = '#000';
container.style.zIndex = '9999';
container.style.display = 'flex';
container.style.alignItems = 'center';
container.style.justifyContent = 'center';
container.style.overflow = 'hidden';
// 创建图片显示区域
const imgDisplay = document.createElement('img');
imgDisplay.style.maxWidth = '100%'; // 图片最大宽度为页面宽度
imgDisplay.style.maxHeight = '100%'; // 图片最大高度为页面高度
imgDisplay.style.objectFit = 'contain'; // 保持图片比例
imgDisplay.src = images[currentIndex];
container.appendChild(imgDisplay);
// 创建导航按钮容器
const navContainer = document.createElement('div');
navContainer.style.position = 'absolute';
navContainer.style.bottom = '20px';
navContainer.style.width = '100%';
navContainer.style.display = 'flex';
navContainer.style.justifyContent = 'space-between';
navContainer.style.padding = '0 20px';
navContainer.style.boxSizing = 'border-box';
// 上一张按钮
const prevButton = document.createElement('button');
prevButton.textContent = '上一张';
prevButton.style.padding = '10px 20px';
prevButton.style.fontSize = '16px';
prevButton.style.cursor = 'pointer';
prevButton.style.backgroundColor = '#e7392e';
prevButton.style.color = '#fff';
prevButton.style.border = 'none';
prevButton.style.borderRadius = '5px';
// 下一张按钮
const nextButton = document.createElement('button');
nextButton.textContent = '下一张';
nextButton.style.padding = '10px 20px';
nextButton.style.fontSize = '16px';
nextButton.style.cursor = 'pointer';
nextButton.style.backgroundColor = '#e7392e';
nextButton.style.color = '#fff';
nextButton.style.border = 'none';
nextButton.style.borderRadius = '5px';
navContainer.appendChild(prevButton);
navContainer.appendChild(nextButton);
container.appendChild(navContainer);
// 关闭按钮
const closeButton = document.createElement('button');
closeButton.textContent = '关闭';
closeButton.style.position = 'absolute';
closeButton.style.top = '20px';
closeButton.style.right = '20px';
closeButton.style.padding = '10px 20px';
closeButton.style.fontSize = '16px';
closeButton.style.cursor = 'pointer';
closeButton.style.backgroundColor = '#e7392e';
closeButton.style.color = '#fff';
closeButton.style.border = 'none';
closeButton.style.borderRadius = '5px';
container.appendChild(closeButton);
// 添加到页面
document.body.appendChild(container);
function preloadAdjacentImages(currentIndex) {
// 预加载前后各2张图片
const preloadRange = 2;
for (let i = -preloadRange; i <= preloadRange; i++) {
const index = currentIndex + i;
if (index >= 0 && index < images.length) {
const img = new Image();
img.src = images[index];
}
}
}
// 更新图片显示,先预加载图片,加载完成后再更新 src
function updateImage() {
const newSrc = images[currentIndex];
const tempImage = new Image();
tempImage.src = newSrc;
// 预加载相邻的图片
preloadAdjacentImages(currentIndex);
tempImage.onload = () => {
imgDisplay.src = tempImage.src; // 使用已加载的图片
};
}
// 按钮点击事件
prevButton.addEventListener('click', () => {
currentIndex = (currentIndex - 1 + images.length) % images.length;
updateImage();
});
nextButton.addEventListener('click', () => {
currentIndex = (currentIndex + 1) % images.length;
updateImage();
});
closeButton.addEventListener('click', () => {
container.remove();
});
// 键盘事件
document.addEventListener('keydown', (event) => {
if (event.key === 'ArrowLeft' || event.key === 'PageUp') {
// 上一张
currentIndex = (currentIndex - 1 + images.length) % images.length;
updateImage();
} else if (event.key === 'ArrowRight' || event.key === 'PageDown') {
// 下一张
currentIndex = (currentIndex + 1) % images.length;
updateImage();
} else if (event.key === 'Escape') {
// 关闭
container.remove();
}
});
// 鼠标滚轮事件
container.addEventListener('wheel', (event) => {
event.preventDefault(); // 阻止页面滚动
// alert('container wheel');
console.log('container wheel event');
if (event.deltaY > 0) {
// 向下滚动,下一张
currentIndex = (currentIndex + 1) % images.length;
} else if (event.deltaY < 0) {
// 向上滚动,上一张
currentIndex = (currentIndex - 1 + images.length) % images.length;
}
updateImage();
}, { passive: false });
}
// 主函数
function main() {
const images = extractMgImages();
// alert('main');
console.log('main');
createImageBrowser(images);
document.body.style.backgroundColor = "white";
isMainExecuted = true; // 标记 main 已经执行
}
// 鼠标滚轮事件
document.addEventListener('wheel', (event) => {
console.log('document wheel event');
// 如果 main 还没有执行,则执行 main 并返回
if (!isMainExecuted) {
main();
return;
}
}); //
// 添加一个按钮到页面,点击后启动图片浏览器
const button = document.createElement('button');
button.textContent = '启动 MG 图片浏览器';
button.style.position = 'fixed';
button.style.bottom = '20px';
button.style.right = '20px';
button.style.padding = '10px 20px';
button.style.fontSize = '16px';
button.style.zIndex = '9999';
button.style.cursor = 'pointer';
button.style.backgroundColor = '#e7392e';
button.style.color = '#fff';
button.style.border = 'none';
button.style.borderRadius = '5px';
button.addEventListener('click', main);
document.body.appendChild(button);
})();