// ==UserScript== // @name 重庆人社|重庆继续教育|无报错控制台无报错+自动下一节 // @namespace http://tampermonkey.net/ // @version 1.5 // @description 仅指定域名生效,UI可拖动,视频最高15倍速,自动点下一节 // @author bka // @match *://*.21tb.com/* // @grant none // @tag 21tb // ==/UserScript== (function() { 'use strict'; // 单例检查 if (document.getElementById("autoStudyUIContainer")) { console.log('脚本已运行,无需重复注入'); return; } // 样式 const style = document.createElement('style'); style.textContent = ` #autoStudyUIContainer{ position:fixed; top:70px; right:15px; z-index:99999999; background:#fff; border:1px solid #e5e7eb; border-radius:10px; padding:16px; width:320px; box-shadow:0 4px 20px rgba(0,0,0,0.15); font-family:Microsoft YaHei,sans-serif; user-select:none; } #uiDragHead{ text-align:center; font-size:16px; font-weight:bold; color:#333; margin:0 0 12px 0; padding:4px 0; cursor:move; border-bottom:1px solid #eee; } .ui-item{ margin:12px 0; font-size:14px; color:#444; } #speedValue{ color:#f56c6c; font-weight:bold; margin:0 6px; } input[type="range"]{ width:180px; margin:0 5px; vertical-align:middle; } .btn-wrap{ text-align:center; margin-top:15px; } .btn-wrap button{ padding:6px 12px; margin:0 4px; border:none; border-radius:6px; cursor:pointer; font-size:13px; transition:0.2s; } #startBtn{background:#67c23a;color:#fff;} #stopBtn{background:#e6a23c;color:#fff;} #closeBtn{background:#f56c6c;color:#fff;} .btn-wrap button:hover{opacity:0.9;} `; document.head.appendChild(style); // 悬浮UI const uiBox = document.createElement('div'); uiBox.id = "autoStudyUIContainer"; uiBox.innerHTML = `
重庆继续教育无报错终极版
自动静音:
防页面休眠:
自动跳下一课:
视频倍速: 4.0
`; document.body.appendChild(uiBox); // 拖拽 const dragHead = document.getElementById('uiDragHead'); let isDrag = false; let offsetX, offsetY; dragHead.addEventListener('mousedown', (e) => { isDrag = true; offsetX = e.clientX - uiBox.getBoundingClientRect().left; offsetY = e.clientY - uiBox.getBoundingClientRect().top; uiBox.style.transition = 'none'; e.preventDefault(); }); document.addEventListener('mousemove', (e) => { if (!isDrag) return; let left = e.clientX - offsetX; let top = e.clientY - offsetY; const w = uiBox.offsetWidth, h = uiBox.offsetHeight; left = Math.max(0, Math.min(left, window.innerWidth - w)); top = Math.max(0, Math.min(top, window.innerHeight - h)); uiBox.style.left = left + 'px'; uiBox.style.top = top + 'px'; }); document.addEventListener('mouseup', () => { isDrag = false; }); // ==================== 核心配置 ==================== let timer = null; let isRunning = true; let playSpeed = 4.0; let wakeLock = null; // 倍速 const speedRange = document.getElementById('speedRange'); const speedValue = document.getElementById('speedValue'); speedRange.addEventListener('input', () => { playSpeed = parseFloat(speedRange.value); speedValue.innerText = playSpeed.toFixed(1); }); // 休眠 async function keepAwake() { if (!document.getElementById('preventSleep').checked) return; try { wakeLock = await navigator.wakeLock.request('screen'); } catch (e) {} } // 视频倍速 + 静音 function applyVideoConfig() { document.querySelectorAll('video').forEach(v => { v.playbackRate = playSpeed; v.muted = document.getElementById('autoMute').checked; }); } // ==================== 修复:自动关闭完成弹窗(纯原生JS) ==================== function autoCloseFinishModal() { const buttons = document.querySelectorAll('button, div[role="button"]'); for (const btn of buttons) { if ((btn.innerText || '').trim() === '确定' && btn.offsetParent !== null) { console.log("✅ 自动点击课程完成弹窗的「确定」按钮"); btn.click(); break; } } } // ==================== 你提供的 自动跳下一课 核心逻辑 ==================== const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); const nextCourse = async (element) => { if (!element || !element.innerText.includes('已完成')) return; await sleep(1000); const tmp = element.parentElement?.nextElementSibling; const next_cap = element.parentElement?.parentElement?.parentElement?.nextElementSibling; if (tmp) { console.log("✅ 点击下一节"); tmp.click(); } else if (next_cap) { console.log("✅ 点击下一章节"); next_cap.firstElementChild?.nextElementSibling?.firstElementChild?.click(); } }; // 课程列表页:自动点击未完成课程(纯原生JS) function autoStartUnfinishedCourse() { // 先切换到「未完成」标签 const tabs = document.querySelectorAll('button, div[role="tab"]'); for (const tab of tabs) { if ((tab.innerText || '').trim() === '未完成' && tab.offsetParent !== null) { tab.click(); break; } } // 找未完成课程卡片 const cards = document.querySelectorAll('div[class*="course"], div[class*="card"]'); for (const card of cards) { if ((card.innerText || '').includes('未完成')) { const img = card.querySelector('img'); if (img && img.offsetParent !== null) { console.log("✅ 点击未完成课程卡片"); img.click(); return true; } } } return false; } // 定时检测课程状态 async function startAutoJump() { if (!document.getElementById('autoJump').checked) return; try { const iframe = document.querySelector('.url-course-content')?.contentDocument; if (!iframe) { // 如果没有iframe,说明在课程列表页,直接自动点未完成课程 autoStartUnfinishedCourse(); return; } const active = iframe.querySelector('.active'); if (active) nextCourse(active); } catch (e) {} } // ==================== 主循环 ==================== function mainLoop() { autoCloseFinishModal(); // 先关弹窗 applyVideoConfig(); // 再设置倍速静音 startAutoJump(); // 再自动跳下一课/列表页 } // 按钮 document.getElementById('startBtn').onclick = () => { if (isRunning) return; isRunning = true; keepAwake(); timer = setInterval(mainLoop, 1000); alert("✅ 启动成功:无报错版自动学习"); }; document.getElementById('stopBtn').onclick = () => { isRunning = false; clearInterval(timer); if (wakeLock) wakeLock.release(); alert("⏸️ 已暂停"); }; document.getElementById('closeBtn').onclick = () => { clearInterval(timer); if (wakeLock) wakeLock.release(); uiBox.remove(); style.remove(); alert("❌ 已关闭"); }; // 启动 timer = setInterval(mainLoop, 1000); keepAwake(); console.log("✅ 重庆继续教育无报错终极版加载完成,控制台无报错"); })();