快速處理畫面操作
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.greasyfork.org/scripts/570074/1777131/mike%27s%20lib.js
// ==UserScript==
// @name mike's lib
// @namespace 小說
// @version 2026-03-18
// @description 工具函式庫
// @author mike
// @match http*://*/*
// @grant none
// ==/UserScript==
(function (global) {
'use strict';
// 等待物件 func
const waitElement = (selector, callback) => {
const interval = setInterval(() => {
const element = document.querySelector(selector);
if (element) {
clearInterval(interval);
callback(element);
}
}, 100);
};
// 移除物件
const removeElement = (baseObj, removeTarget) => {
let beRemoveObj = baseObj.querySelector(removeTarget);
if (beRemoveObj) {
beRemoveObj.remove();
}
};
// 等並刪除
const waitAndKillElement = (selector) => {
waitElement(selector, () => {
removeElement(document, selector);
});
};
// 重置寬高
const resetMarginPadding = (element) => {
element.style.margin = '0px';
element.style.padding = '0px';
};
// 取得 平台名稱
const getPlatform = (platformList) => {
const pathname = window.location.pathname // 用網址查
const findPlatform = platformList.find(item => {
const [key, value] = Object.entries(item)[0];
return pathname.includes(key);
});
return Object.values(findPlatform)[0]
}
// 製作快速跳轉浮窗
// initChapterNavigator({selectors: ['.entry-content', 'p'], chapterStartsWith: ['[', '【']});
const initChapterNavigator = ({
selectors,
chapterStartsWith
}) => {
if (
!Array.isArray(selectors) ||
selectors.length === 0 ||
selectors.some(s => typeof s !== 'string' || !s.trim())
) {
console.log('[ChapterNavigator] selectors 必須為非空字串陣列');
return;
}
if (
!Array.isArray(chapterStartsWith) ||
chapterStartsWith.length === 0 ||
chapterStartsWith.some(s => typeof s !== 'string' || !s)
) {
console.log('[ChapterNavigator] chapterStartsWith 必須為非空字串陣列');
return;
}
const queryBySelectors = () => {
let current = document;
for (let i = 0; i < selectors.length; i++) {
if (!current) return [];
if (i === selectors.length - 1) {
return Array.from(current.querySelectorAll(selectors[i]));
}
current = current.querySelector(selectors[i]);
}
return [];
};
const areaKeyList = () => {
return queryBySelectors().filter(el => {
const text = el.textContent.trim();
return chapterStartsWith.some(prefix =>
text.startsWith(prefix)
);
});
};
const gotoText = (findText) => {
areaKeyList().forEach(el => {
if (el.textContent.includes(findText)) {
el.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
};
const getChapterList = () =>
areaKeyList().map(el => el.textContent);
const createFloatingBox = (chapterList) => {
if (document.getElementById('floatingBox')) {
return;
}
const floatingBox = document.createElement('div');
floatingBox.id = 'floatingBox';
Object.assign(floatingBox.style, {
position: 'fixed',
right: '10px',
bottom: '10px',
width: '150px',
height: '450px',
overflow: 'auto',
padding: '10px',
backgroundColor: '#333',
color: 'white',
borderRadius: '8px',
zIndex: '1000'
});
chapterList.forEach(text => {
const btn = document.createElement('button');
Object.assign(btn.style, {
width: '100%',
margin: '2px 0',
padding: '10px 5px',
backgroundColor: '#f44336',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
});
btn.textContent = text;
btn.onclick = () => gotoText(text);
floatingBox.appendChild(btn);
});
document.body.appendChild(floatingBox);
};
const chapterList = getChapterList();
if (!chapterList.length) {
console.log('[ChapterNavigator] 未找到任何符合規則的章節');
return;
}
createFloatingBox(chapterList);
};
// ⭐ 關鍵:對外輸出
global.mikeLib = {
waitElement,
removeElement,
waitAndKillElement,
resetMarginPadding,
getPlatform,
initChapterNavigator
};
})(window);