您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
提前报名所需课程,进入【学习中心】,点击脚本开始按钮。鼠标移到左上角显示控制窗口,移开自动隐藏。
// ==UserScript== // @name 学习教育公需课和专业课视频 // @namespace http://tampermonkey.net/ // @version 1.4 // @description 提前报名所需课程,进入【学习中心】,点击脚本开始按钮。鼠标移到左上角显示控制窗口,移开自动隐藏。 // @author shadow // @match http://sdld.gxk.yxlearning.com/my/learning* // @match http://sdld.gxk.yxlearning.com/learning* // @match https://sdld.zyk.yxlearning.com/my/learning* // @match https://sdld.zyk.yxlearning.com/learning* // @grant GM_getValue // @grant GM_setValue // ==/UserScript== (function () { 'use strict'; const SCRIPT_RUNNING_KEY = 'script_running'; const ORIGIN_URL_KEY = 'script_origin_url'; const MAX_LOG_LINES = 100; // 浮动窗口样式 const styles = ` #floating-window { position: fixed; top: 10px; left: 10px; padding: 10px; background-color: #f0f0f0; border: 1px solid #ccc; box-shadow: 0px 0px 10px rgba(0,0,0,0.1); z-index: 1000; font-family: Arial, sans-serif; } #floating-window button { margin: 5px; } `; // 创建浮动窗口 const createFloatingWindow = () => { const styleElement = document.createElement('style'); styleElement.innerHTML = styles; document.head.appendChild(styleElement); const container = document.createElement('div'); container.id = 'floating-window'; const startButton = document.createElement('button'); startButton.textContent = '开始'; startButton.id = 'start-button'; // container.appendChild(startButton); const pauseButton = document.createElement('button'); pauseButton.textContent = '暂停'; pauseButton.id = 'pause-button'; // container.appendChild(pauseButton); // 创建一个div来容纳按钮 const buttonContainer = document.createElement('div'); buttonContainer.className = 'button-container'; buttonContainer.appendChild(startButton); buttonContainer.appendChild(pauseButton); // 将按钮容器和日志文本区域添加到容器中 container.appendChild(buttonContainer); document.body.appendChild(container); const log = document.createElement('textarea'); log.id = 'log'; log.rows = 5; log.cols = 40; log.readOnly = true; container.appendChild(log); // 鼠标移动到页面左上角时显示浮窗 document.addEventListener('mousemove', (event) => { if (event.clientX < 20 && event.clientY < 20) { // 根据需要调整触发区域大小 container.style.display = 'block'; } }); // 鼠标在浮窗上时不隐藏浮窗 container.addEventListener('mouseenter', () => { container.style.display = 'block'; }); container.addEventListener('mouseleave', () => { container.style.display = 'none'; }); container.style.display = 'none'; return {log, startButton, pauseButton}; }; // 写入日志 const writeLog = (message) => { console.log(message); // 输出到控制台 const timestamp = new Date().toISOString(); const logTextarea = document.getElementById('log'); if (logTextarea) { const lines = logTextarea.value.split('\n'); if (lines.length >= MAX_LOG_LINES) { logTextarea.value = ''; // 清空日志 } logTextarea.value += `[${timestamp}] ${message}` + '\n'; logTextarea.scrollTop = logTextarea.scrollHeight; } }; // 判断当前 URL 是否以特定开头 const isLearningIndexPage = () => { const currentUrl = window.location.href; return currentUrl.startsWith('http://sdld.gxk.yxlearning.com/learning/index') || currentUrl.startsWith('https://sdld.zyk.yxlearning.com/learning/index'); }; // 检查元素是否可见 const isElementVisible = (element) => { if (!(element instanceof HTMLElement)) { throw new Error('参数必须是一个 HTMLElement 对象'); } // 检查元素是否在视口内 const rect = element.getBoundingClientRect(); const inViewport = ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); // 检查元素的 CSS 样式 const style = getComputedStyle(element); return ( inViewport && style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0' ); }; // 脚本功能 let isRunning = false; let initialUrl = ''; // 记录初始url,用于返回 let intervalId = null; let courseLinks; let last_index = -1; const startScript = () => { if (intervalId) return; GM_setValue(SCRIPT_RUNNING_KEY, 'true'); isRunning = true; writeLog('脚本开始运行'); debugger; // 在此位置暂停脚本的执行 intervalId = setInterval(async () => { if (!isLearningIndexPage()) { // 查找并点击内容为【学习中】的a标签 initialUrl = window.location.href GM_setValue(ORIGIN_URL_KEY, initialUrl); const learningLink = Array.from(document.querySelectorAll('a')).find(a => a.textContent.trim() === '学习中'); if (learningLink && isElementVisible(learningLink)) { learningLink.click(); writeLog('点击了内容为【学习中】的标签'); // 等待页面跳转并加载课程链接 await new Promise(resolve => setTimeout(resolve, 2000)); // 查找所有课程链接 courseLinks = Array.from(document.querySelectorAll('div.active[content-index="2"] a[du-click="courseck"]')).filter(isElementVisible); if (courseLinks.length > 0) { writeLog(`找到 ${courseLinks.length} 个可见课程链接`); // 点击当前课程链接 const link = courseLinks[0]; link.click(); writeLog(`点击了课程链接: 1`); // 等待页面跳转并加载视频 await new Promise(resolve => setTimeout(resolve, 2000)); } else { writeLog('未找到任何可见课程链接'); isRunning = false; } } else { writeLog('未找到内容为【学习中】的a标签或该标签不可见'); isRunning = false; } } else { // 检测视频播放完成并检查条件 // writeLog('检测视频播放完成并检查条件'); checkAndClickVideo(); await waitForVideoCompletionAndCheckCondition(); // 增加索引,准备点击下一个课程链接 // 返回到初始 URL window.location.href = initialUrl; writeLog('返回到初始网页'); // 等待返回操作完成 await new Promise(resolve => setTimeout(resolve, 2000)); } if (!isRunning) { writeLog('所有课程链接已处理完毕'); pauseScript() } }, 5000); // 每10秒运行一次 }; const pauseScript = () => { isRunning = false; GM_setValue(SCRIPT_RUNNING_KEY, 'false'); if (intervalId) { clearInterval(intervalId); } intervalId = null; writeLog('脚本已暂停'); }; const checkAndClickVideo = () => { // 循环检测视频列表,若不为100则点击播放 let lst = document.querySelectorAll('div.course-list li.videoLi') // console.log(lst) for (let i = 0; i < lst.length; i++) { let row = lst[i]; let span = row.querySelector('span.badge'); const content = span.textContent.trim(); // console.log(content) if (content !== '100%') { let hasActiveDiv = row.querySelector('div.active') !== null; // writeLog(`未完成:${index},last_index:${last_index}`); if (!hasActiveDiv) { last_index = i; writeLog('点击视频'); row.click() } break } } }; // 等待视频播放完成并检查条件 const waitForVideoCompletionAndCheckCondition = () => { return new Promise((resolve) => { checkCondition(resolve); }); }; // 检查条件 const checkCondition = (callback) => { const spanElement = document.querySelector('span[du-html="sumschedule"]'); if (spanElement) { const content = spanElement.textContent.trim(); if (content === '100.00') { // writeLog('条件满足:span 内容等于 100'); callback(); } else { // writeLog(`条件不满足:span 内容不等于 100 ${content} `); } } else { writeLog('未找到 span 元素'); callback(); } }; // 初始化浮动窗口 const {log, startButton, pauseButton} = createFloatingWindow(); // 绑定按钮事件 startButton.addEventListener('click', startScript); pauseButton.addEventListener('click', pauseScript); // 仅在页面加载完成后显示 window.onload = () => { writeLog('页面加载完成'); isRunning = GM_getValue(SCRIPT_RUNNING_KEY) initialUrl = GM_getValue(ORIGIN_URL_KEY) if (isRunning === 'false') { isRunning = false } writeLog(`isRunning: ${isRunning}`); if (isRunning) { startScript() } }; })();