校本研修管理平台刷课脚本分享
校本研修管理平台
我是脚本喵,2026年搞这个刷课脚本也有一阵子了。说起来,北京那边的校本研修平台,说实话真的让人头疼。前几天,山东济南的李老师还找我,说他这个平台的视频老是暂停,一换页面就停,刷个课太费劲了。
那天早上我刚喝了碗豆浆,突然想到,是不是可以整个脚本解决这个问题。折腾了好几天,终于搞出来了,分享给大家。
这个油猴脚本,专门给校本研修管理平台用的。网址是 https://www.xiaoben365.com/ 。适配奥鹏远程教育的,大家记好网址哈。
脚本功能呢?大概有这些,自动播放课程视频,解除那个烦人得视频暂停限制。还有哦,页面切换了也不会让学习中断。各种播放异常也能自动处理,智能盯着学习进度,倍速播放也支持。
脚本安装地址,暂时下架了哈。代学也可以,闲鱼交易放心哈。
不会用脚本的朋友,别着急,下面有教程,一步步教你咋弄。
提示
如需代学,请联系客服,支持闲鱼交易。

微信联系:yizhituziang

QQ联系:2422270452
- img: /img/weixin.jpg
name: 微信联系:yizhituziang
- img: /img/qq.jpg
name: QQ联系:2422270452
先说一下怎么用哈。
首先,得先装个脚本猫插件,这个是基础,要是之前装过油猴或者脚本猫的,那就可以跳过这步了。推荐用edge浏览器,装插件方便,比谷歌省事儿。
浏览器打开这个网址 https://docs.scriptcat.org/
用edge浏览器哈,点那个"添加到Edge浏览器"

然后点"获取"

右上角会弹个窗口,点"添加扩展"

等个几秒就行,会提示装好了。

然后装刷课脚本,打开安装地址后,点"安装脚本"按钮,弹窗口点"安装",就提示成功了。
装完后,得重新进学习网站,要是之前开了课程页面,刷新一下脚本就生效了,别忘啦。
(function() {
'use strict';
console.log('校本研修管理平台刷课脚本已成功加载');
const config = {
checkInterval: 2000,
debugMode: true,
autoPlay: true,
preventPause: true,
playbackSpeed: 1.5,
autoNext: true
};
let isInitialized = false;
function debug(msg) {
if (config.debugMode) {
console.log('[校本研修脚本]', msg);
}
}
function blockRestrictedEvents() {
const originalAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(event, callback, options) {
const blockedEvents = [
'visibilitychange',
'blur',
'mouseleave',
'pagehide',
'focusout'
];
if (blockedEvents.includes(event)) {
debug('已拦截限制事件: ' + event);
return;
}
return originalAddEventListener.call(this, event, callback, options);
};
debug('事件拦截系统已就绪');
}
function modifyVisibilityState() {
try {
Object.defineProperty(document, 'hidden', {
get: () => false,
configurable: true
});
Object.defineProperty(document, 'visibilityState', {
get: () => 'visible',
configurable: true
});
if (document.msHidden !== undefined) {
Object.defineProperty(document, 'msHidden', {
get: () => false,
configurable: true
});
}
if (document.msVisibilityState !== undefined) {
Object.defineProperty(document, 'msVisibilityState', {
get: () => 'visible',
configurable: true
});
}
debug('页面可见性属性已修改');
} catch (err) {
debug('属性修改失败: ' + err.message);
}
}
function setupWindowProtection() {
window.onblur = null;
window.onfocusout = null;
window.onmouseleave = null;
window.addEventListener('blur', function(e) {
e.stopImmediatePropagation();
e.preventDefault();
return false;
}, true);
window.addEventListener('focusout', function(e) {
e.stopImmediatePropagation();
e.preventDefault();
return false;
}, true);
debug('窗口保护已激活');
}
function handleVideoElement(video) {
if (!video) return;
video.muted = false;
video.volume = 0.8;
if (video.paused && config.autoPlay) {
video.play().then(() => {
debug('视频开始播放');
}).catch(error => {
debug('播放异常: ' + error);
setTimeout(() => handleVideoElement(video), 2000);
});
}
if (video.playbackRate !== config.playbackSpeed) {
video.playbackRate = config.playbackSpeed;
}
if (config.preventPause) {
video.addEventListener('pause', function() {
debug('检测到暂停,恢复播放');
setTimeout(() => {
if (video.paused) {
video.play();
}
}, 600);
});
}
video.setAttribute('autoplay', 'autoplay');
video.setAttribute('playsinline', '');
}
function scanVideos() {
const videos = document.querySelectorAll('video');
if (videos.length > 0) {
videos.forEach((video, index) => {
debug('处理视频 ' + (index + 1));
handleVideoElement(video);
});
} else {
const iframes = document.querySelectorAll('iframe');
iframes.forEach(iframe => {
try {
const iframeDoc = iframe.contentWindow.document;
const iframeVideos = iframeDoc.querySelectorAll('video');
iframeVideos.forEach(video => handleVideoElement(video));
} catch (e) {
debug('iframe访问失败: ' + e);
}
});
}
}
function closePopups() {
const selectors = [
'.popup',
'.modal',
'.dialog',
'[class*="popup"]',
'[class*="modal"]'
];
selectors.forEach(selector => {
const elements = document.querySelectorAll(selector);
elements.forEach(el => {
const closeBtn = el.querySelector(
'.close, .close-btn, [aria-label*="close"], button'
);
if (closeBtn) {
closeBtn.click();
debug('已关闭弹窗');
} else {
el.style.display = 'none';
el.style.visibility = 'hidden';
}
});
});
}
function setupObserver() {
const observer = new MutationObserver((mutations) => {
let hasNewVideo = false;
mutations.forEach(mutation => {
if (mutation.addedNodes.length > 0) {
hasNewVideo = Array.from(mutation.addedNodes).some(node =>
node.tagName === 'VIDEO' ||
(node.querySelectorAll && node.querySelectorAll('video').length > 0
);
}
});
if (hasNewVideo) {
debug('检测到新视频');
scanVideos();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
debug('DOM观察器已启动');
}
function simulateActivity() {
const actions = ['mousemove', 'keydown'];
setInterval(() => {
const action = actions[Math.floor(Math.random() * actions.length)];
const event = new Event(action, { bubbles: true });
document.dispatchEvent(event);
}, 60000);
debug('用户活动模拟已启动');
}
function findNextButton() {
const buttonSelectors = [
'.next',
'.next-lesson',
'.continue',
'[class*="next"]',
'button:contains("下一节")',
'button:contains("继续")'
];
for (let selector of buttonSelectors) {
const button = document.querySelector(selector);
if (button && button.offsetParent !== null) {
debug('找到下一课按钮');
return button;
}
}
return null;
}
function mainLoop() {
setInterval(() => {
scanVideos();
closePopups();
const nextBtn = findNextButton();
if (nextBtn && config.autoNext) {
debug('准备跳转下一课');
}
}, config.checkInterval);
debug('主循环已启动');
}
function init() {
if (isInitialized) return;
debug('开始初始化脚本...');
blockRestrictedEvents();
modifyVisibilityState();
setupWindowProtection();
setupObserver();
simulateActivity();
mainLoop();
isInitialized = true;
debug('初始化完成!');
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
window.addEventListener('load', function() {
setTimeout(init, 2000);
});
})();