您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Quin动态, 快捷跳转直播间
当前为
// ==UserScript== // @name Quin动态快捷跳转直播间 // @name:en BiliQuinDynamicLiveLinkJump // @description Quin动态, 快捷跳转直播间 // @description:en Quin动态直播间链接快捷跳转 // @author Yiero // @version 1.0.1 // @match https://t.bilibili.com/* // @icon https://t.bilibili.com/favicon.ico // @namespace https://github.com/AliubYiero/TamperMonkeyScripts/ // @license GPL // @run-at document-idle // ==/UserScript== var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class Info { constructor(projectName) { __publicField(this, "projectName"); __publicField(this, "header"); this.projectName = projectName; this.header = `[${projectName}]`; } log(...msg) { (() => {})(...this.contentInfo(...msg)); } info(...msg) { console.info(...this.contentInfo(...msg)); } warn(...msg) { console.warn(...this.contentInfo(...msg)); } error(...msg) { console.error(...this.contentInfo(...msg)); } contentInfo(...msg) { return [ this.header, ...msg ]; } } class EntryBranch { constructor() { __publicField(this, "branchList", []); } add(condition, callback) { if (typeof condition === "boolean") { this.branchList.push([ () => condition, callback ]); } else { this.branchList.push([ condition, callback ]); } return this; } default(callback) { this.add(true, callback); return this; } run() { const entry = this.branchList.find((entry2 => entry2[0]())); if (entry) { new Info("EntryBranch").log("进入分支", entry); entry[1](); } } } function elementWaiter(selector, parent = document.body, timeoutPerSecond = 0, delayPerSecond = 0) { parent || (parent = document.body); const entryBranch = new EntryBranch; return new Promise(((resolve, reject) => { function returnElement(element) { if (!element) { reject(new Error("void Element")); return; } setTimeout((() => { dispatchEvent(new CustomEvent("getElement", { detail: element })); resolve(element); }), delayPerSecond * 1e3); } entryBranch.add((() => !!document.querySelector(selector)), (() => { returnElement(document.querySelector(selector)); })).add((() => !!MutationObserver), (() => { const timer = timeoutPerSecond && window.setTimeout((() => { observer.disconnect(); returnElement(); }), timeoutPerSecond * 1e3); const observer = new MutationObserver(observeElementCallback); function observeElementCallback(mutations) { mutations.forEach((mutation => { mutation.addedNodes.forEach((addNode => { if (!(addNode instanceof HTMLElement)) { return; } const element = addNode.matches(selector) ? addNode : addNode.querySelector(selector); if (element) { timer && clearTimeout(timer); returnElement(element); } })); })); } observer.observe(parent, { subtree: true, childList: true }); })).default((() => { const intervalDelay = 500; let intervalCounter = 0; const maxIntervalCounter = Math.ceil((timeoutPerSecond * 1e3 || 20 * 1e3) / intervalDelay); const timer = window.setInterval((() => { if (++intervalCounter > maxIntervalCounter) { clearInterval(timer); returnElement(); return; } const element = parent.querySelector(selector); if (element) { clearInterval(timer); returnElement(element); } }), intervalDelay); })).run(); })); } class DynamicLoad { constructor() { this.updateObserver(); } get get() { return Array.from(document.querySelectorAll(".bili-dyn-list__item")); } updateObserver() { const dynamicUpdateObserver = new MutationObserver((recordList => { const appendDynamicList = []; recordList.forEach((record => { record.addedNodes.forEach((addNode => { appendDynamicList.push(addNode); })); })); window.dispatchEvent(new CustomEvent("dynamicUpdate", { detail: appendDynamicList })); })); dynamicUpdateObserver.observe(document.querySelector(".bili-dyn-list__items"), { childList: true }); } } function isQuin(dynamicDom) { var _a; const upName = (_a = dynamicDom.querySelector(".bili-dyn-title__text")) == null ? void 0 : _a.innerText; return upName === "Mr.Quin"; } function addQuinLiveBtn(dynamicDom) { if (!isQuin(dynamicDom)) { return; } const domList = { dynamicItem: dynamicDom, firstMoreBtn: dynamicDom.querySelector(".bili-dyn-more__menu__item"), popoverContainer: dynamicDom.querySelector(".bili-popover"), moreMenu: dynamicDom.querySelector(".bili-dyn-more__menu") }; const dynamicItem = dynamicDom; const CCLiveLinkBtn = domList.firstMoreBtn.cloneNode(); CCLiveLinkBtn.dataset.type = "THREE_POINT_CC_LIVE_LINK"; CCLiveLinkBtn.innerHTML = '<a href="https://cc.163.com/361433/" target="_blank">跳转CC</a>'; CCLiveLinkBtn.onclick = () => domList.popoverContainer.style.display = "none"; const douyinLiveLinkBtn = dynamicItem.querySelector(".bili-dyn-more__menu__item").cloneNode(); douyinLiveLinkBtn.dataset.type = "THREE_POINT_DOUYIN_LIVE_LINK"; douyinLiveLinkBtn.innerHTML = '<a href="https://live.douyin.com/200525029536" target="_blank">跳转抖音</a>'; douyinLiveLinkBtn.onclick = () => domList.popoverContainer.style.display = "none"; domList.moreMenu.appendChild(CCLiveLinkBtn); domList.moreMenu.appendChild(douyinLiveLinkBtn); } function isMatchURL(...regExpList) { const matchResultList = []; regExpList.forEach((regExp => { if (typeof regExp === "string") { regExp = new RegExp(regExp); } matchResultList.push(!!document.URL.match(regExp)); })); return matchResultList.includes(true); } (async () => { (new EntryBranch).add(isMatchURL("^https://t.bilibili.com/"), handlerBindQuinLiveBtn).run(); async function handlerBindQuinLiveBtn() { await elementWaiter(".bili-dyn-list__item"); const dynamicLoad = new DynamicLoad; const dynamicList = dynamicLoad.get; dynamicList.forEach(addQuinLiveBtn); window.addEventListener("dynamicUpdate", (e => { const result = e; const dynamicList2 = result.detail; dynamicList2.forEach(addQuinLiveBtn); })); } })();