// ==UserScript==
// @name 电子科技中山学院
// @namespace http://tampermonkey.net/
// @version 1.7
// @description 自动答题并在有参考答案页面记录到题库,支持单选题、多选题和判断题
// @match *://*.wencaischool.net/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_listValues
// @grant GM_deleteValue
// @grant unsafeWindow
// ==/UserScript==
(function() {
'use strict';
console.log('文才答题助手脚本开始加载...');
// 题库存储键名
const QUESTION_DB_KEY = 'wencai_question_database';
// 面板显示状态存储键名
const PANEL_VISIBLE_KEY = 'wencai_panel_visible';
// 初始化题库
let questionDatabase = GM_getValue(QUESTION_DB_KEY, {});
// 初始化面板显示状态(默认显示)
let panelVisible = GM_getValue(PANEL_VISIBLE_KEY, true);
// 配置选项
const config = {
autoAnswer: true, // 是否自动答题
recordToDB: true, // 是否记录到题库
showNotifications: true, // 是否显示通知
answerDelay: 500, // 答题延迟(ms)
debugMode: true // 调试模式 - 打开以便查看问题
};
// 全局变量,用于管理打开的窗口
let currentViewer = null;
let currentESCListener = null;
let controlPanel = null; // 控制面板引用
let toggleIcon = null; // 切换图标引用
// 添加脚本运行标志到window对象,避免重复执行
if (window.wencaiScriptLoaded) {
console.log('脚本已在当前窗口加载,跳过重复执行');
return;
}
window.wencaiScriptLoaded = true;
// 工具函数:提取问题纯文本
function extractQuestionText(element) {
// 从题目元素中提取问题文本
// 查找包含问题的div或table
let questionText = '';
// 尝试从div中提取
const questionDiv = element.querySelector('div[style*="line-height:20px;font-size:10pt"]');
if (questionDiv) {
// 复制div的内容,避免修改原DOM
const tempDiv = questionDiv.cloneNode(true);
// 移除选项表格
const optionTable = tempDiv.querySelector('table[isitemoption="1"]');
if (optionTable) {
optionTable.remove();
}
// 移除参考答案div
const answerDiv = tempDiv.querySelector('div[style*="color:darkred"]');
if (answerDiv) {
answerDiv.remove();
}
// 获取文本
questionText = tempDiv.textContent.trim();
// 清理文本
questionText = questionText.replace(/\[参考答案.*?\]/g, '');
questionText = questionText.replace(/分值:\d+/g, '');
questionText = questionText.replace(/\s+/g, ' ').trim();
} else {
// 尝试从table中提取
const questionTable = element.querySelector('table[isitem="1"]');
if (questionTable) {
const questionTd = questionTable.querySelector('tr:first-child td');
if (questionTd) {
questionText = questionTd.textContent.trim();
questionText = questionText.replace(/\[参考答案.*?\]/g, '');
questionText = questionText.replace(/分值:\d+/g, '');
questionText = questionText.replace(/\s+/g, ' ').trim();
}
}
}
return questionText || null;
}
// 工具函数:提取选项
function extractOptions(element) {
const options = [];
const optionTable = element.querySelector('table[isitemoption="1"]');
if (!optionTable) return options;
// 判断题目类型
const optionType = optionTable.getAttribute('optiontype') || 'radio';
const isCheckbox = optionType === 'checkbox';
const optionRows = optionTable.querySelectorAll('tr');
optionRows.forEach(row => {
const input = row.querySelector('input[type="radio"], input[type="checkbox"]');
const label = row.querySelector('label');
if (input && label) {
options.push({
value: input.value,
text: label.textContent.trim(),
type: input.type
});
}
});
return options;
}
// 工具函数:提取参考答案
function extractCorrectAnswer(element) {
// 从深红色div中提取参考答案
const answerDiv = element.querySelector('div[style*="color:darkred"]');
if (!answerDiv) return null;
const text = answerDiv.textContent;
const match = text.match(/参考答案:([A-Z]+)/);
return match ? match[1] : null;
}
// 判断题目类型
function getQuestionType(element) {
const optionTable = element.querySelector('table[isitemoption="1"]');
if (!optionTable) return 'unknown';
const optionType = optionTable.getAttribute('optiontype');
if (optionType === 'checkbox') {
return 'multiple';
} else if (optionType === 'radio') {
const options = extractOptions(element);
// 判断题通常只有A和B两个选项,且文本为"对"和"错"
if (options.length === 2) {
const optionTexts = options.map(opt => opt.text.toLowerCase());
if ((optionTexts.includes('对') && optionTexts.includes('错')) ||
(optionTexts.includes('正确') && optionTexts.includes('错误')) ||
(optionTexts.includes('是') && optionTexts.includes('否'))) {
return 'judgement';
}
}
return 'single';
}
return 'unknown';
}
// 生成问题指纹(用于唯一标识问题)
function generateQuestionFingerprint(questionText, options, questionType) {
// 基于问题文本、选项和题目类型生成哈希
let content = questionText + questionType;
options.forEach(opt => {
content += opt.value + opt.text.substring(0, 20);
});
// 简单哈希函数
let hash = 0;
for (let i = 0; i < content.length; i++) {
const char = content.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
return hash.toString(36).substring(1);
}
// 记录问题到题库
function recordQuestionToDatabase(questionElement) {
if (!config.recordToDB) return;
const questionText = extractQuestionText(questionElement);
if (!questionText) return;
const options = extractOptions(questionElement);
if (options.length === 0) return;
const correctAnswer = extractCorrectAnswer(questionElement);
if (!correctAnswer) return;
const questionType = getQuestionType(questionElement);
// 生成问题指纹
const fingerprint = generateQuestionFingerprint(questionText, options, questionType);
// 构建问题对象
const questionObj = {
id: fingerprint,
text: questionText,
options: options,
correctAnswer: correctAnswer,
questionType: questionType,
timestamp: new Date().toISOString(),
source: window.location.href
};
// 保存到数据库
if (!questionDatabase[fingerprint]) {
questionDatabase[fingerprint] = questionObj;
GM_setValue(QUESTION_DB_KEY, questionDatabase);
// 更新控制面板的题库数量显示
updateQuestionCount();
if (config.showNotifications) {
showNotification(`已记录新题目: ${questionText.substring(0, 30)}...`);
}
if (config.debugMode) {
console.log('记录到题库:', questionObj);
}
}
return fingerprint;
}
// 从题库获取答案
function getAnswerFromDatabase(questionElement) {
const questionText = extractQuestionText(questionElement);
if (!questionText) return null;
const options = extractOptions(questionElement);
if (options.length === 0) return null;
const questionType = getQuestionType(questionElement);
const fingerprint = generateQuestionFingerprint(questionText, options, questionType);
if (questionDatabase[fingerprint]) {
return questionDatabase[fingerprint].correctAnswer;
}
return null;
}
// 自动答题函数
function autoAnswerQuestion(questionElement) {
if (!config.autoAnswer) return;
let correctAnswer = null;
// 首先尝试从页面提取参考答案
correctAnswer = extractCorrectAnswer(questionElement);
// 如果没有页面答案,从题库查找
if (!correctAnswer) {
correctAnswer = getAnswerFromDatabase(questionElement);
}
// 找到答案则自动选择
if (correctAnswer) {
const questionType = getQuestionType(questionElement);
let answered = false;
if (questionType === 'multiple') {
// 多选题:答案可能是多个字母,如"ABC"
for (let i = 0; i < correctAnswer.length; i++) {
const answerValue = correctAnswer[i];
const checkboxSelector = `input[type="checkbox"][value="${answerValue}"]`;
const checkbox = questionElement.querySelector(checkboxSelector);
if (checkbox && !checkbox.checked) {
checkbox.click();
checkbox.checked = true;
// 触发相关事件
const event = new Event('change', { bubbles: true });
checkbox.dispatchEvent(event);
answered = true;
if (config.debugMode) {
console.log(`已选择答案: ${answerValue}`, checkbox);
}
}
}
} else {
// 单选题或判断题
const radioSelector = `input[type="radio"][value="${correctAnswer}"]`;
const radioButton = questionElement.querySelector(radioSelector);
if (radioButton && !radioButton.checked) {
radioButton.click();
radioButton.checked = true;
// 触发相关事件
const event = new Event('change', { bubbles: true });
radioButton.dispatchEvent(event);
answered = true;
if (config.debugMode) {
console.log(`已选择答案: ${correctAnswer}`, radioButton);
}
}
}
return answered;
}
return false;
}
// 显示通知
function showNotification(message) {
if (!config.showNotifications) return;
// 检查是否已存在通知
const existingNotification = document.querySelector('.wencai-notification');
if (existingNotification) {
existingNotification.remove();
}
// 创建通知元素
const notification = document.createElement('div');
notification.className = 'wencai-notification';
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #4CAF50;
color: white;
padding: 15px;
border-radius: 5px;
z-index: 99999;
font-family: Arial, sans-serif;
font-size: 14px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
animation: fadeInOut 3s ease-in-out;
`;
// 添加CSS动画
if (!document.querySelector('#wencai-notification-style')) {
const style = document.createElement('style');
style.id = 'wencai-notification-style';
style.textContent = `
@keyframes fadeInOut {
0% { opacity: 0; transform: translateY(-20px); }
10% { opacity: 1; transform: translateY(0); }
90% { opacity: 1; transform: translateY(0); }
100% { opacity: 0; transform: translateY(-20px); }
}
`;
document.head.appendChild(style);
}
notification.textContent = message;
document.body.appendChild(notification);
// 3秒后移除
setTimeout(() => {
if (notification.parentNode) {
notification.parentNode.removeChild(notification);
}
}, 3000);
}
// 处理所有题目
function processAllQuestions() {
// 查找所有题目元素
const questionElements = document.querySelectorAll('td[id^="trScore_"], td:has(table[isitem="1"]), td:has(div[style*="line-height:20px;font-size:10pt"])');
if (config.debugMode) {
console.log(`找到 ${questionElements.length} 个题目`);
}
let answeredCount = 0;
let recordedCount = 0;
let singleChoiceCount = 0;
let multipleChoiceCount = 0;
let judgementCount = 0;
questionElements.forEach((element, index) => {
setTimeout(() => {
// 判断题目类型
const questionType = getQuestionType(element);
switch(questionType) {
case 'single':
singleChoiceCount++;
break;
case 'multiple':
multipleChoiceCount++;
break;
case 'judgement':
judgementCount++;
break;
}
// 记录到题库(如果有参考答案)
if (element.querySelector('div[style*="color:darkred"]')) {
const fingerprint = recordQuestionToDatabase(element);
if (fingerprint) recordedCount++;
}
// 自动答题
if (autoAnswerQuestion(element)) {
answeredCount++;
}
// 显示统计
if (index === questionElements.length - 1 && config.showNotifications) {
if (answeredCount > 0 || recordedCount > 0) {
let stats = `处理完成: ${answeredCount}题已答, ${recordedCount}题已记录`;
if (singleChoiceCount > 0 || multipleChoiceCount > 0 || judgementCount > 0) {
stats += ` (单选题:${singleChoiceCount}, 多选题:${multipleChoiceCount}, 判断题:${judgementCount})`;
}
showNotification(stats);
}
}
}, index * config.answerDelay);
});
}
// 更新题目计数
function updateQuestionCount() {
if (controlPanel) {
const viewDbBtn = controlPanel.querySelector('#view-db-btn');
if (viewDbBtn) {
viewDbBtn.innerHTML = `查看题库(${Object.keys(questionDatabase).length})`;
}
}
}
// 添加控制面板
function addControlPanel() {
console.log('开始添加控制面板...');
// 检查是否已存在控制面板
const existingPanel = document.getElementById('wencai-auto-helper');
if (existingPanel) {
console.log('控制面板已存在,移除旧的面板');
existingPanel.remove();
}
const panel = document.createElement('div');
panel.id = 'wencai-auto-helper';
panel.style.cssText = `
position: fixed;
top: 10px;
right: 10px;
background: white;
border: 2px solid #4CAF50;
border-radius: 8px;
padding: 10px;
z-index: 10000;
font-family: Arial, sans-serif;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
min-width: 200px;
display: ${panelVisible ? 'block' : 'none'};
`;
panel.innerHTML = `
文才答题助手 v1.5
×
当前页有 0 题
`;
document.body.appendChild(panel);
controlPanel = panel; // 保存引用
console.log('控制面板已添加到页面');
// 更新题目计数
const questionElements = document.querySelectorAll('td[id^="trScore_"], td:has(table[isitem="1"]), td:has(div[style*="line-height:20px;font-size:10pt"])');
panel.querySelector('#question-count').textContent = questionElements.length;
// 绑定事件
panel.querySelector('#close-panel').addEventListener('click', () => {
console.log('隐藏控制面板');
setPanelVisible(false);
});
panel.querySelector('#auto-answer-checkbox').addEventListener('change', (e) => {
config.autoAnswer = e.target.checked;
console.log('自动答题设置:', config.autoAnswer);
});
panel.querySelector('#record-db-checkbox').addEventListener('change', (e) => {
config.recordToDB = e.target.checked;
console.log('记录题库设置:', config.recordToDB);
});
panel.querySelector('#process-btn').addEventListener('click', () => {
console.log('手动处理题目');
processAllQuestions();
});
panel.querySelector('#view-db-btn').addEventListener('click', () => {
console.log('打开题库查看器');
showDatabaseViewer();
});
// 添加拖拽功能
let isDragging = false;
let offsetX, offsetY;
panel.addEventListener('mousedown', (e) => {
if (e.target.id === 'close-panel' || e.target.tagName === 'INPUT' || e.target.tagName === 'BUTTON') {
return;
}
isDragging = true;
offsetX = e.clientX - panel.getBoundingClientRect().left;
offsetY = e.clientY - panel.getBoundingClientRect().top;
panel.style.cursor = 'move';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
panel.style.left = (e.clientX - offsetX) + 'px';
panel.style.top = (e.clientY - offsetY) + 'px';
panel.style.right = 'auto';
});
document.addEventListener('mouseup', () => {
isDragging = false;
panel.style.cursor = 'default';
});
return panel;
}
// 添加切换图标
function addToggleIcon() {
console.log('添加切换图标...');
// 检查是否已存在切换图标
const existingIcon = document.getElementById('wencai-toggle-icon');
if (existingIcon) {
console.log('切换图标已存在,移除旧的图标');
existingIcon.remove();
}
const icon = document.createElement('div');
icon.id = 'wencai-toggle-icon';
icon.style.cssText = `
position: fixed;
left: 10px;
bottom: 10px;
width: 40px;
height: 40px;
background-color: #4CAF50;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
font-weight: bold;
cursor: pointer;
z-index: 9999;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
transition: all 0.3s ease;
user-select: none;
`;
// 设置图标文本
icon.textContent = '题';
// 添加悬停效果
icon.addEventListener('mouseenter', function() {
this.style.transform = 'scale(1.1)';
this.style.backgroundColor = '#45a049';
});
icon.addEventListener('mouseleave', function() {
this.style.transform = 'scale(1)';
this.style.backgroundColor = '#4CAF50';
});
// 点击事件 - 切换控制面板显示/隐藏
icon.addEventListener('click', function() {
setPanelVisible(!panelVisible);
});
// 右键点击事件 - 显示选项菜单
icon.addEventListener('contextmenu', function(e) {
e.preventDefault();
showIconContextMenu(e.clientX, e.clientY);
});
document.body.appendChild(icon);
toggleIcon = icon; // 保存引用
console.log('切换图标已添加到页面');
// 更新图标提示
updateIconTooltip();
return icon;
}
// 更新图标提示
function updateIconTooltip() {
if (!toggleIcon) return;
// 移除旧提示
toggleIcon.removeAttribute('title');
// 添加新提示
toggleIcon.title = `文才答题助手 (${panelVisible ? '显示' : '隐藏'})\n左键点击:${panelVisible ? '隐藏' : '显示'}面板\n右键点击:更多选项`;
}
// 显示图标右键菜单
function showIconContextMenu(x, y) {
// 移除现有菜单
const existingMenu = document.getElementById('wencai-context-menu');
if (existingMenu) {
existingMenu.remove();
}
const menu = document.createElement('div');
menu.id = 'wencai-context-menu';
menu.style.cssText = `
position: fixed;
left: ${x}px;
top: ${y}px;
background-color: white;
border: 1px solid #ccc;
border-radius: 4px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
z-index: 10010;
min-width: 150px;
font-family: Arial, sans-serif;
font-size: 14px;
`;
menu.innerHTML = `
文才答题助手
`;
// 添加菜单项样式
const style = document.createElement('style');
style.textContent = `
.menu-item {
padding: 8px 12px;
cursor: pointer;
border-bottom: 1px solid #f0f0f0;
}
.menu-item:hover {
background-color: #f0f0f0;
}
.menu-item:last-child {
border-bottom: none;
}
`;
menu.appendChild(style);
document.body.appendChild(menu);
// 绑定菜单项点击事件
menu.querySelectorAll('.menu-item').forEach(item => {
item.addEventListener('click', function() {
const action = this.getAttribute('data-action');
handleContextMenuAction(action);
menu.remove();
});
});
// 点击外部关闭菜单
const closeMenu = function(e) {
if (!menu.contains(e.target)) {
menu.remove();
document.removeEventListener('click', closeMenu);
}
};
// 延迟绑定,避免立即触发
setTimeout(() => {
document.addEventListener('click', closeMenu);
}, 10);
}
// 处理右键菜单操作
function handleContextMenuAction(action) {
switch(action) {
case 'toggle-panel':
setPanelVisible(!panelVisible);
break;
case 'process-questions':
processAllQuestions();
showNotification('正在处理题目...');
break;
case 'view-database':
showDatabaseViewer();
break;
case 'export-database':
exportDatabase();
break;
case 'reset-position':
resetPanelPosition();
break;
case 'show-help':
showHelp();
break;
}
}
// 导出题库
function exportDatabase() {
const dataStr = JSON.stringify(questionDatabase, null, 2);
const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);
const exportFileDefaultName = `wencai_questions_${new Date().toISOString().slice(0,10)}.json`;
const linkElement = document.createElement('a');
linkElement.setAttribute('href', dataUri);
linkElement.setAttribute('download', exportFileDefaultName);
linkElement.click();
showNotification('题库已导出');
}
// 重置面板位置
function resetPanelPosition() {
if (controlPanel) {
controlPanel.style.left = '';
controlPanel.style.top = '';
controlPanel.style.right = '10px';
controlPanel.style.top = '10px';
showNotification('面板位置已重置');
}
}
// 显示帮助
function showHelp() {
alert(`文才答题助手 v1.5 使用帮助:
功能说明:
1. 自动答题:自动选择已知答案的题目
2. 题库记录:记录有参考答案的题目到本地题库
3. 支持题型:单选题、多选题、判断题
使用方法:
1. 左下角图标左键点击:显示/隐藏控制面板
2. 左下角图标右键点击:打开快捷菜单
3. 控制面板可拖拽移动位置
配置选项:
- 自动答题:启用/禁用自动答题功能
- 记录题库:启用/禁用题库记录功能
- 立即处理:手动处理当前页面题目
- 查看题库:查看已记录的题目
注意事项:
1. 题库数据存储在本地,清除浏览器数据会导致题库丢失
2. 建议定期导出题库备份
3. 只记录有参考答案的题目`);
}
// 设置面板显示状态
function setPanelVisible(visible) {
panelVisible = visible;
// 更新面板显示状态
if (controlPanel) {
controlPanel.style.display = visible ? 'block' : 'none';
}
// 更新图标提示
updateIconTooltip();
// 保存状态到本地存储
GM_setValue(PANEL_VISIBLE_KEY, visible);
// 显示通知
if (config.showNotifications) {
showNotification(`控制面板已${visible ? '显示' : '隐藏'}`);
}
console.log(`控制面板${visible ? '显示' : '隐藏'}`);
}
// 关闭数据库查看器
function closeDatabaseViewer() {
if (currentViewer) {
if (currentViewer.parentNode) {
currentViewer.parentNode.removeChild(currentViewer);
}
// 移除ESC事件监听器
if (currentESCListener) {
document.removeEventListener('keydown', currentESCListener);
currentESCListener = null;
}
currentViewer = null;
}
}
// 显示题库查看器
function showDatabaseViewer() {
// 如果已存在查看器,先关闭它
closeDatabaseViewer();
const viewer = document.createElement('div');
currentViewer = viewer;
viewer.id = 'question-db-viewer';
viewer.style.cssText = `
position: fixed;
top: 50px;
left: 50px;
right: 50px;
bottom: 50px;
background: white;
border: 2px solid #2196F3;
border-radius: 8px;
padding: 20px;
z-index: 10001;
font-family: Arial, sans-serif;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
overflow: auto;
`;
let html = `
题库查看器 (${Object.keys(questionDatabase).length} 题)
`;
// 检查题库是否为空
if (Object.keys(questionDatabase).length === 0) {
html += `
📚
题库是空的
做有参考答案的题目会自动记录到题库
`;
} else {
// 按题目类型分类统计
let singleCount = 0;
let multipleCount = 0;
let judgementCount = 0;
Object.values(questionDatabase).forEach(q => {
switch(q.questionType) {
case 'single': singleCount++; break;
case 'multiple': multipleCount++; break;
case 'judgement': judgementCount++; break;
}
});
html += `
题型统计: 单选题(${singleCount}) | 多选题(${multipleCount}) | 判断题(${judgementCount})
`;
// 添加题库内容
Object.values(questionDatabase).forEach((q, index) => {
const typeBadge = q.questionType === 'single' ? '[单选题]' :
q.questionType === 'multiple' ? '[多选题]' :
q.questionType === 'judgement' ? '[判断题]' : '[未知]';
html += `
${index + 1}. ${typeBadge} ${q.text.substring(0, 100)}${q.text.length > 100 ? '...' : ''}
${q.questionType === 'multiple' ? '多选' : q.questionType === 'judgement' ? '判断' : '单选'}
`;
q.options.forEach(opt => {
let isCorrect = false;
if (q.questionType === 'multiple') {
// 多选题:正确答案可能包含多个字母
isCorrect = q.correctAnswer.includes(opt.value);
} else {
// 单选题或判断题
isCorrect = opt.value === q.correctAnswer;
}
html += `
${opt.value}. ${opt.text} ${isCorrect ? '✓' : ''}
`;
});
html += `
正确答案: ${q.correctAnswer} | 记录时间: ${new Date(q.timestamp).toLocaleString()} |
来源
`;
});
}
html += `
`;
viewer.innerHTML = html;
document.body.appendChild(viewer);
// 绑定事件
const closeViewer = () => closeDatabaseViewer();
viewer.querySelector('#close-viewer-btn').addEventListener('click', closeViewer);
viewer.querySelector('#export-db-btn').addEventListener('click', () => {
exportDatabase();
});
viewer.querySelector('#import-db-btn').addEventListener('click', () => {
const input = document.createElement('input');
input.type = 'file';
input.accept = 'application/json';
input.addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (event) => {
try {
const importedData = JSON.parse(event.target.result);
questionDatabase = { ...questionDatabase, ...importedData };
GM_setValue(QUESTION_DB_KEY, questionDatabase);
// 更新题库数量显示
updateQuestionCount();
// 关闭并重新打开查看器以刷新内容
closeDatabaseViewer();
showDatabaseViewer();
showNotification('题库已导入');
} catch (err) {
alert('导入失败: ' + err.message);
}
};
reader.readAsText(file);
});
input.click();
});
viewer.querySelector('#clear-db-btn').addEventListener('click', () => {
if (confirm('确定要清空题库吗?此操作不可撤销!')) {
questionDatabase = {};
GM_setValue(QUESTION_DB_KEY, {});
// 更新题库数量显示
updateQuestionCount();
// 关闭查看器
closeViewer();
showNotification('题库已清空');
}
});
// ESC键关闭
currentESCListener = function(e) {
if (e.key === 'Escape') {
closeViewer();
}
};
document.addEventListener('keydown', currentESCListener);
// 点击查看器外部关闭
viewer.addEventListener('click', (e) => {
if (e.target === viewer) {
closeViewer();
}
});
}
// 页面加载完成后执行
function init() {
console.log('脚本初始化开始...');
// 等待页面加载完成
if (document.readyState === 'loading') {
console.log('文档加载中,等待DOMContentLoaded事件...');
document.addEventListener('DOMContentLoaded', () => {
console.log('DOMContentLoaded事件触发');
setTimeout(main, 1000);
});
} else {
console.log('文档已加载完成,直接执行main函数');
setTimeout(main, 1000);
}
}
function main() {
console.log('main函数开始执行');
// 添加控制面板
addControlPanel();
console.log('控制面板添加完成');
// 添加切换图标
addToggleIcon();
console.log('切换图标添加完成');
// 自动处理题目
processAllQuestions();
console.log('题目处理完成');
// 监听页面变化(针对动态加载的内容)
const observer = new MutationObserver((mutations) => {
let shouldProcess = false;
mutations.forEach((mutation) => {
if (mutation.addedNodes.length) {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1) {
// 检查是否添加了题目相关的元素
if (node.querySelector?.('table[isitem="1"]') ||
node.querySelector?.('div[style*="line-height:20px;font-size:10pt"]') ||
node.matches?.('td[id^="trScore_"]')) {
shouldProcess = true;
}
}
});
}
});
if (shouldProcess) {
console.log('检测到页面变化,重新处理题目');
setTimeout(() => {
processAllQuestions();
// 更新题目计数
const countElement = document.querySelector('#question-count');
if (countElement) {
const questionElements = document.querySelectorAll('td[id^="trScore_"], td:has(table[isitem="1"]), td:has(div[style*="line-height:20px;font-size:10pt"])');
countElement.textContent = questionElements.length;
}
}, 500);
}
});
// 开始观察
observer.observe(document.body, {
childList: true,
subtree: true
});
console.log('脚本初始化完成');
}
// 启动脚本
console.log('启动脚本...');
init();
})();