您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Eine nützliche Bibliothek für verschiedene Funktionen
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://updategreasyfork.deno.dev/scripts/528456/1545566/UTILS_DOM%20Library.js
// ==UserScript== // @name UTILS_DOM Library // @namespace dannysaurus.epik // @version 1.0 // @description dom manipulation library // // @license MIT // @grant unsafeWindow // ==/UserScript== /* jslint esversion: 11 */ /* global unsafeWindow */ (() => { 'use strict'; const selectorsConfig = (() => { const ids = { bcasts: 'bcasts', ctabs: 'ctabs', ctext: 'ctext', chatInputWrapper: 'chat-input-wrapper', broadcastSlots: 'broadcastSlots', messagesLC: 'messagesLC', usersLC: 'usersLC', username: 'username', }; const classNames = { userSection: 'user-section', chatSection: 'chat-section', sidebarSection: 'sidebar-section', bcstPlayer: 'bcst-player', userItem: 'user-item', theIcons: 'the-icons', faUser: 'fa-user', userName: 'user-name', }; const attributes = { }; const querySelectors = { bcastsContainer: `#${ids.bcasts}`, ctabsContainer: `#${ids.ctabs}`, ctextContainer: `#${ids.ctext}`, chatInputWrapper: `#${ids.chatInputWrapper}`, broadcastSlots: `#${ids.broadcastSlots}`, messagesLC: `#${ids.messagesLC}`, usersLC: `#${ids.usersLC}`, usernameContainer: `#${ids.username}`, userSection: `.${classNames.userSection}`, chatSection: `.${classNames.chatSection}`, sidebarSection: `.${classNames.sidebarSection}`, bcstPlayer: `.${classNames.bcstPlayer}`, userItem: `.${classNames.userItem}`, userIcon: `.${classNames.theIcons} .${classNames.faUser}`, userName: `.${classNames.userName}`, }; return { ids, classNames, attributes, querySelectors, }; })(); /** * Tries to select an element by repeatedly attempting to find it. * * @param {Object} options - The options for selecting the element. * @param {String} [options.selectors] - The function to select the element. * @param {number} [options.maxAttempts=6] - The number of attempts to make. * @param {number} [options.intervalMs=10000] - The interval between attempts in milliseconds. * @returns {Promise<Element|NodeList>} The selected element(s). * * @throws {Error} If the element(s) could not be found. */ const trySelectElement = async ({ selectors, maxAttempts = 6, intervalMs = 10000, throwError = true, } = {}) => { const sleep = () => new Promise(resolve => setTimeout(resolve, intervalMs)); for (let attemptCount = 0; attemptCount < maxAttempts; attemptCount++) { const elements = document.querySelector(selectors); if (elements instanceof Element || (elements instanceof NodeList && elements.length)) { return elements; } await sleep(); } throw new Error(`Element(s) not found with selectors: ${selectors}`); }; const getUsername = () => { return document.querySelector(selectorsConfig.querySelectors.usernameContainer)?.textContent || ''; }; /** * Checks if the specified keys are pressed. * * @param {KeyboardEvent} event - The keyboard event. * @param {Object} keysToCheck - The keys to check. * @returns {boolean} True if all specified keys are pressed, false otherwise. */ const areKeysPressed = (event, keysToCheck) => { const keys = Object.keys(keysToCheck || []); if (keys.length === 0) { return false; } return Object.keys(keysToCheck).every(key => event[key] === keysToCheck[key]); }; unsafeWindow.dannysaurus_epik ||= {}; unsafeWindow.dannysaurus_epik.libraries ||= {}; unsafeWindow.dannysaurus_epik.libraries.UTILS_DOM = { selectors: selectorsConfig, trySelectElement, getUsername, areKeysPressed, }; })();