// ==UserScript== // @name 巴哈姆特動畫瘋自動播放 // @namespace http://tampermonkey.net/ // @version 1.0.1 // @description 自动同意動畫瘋的年龄协议并在视频结束后自动播放下一集 // @author luosansui // @match https://ani.gamer.com.tw/animeVideo.php?sn=* // @icon https://www.google.com/s2/favicons?sz=64&domain=gamer.com.tw // @license MIT // @grant none // @downloadURL none // ==/UserScript== 'use strict'; (async function() { const videoElement = await waitForElement('.video-js video'); observeLoading(videoElement, async ()=>{ const agreeButton = await waitForElement('#adult'); agreeButton.click(); console.log('已同意年龄限制'); }) // 等待视频结束 videoElement.addEventListener('ended', async () => { const nextButton = await waitForElement('.vjs-next-button'); nextButton.click(); console.log("已自动播放下一集"); }); })(); function waitForElement(selector, timeout = 30){ return new Promise((resolve, reject) => { // 立刻检查, 如果元素存在就不启用定时器 const element = document.querySelector(selector); if (element) { resolve(element); return } const interval = 50; // 检查间隔 const checkExist = setInterval(() => { const element = document.querySelector(selector); if (element) { clearInterval(checkExist); resolve(element); } }, interval); // 设置超时 setTimeout(() => { clearInterval(checkExist); reject(new Error(`Element not found: ${selector}`)); }, timeout * 1000); }); }; function observeLoading(targetNode , callback) { const callFunc = ()=>{ // 获取当前的 poster 属性值 const posterValue = targetNode.getAttribute('poster'); // 调用回调函数并传递 poster 属性值 callback(posterValue); } // 创建一个 MutationObserver 实例 const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'attributes' && mutation.attributeName === 'poster') { callFunc() } }); }); // 配置观察选项 const config = { attributes: true, // 观察属性变化 childList: false, // 不观察子节点变化 subtree: false // 不观察子树变化 }; // 立即调用 callFunc() // 开始观察 observer.observe(targetNode, config); }