您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A library containing several functions I use often in my other scripts
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/478390/1271335/TetteLib.js
// ==UserScript== // @name TetteLib // @namespace http://tampermonkey.net/ // @version 0.2 // @description A library containing several functions I use often in my other scripts // @author TetteDev // @match *://*/* // @grant none // ==/UserScript== function simulateNotification(title, message, type = "info", timeout = 2500) { const toastId = "simpleToast"; var notificationContainer = document.createElement("div"); notificationContainer.id = toastId; let existingNotification = document.getElementById(toastId); if (existingNotification) existingNotification.remove(); notificationContainer.title = "Click to dismiss this message"; var innerContainer = document.createElement("div"); const imgSize = 54; let imgSrc = ""; let backgroundColor = ""; let fontColor = ""; if (type.toLowerCase() === "debug") { imgSrc = "https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678124-wrench-screwdriver-64.png"; backgroundColor = "#eac100"; fontColor = "#323232"; } else if (type.toLowerCase() === "error") { imgSrc = "https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678069-sign-error-64.png"; backgroundColor = "#ff0000"; fontColor = "#ffffff"; } else { imgSrc = "https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678110-sign-info-64.png"; backgroundColor = "#0f0f0f"; fontColor = "#ffffff"; } notificationContainer.style.cssText = `position: fixed; bottom: 15px; right: 15px; background-color: ${backgroundColor}; color: ${fontColor}; border: 1px solid #ffffff; max-width: 20%; padding-left: 50px; padding-right: 50px; padding-top:10px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); z-index: 9999; opacity: 1; transition: opacity 1s, border-radius 0.5s; border-radius: 5px; cursor: pointer; ` innerContainer.innerHTML = `<img src='${imgSrc}' style='width:${imgSize}px;height:${imgSize}px;padding-bottom:10px;display:block;margin:auto;'></img> <p id='title' style='text-align:center;font-weight:bold;font-size:20px;'>${title}</p> <p id='message' style='text-align:center;padding-bottom:15px;font-size:15px;'>${message}</p>`; notificationContainer.appendChild(innerContainer); notificationContainer.onclick = function() { document.body.removeChild(notificationContainer); notificationContainer = null; } document.body.appendChild(notificationContainer); if (type.toLowerCase() === "debug") { console.warn(`[Youtube AdSkipper][DEBUG] ${title}: ${message}`); } else if (type.toLowerCase() === "error") { console.error(`[Youtube AdSkipper][ERROR] ${title}: ${message}`); } // Set a timer to fade out the notification after 'timeout' milliseconds if (if 'timeout' is not -1 or less) if (timeout > -1) { setTimeout(function() { if (notificationContainer == null) return; notificationContainer.style.opacity = 0; setTimeout(function() { if (notificationContainer == null) return; document.body.removeChild(notificationContainer); }, 500); // Remove the notification after the fade-out animation (adjust as needed) }, (timeout < 1 ? 2500 : timeout)); // Start the fade-out animation after 5 seconds (adjust as needed) } } function waitForElement(selector) { return new Promise((resolve, reject) => { const el = document.querySelector(selector); if (el) {resolve(el);} new MutationObserver((mutationRecords, observer) => { // Query for elements matching the specified selector Array.from(document.querySelectorAll(selector)).forEach((element) => { resolve(element); //Once we have resolved we don't need the observer anymore. observer.disconnect(); }); }) .observe(document.documentElement, { childList: true, subtree: true }); }); } function waitForElementWithTimeout(selector, mustBeVisibleToEye = false, timeout = 3000) { return new Promise((resolve, reject) => { if (timeout < 0) timeout = 0; if (!selector) reject("No selector specified"); const el = document.querySelector(selector); if (el && (mustBeVisibleToEye ? __visible(el) : true)) { resolve(el); } const timeoutMessage = `Timeout: Element with selector '${selector}' not found within ${timeout} ms`; const timer = setTimeout(() => { reject(new Error(timeoutMessage)); }, timeout); const observer = new MutationObserver((mutationRecords, observer) => { const elements = Array.from(document.querySelectorAll(selector)); if (elements.length > 0 && mustBeVisibleToEye) elements = elements.find((el) => __visible(el)); if (elements.length > 0) { clearTimeout(timer); observer.disconnect(); resolve(elements[0]); } }); observer.observe(document.documentElement, { childList: true, subtree: true, }); }); } function traverseParentsUntil(startElement, predicateUntil) { if (!startElement) return null; if (!predicateUntil || typeof predicateUntil !== "function") return null; if (!startElement.parentElement) return predicateUntil(startElement) ? startElement : null; while (startElement.parentElement) { if (predicateUntil(startElement.parentElement)) return startElement.parentElement; else startElement = startElement.parentElement; } return null; } function traverseChildrenUntil(startElement, predicateUntil) { if (!startElement) return null; if (!predicateUntil || typeof predicateUntil !== "function") return null; if (!startElement.firstChild) return predicateUntil(startElement) ? startElement : null; while (startElement.firstChild) { if (predicateUntil(startElement.firstChild)) return startElement.firstChild; else startElement = startElement.firstChild; } return null; } function __visible(el) { return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址