// ==UserScript== // @name 81联聘-批量自动学完助手 v1.2 // @namespace https://github.com/yourname // @version 1.2 // @description 修复稳定性问题,增强错误处理和元素检测 // @author You // @match https://learn.81lianpin.com/myCourses/details/* // @grant none // ==/UserScript== /* 让页面自身的未捕获异常不再抛到控制台(仅视觉清爽,不影响功能) */ window.addEventListener('error', e => { if (e.filename?.includes('index.vue')) e.preventDefault(); }); (() => { 'use strict'; const log = (...a) => console.log('[81批量助手]', ...a); const sleep = t => new Promise(r => setTimeout(r, t)); let isProcessing = false; let isCompletedAlertShown = false; // 用于控制完成提示只显示一次 /* -------------------- 路由 -------------------- */ const onList = () => location.pathname === '/myCourses'; const onChapter = () => location.pathname.includes('/myCourses/details/'); /* -------------------- 面板 -------------------- */ function drawPanel(list) { const old = document.getElementById('lp-helper-panel'); if (old) old.remove(); const box = document.createElement('div'); box.id = 'lp-helper-panel'; box.innerHTML = `

未学完小节(共 ${list.length} 个)

`; document.body.appendChild(box); /* 单独学 */ box.querySelectorAll('.btn:not([id])').forEach(b => { b.onclick = () => handleOne(list[+b.dataset.index]); }); /* 重新扫描 */ box.querySelector('#lp-rescan').onclick = () => { box.remove(); main(); }; } /* -------------------- 单个小节 -------------------- */ async function handleOne(item) { log('进入小节', item.title); // 滚动到元素并点击 item.node.scrollIntoView({ behavior: 'smooth', block: 'center' }); await sleep(800); try { item.node.click(); } catch (e) { log('点击元素失败:', e); // 尝试其他方式触发点击 const event = new MouseEvent('click', { view: window, bubbles: true, cancelable: true }); item.node.dispatchEvent(event); } /* 改进的视频检测机制 */ let video = null; const maxWaitTime = 15000; // 15秒超时 const startTime = Date.now(); while (!video && Date.now() - startTime < maxWaitTime) { video = document.querySelector('video'); if (video) break; await sleep(500); } if (!video) { log('未检测到