此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.greatest.deepsurf.us/scripts/528456/1545566/UTILS_DOM%20Library.js
您需要先安装一款用户样式管理器扩展(如 Stylus)后才能安装此样式。
您需要先安装一款用户样式管理器扩展(如 Stylus)后才能安装此样式。
您需要先安装一款用户样式管理器扩展(如 Stylus)后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
(我已经安装了用户样式管理器,让我安装!)
// ==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,
};
})();