Αυτός ο κώδικας δεν πρέπει να εγκατασταθεί άμεσα. Είναι μια βιβλιοθήκη για άλλους κώδικες που περιλαμβάνεται μέσω της οδηγίας meta // @require https://update.greasyfork.org/scripts/491971/1356811/libs.js
// ==UserScript==
// @name libs
// @description JavaScript 库函数,以便调用
// @namespace essence/libs
// @version 0.4
// @grant GM_addStyle
// ==/UserScript==
// 等待
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
/**
* 等待指定元素出现后,执行回调
* @param selector 元素选择器。参考`document.querySelector`
* @param callback 需要执行的回调。传递的参数为目标元素
*/
const waitElem = (selector, callback) => {
const observer = new MutationObserver(() => {
const element = document.querySelector(selector)
if (element) {
callback(element)
observer.disconnect()
}
})
observer.observe(document.body, {
childList: true,
subtree: true,
})
}
/**
* 读取网站存储到 localStorage 的所有值
* @param excludeRegexp 不读取的键的正则。如 /^Hm_lvt/
* @return {string} JSON 文本
*/
const readLocalStorageValues = (excludeRegexp = undefined) => {
const result = {}
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i)
if (excludeRegexp && excludeRegexp.test(key)) {
continue
}
result[key] = localStorage.getItem(key)
}
return JSON.stringify(result)
}
/**
* 恢复数据到网站的 localStorage
* @param {string} json
*/
const restoreLocalStorageValues = (json) => {
const data = JSON.parse(json)
Object.keys(data).forEach(key => localStorage.setItem(key, data[key]))
}
/**
* 让容器以 flex row 显示子元素
* @param elem {HTMLElement} 容器元素
* @param gap {string} 子元素的间隔。默认"8px"
* @param alignItems {string} 子元素垂直对齐。默认"center"
*/
const containerToRow = (elem, gap = "8px", alignItems = "center") => {
elem.style.display = "flex"
elem.style.flexDirection = "row"
elem.style.justifyContent = "space-between"
elem.style.gap = gap
elem.style.alignItems = alignItems
}
/**
* 发送通知。可使用 Toast 实例快捷发送消息
* @param message {string} 消息
* @param color {string} 消息类型。可选:"default" | "primary" | "success" | warning" | "danger"
* @param element 右侧操作按钮
* @param disappear 持续时长(毫秒)
*/
const toast = (message, color = 'primary', element = null, disappear = 5000) => {
// 创建通知元素
const toast = document.createElement('div')
// 设置消息文本
toast.textContent = message
// 如果提供了操作按钮元素,添加到通知
if (element) {
toast.appendChild(element)
}
// 根据消息的类型设置颜色,并显示
toast.classList.add("toast", "essenceX", color)
// 将通知元素添加到页面
document.body.appendChild(toast)
// 显示 toast
setTimeout(() => toast.classList.add("show"), 10)
// toast 在 N 秒后消失
setTimeout(() => {
toast.classList.remove("show")
toast.classList.add("hide")
// 在消失动画完成后,从页面移除通知元素
toast.addEventListener('transitionend', () => toast.remove())
}, disappear)
}
/**
* 快捷发送通知
*/
const Toast = {
default: (message, element = null, disappear = 5000) => toast(message, "default", element, disappear),
primary: (message, element = null, disappear = 5000) => toast(message, "primary", element, disappear),
success: (message, element = null, disappear = 5000) => toast(message, "success", element, disappear),
warning: (message, element = null, disappear = 5000) => toast(message, "warning", element, disappear),
danger: (message, element = null, disappear = 5000) => toast(message, "danger", element, disappear)
}
const removeDialog = (dialog) => {
dialog.classList.remove("show")
dialog.classList.add("hide")
// 在消失动画完成后,从页面移除通知元素
dialog.addEventListener('transitionend', () => dialog.remove())
}
/**
* 显示对话框
* @param title {string} 标题
* @param body {Element} 内容
* @param isModel {boolean} 是否为模态对话框
* @return {HTMLElement} 返回对话框实例,以便 remove()
*/
const showDialog = (title, body, isModel = false) => {
const dialog = document.createElement('div')
const content = document.createElement('div')
const header = document.createElement('div')
const dialogBody = document.createElement('div')
dialog.classList.add("dialog", "essenceX")
content.classList.add("dialog-content", "essenceX")
header.classList.add("dialog-header", "essenceX")
dialogBody.classList.add("dialog-body", "essenceX")
header.textContent = title
dialogBody.appendChild(body)
content.append(header, dialogBody)
dialog.appendChild(content)
document.body.appendChild(dialog)
// 使用动画显示对话框
setTimeout(() => dialog.classList.add("show"), 10)
// 不是模态对话框时,点击外部即取消
if (!isModel) {
window.addEventListener("click", event => {
if (event.target === dialog) {
removeDialog(dialog)
}
})
}
return dialog
}