Greasy Fork

Greasy Fork is available in English.

学习通作业复习助手

为作业添加答题按钮

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         学习通作业复习助手
// @namespace    http://xuanyue1024.net/
// @version      0.8
// @description  为作业添加答题按钮
// @author       竹林听雨
// @match        file:///*.html
// @match        https://mooc1.chaoxing.com/mooc-ans/mooc2/work/view*
// @match        *://*/*.html
// @license MIT
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 等待页面加载完成
    function waitForElement(selector, callback) {
        if (document.querySelector(selector)) {
            callback();
        } else {
            setTimeout(() => waitForElement(selector, callback), 500);
        }
    }

    // 主函数
    function addAnswerButtons() {
        // 添加清除记录按钮
        addClearButton();
        
        // 查找所有题目
        const questions = document.querySelectorAll('.questionLi');
        
        questions.forEach(question => {
            // 检查是否已经添加过按钮
            if (question.querySelector('.custom-answer-buttons')) {
                return;
            }

            // 获取题号并移除对应题号的active类
            const questionId = question.getAttribute('id');
            if (questionId) {
                // 恢复上次的作答记录
                restoreAnswer(question, questionId);
            }

            // 隐藏答案区域
            const answerArea = question.querySelector('.mark_answer');
            if (answerArea) {
                answerArea.style.setProperty('display', 'none', 'important');
            }

            // 创建按钮容器
            const buttonContainer = document.createElement('div');
            buttonContainer.className = 'custom-answer-buttons';
            buttonContainer.style.cssText = 'margin: 10px 0; padding: 10px; background: #f5f5f5; border-radius: 5px;';

            // 添加展示答案按钮
            const showAnswerButton = document.createElement('button');
            showAnswerButton.textContent = '显示答案';
            showAnswerButton.style.cssText = 'margin: 0 5px; padding: 5px 15px; border: 1px solid #ddd; border-radius: 3px; cursor: pointer; background-color: #4CAF50; color: white;';
            showAnswerButton.addEventListener('click', () => toggleAnswer(question));

            // 添加标记按钮
            const markButton = document.createElement('button');
            markButton.textContent = '标记题目';
            markButton.style.cssText = 'margin: 0 5px; padding: 5px 15px; border: 1px solid #ddd; border-radius: 3px; cursor: pointer; background-color: #fff; color: #666;';
            markButton.addEventListener('click', () => toggleMarkQuestion(question, markButton));

            // 先添加显示答案按钮,再添加标记按钮
            buttonContainer.appendChild(showAnswerButton);
            buttonContainer.appendChild(markButton);

            // 获取题目类型
            const titleElement = question.querySelector('.colorShallow');
            if (titleElement) {
                const questionType = titleElement.textContent;
                
                // 为选项添加点击事件
                if (questionType.includes('单选题')) {
                    addSingleChoiceHandlers(question);
                } else if (questionType.includes('判断题')) {
                    addTrueFalseHandlers(question);
                }
            }

            // 在题目内容后插入按钮容器
            const content = question.querySelector('.aiAreaContent');
            if (content) {
                content.appendChild(buttonContainer);
            }

            // 恢复标记状态
            if (questionId) {
                const marks = JSON.parse(localStorage.getItem('questionMarks') || '{}');
                if (marks[questionId]) {
                    markButton.textContent = '取消标记';
                    markButton.style.backgroundColor = '#FFA500';
                    markButton.style.color = '#fff';
                    question.style.backgroundColor = '#FFF3E0';
                    
                    // 恢复题号标记图标
                    const questionNumber = questionId.replace('question', '');
                    const answerSheetItem = document.querySelector(`#answerSheet${questionNumber}`);
                    if (answerSheetItem && !answerSheetItem.querySelector('.mark-icon')) {
                        const markIcon = document.createElement('span');
                        markIcon.className = 'mark-icon';
                        markIcon.innerHTML = '★';
                        markIcon.style.color = '#FF4444';
                        answerSheetItem.appendChild(markIcon);
                    }
                }
            }
        });
    }

    // 为单选题添加点击处理
    function addSingleChoiceHandlers(question) {
        const options = question.querySelectorAll('.mark_letter li');
        options.forEach((option, index) => {
            option.style.cursor = 'pointer';
            option.addEventListener('click', () => selectAnswer(question, index, 'single'));
        });
    }

    // 为判断题添加点击处理
    function addTrueFalseHandlers(question) {
        const options = question.querySelectorAll('.mark_letter li');
        options.forEach((option, index) => {
            option.style.cursor = 'pointer';
            option.addEventListener('click', () => selectAnswer(question, index, 'judge'));
        });
    }

    // 切换显示/隐藏答案
    function toggleAnswer(question) {
        const answerContainer = question.querySelector('.mark_answer');
        if (!answerContainer) return;

        const isHidden = answerContainer.style.display === 'none' || getComputedStyle(answerContainer).display === 'none';
        answerContainer.style.setProperty('display', isHidden ? 'block' : 'none', 'important');

        // 更新按钮文本
        const showAnswerButton = question.querySelector('.custom-answer-buttons button:first-child');
        if (showAnswerButton) {
            showAnswerButton.textContent = isHidden ? '隐藏答案' : '显示答案';
            showAnswerButton.style.backgroundColor = isHidden ? '#f44336' : '#4CAF50';
        }
    }

    // 选择答案
    function selectAnswer(question, index, type) {
        // 获取答案区域的父元素
        const answerContainer = question.querySelector('.mark_answer');
        if (!answerContainer) return;

        // 获取所有选项
        const options = question.querySelectorAll('.mark_letter li');
        
        // 检查是否是重复点击同一个选项
        const isSelected = options[index].style.backgroundColor === 'rgb(240, 240, 240)';
        
        // 获取题目ID
        const questionId = question.getAttribute('id');
        const questionNumber = questionId.replace('question', '');
        const answerSheetItem = document.querySelector(`#answerSheet${questionNumber}`);

        // 如果是重复点击,则取消选择
        if (isSelected) {
            // 重置选项样式
            options[index].style.backgroundColor = '';
            options[index].style.color = '';
            
            // 隐藏答案区域
            answerContainer.style.setProperty('display', 'none', 'important');

            // 移除题号的active类并重置颜色
            if (answerSheetItem) {
                answerSheetItem.classList.remove('active');
                answerSheetItem.style.backgroundColor = '#fff';
                answerSheetItem.style.color = '#6BA9FF';
            }

            // 从localStorage中移除该题的记录
            if (questionId) {
                let answers = JSON.parse(localStorage.getItem('answersRecord') || '{}');
                delete answers[questionId];
                localStorage.setItem('answersRecord', JSON.stringify(answers));
            }

            return;
        }

        // 如果不是重复点击,执行正常的选择逻辑
        if (questionId) {
            saveAnswer(questionId, index, type);
        }

        // 隐藏"我的答案"部分
        const myAnswerSpan = answerContainer.querySelector('.colorDeep.marginRight40.fl');
        const myAnswerText = answerContainer.querySelector('.element-invisible-hidden.colorDeep');
        if (myAnswerSpan) {
            myAnswerSpan.style.display = 'none';
        }
        if (myAnswerText) {
            myAnswerText.style.display = 'none';
        }

        // 隐藏对错标记部分
        const markScore = answerContainer.querySelector('.mark_score');
        if (markScore) {
            markScore.style.display = 'none';
        }

        // 显示答案区域
        answerContainer.style.setProperty('display', 'block', 'important');
            
        // 高亮选中的选项
        options.forEach((option, i) => {
            if (i === index) {
                option.style.backgroundColor = '#f0f0f0';
                option.style.color = '#6C07A2';
            } else {
                option.style.backgroundColor = '';
                option.style.color = '';
            }
        });

        // 更新题号状态
        if (answerSheetItem) {
            answerSheetItem.classList.add('active');
            answerSheetItem.style.backgroundColor = '#BFDAFF';
            answerSheetItem.style.color = '#6BA9FF';
        }
    }

    // 添加清除记录按钮
    function addClearButton() {
        const container = document.querySelector('.fanyaMarking_left');
        if (!container || container.querySelector('.clear-answers-button')) return;

        // 创建按钮容器
        const buttonContainer = document.createElement('div');
        buttonContainer.className = 'clear-buttons-container';
        buttonContainer.style.cssText = 'position: fixed; top: 20px; right: 20px; z-index: 1000; display: flex; gap: 10px;';

        // 清除作答记录按钮
        const clearAnswersButton = document.createElement('button');
        clearAnswersButton.className = 'clear-answers-button';
        clearAnswersButton.textContent = '清除作答记录';
        clearAnswersButton.style.cssText = 'padding: 8px 16px; background-color: #f44336; color: white; border: none; border-radius: 4px; cursor: pointer;';
        clearAnswersButton.addEventListener('click', clearAllAnswers);

        // 清除标记按钮
        const clearMarksButton = document.createElement('button');
        clearMarksButton.className = 'clear-marks-button';
        clearMarksButton.textContent = '清除所有标记';
        clearMarksButton.style.cssText = 'padding: 8px 16px; background-color: #FFA500; color: white; border: none; border-radius: 4px; cursor: pointer;';
        clearMarksButton.addEventListener('click', clearAllMarks);

        // 添加按钮到容器
        buttonContainer.appendChild(clearAnswersButton);
        buttonContainer.appendChild(clearMarksButton);
        container.appendChild(buttonContainer);
    }

    // 清除所有作答记录
    function clearAllAnswers() {
        if (confirm('确定要清除所有作答记录吗?')) {
            localStorage.removeItem('answersRecord');
            // 刷新页面
            window.location.reload();
        }
    }

    // 保存答案
    function saveAnswer(questionId, index, type) {
        let answers = JSON.parse(localStorage.getItem('answersRecord') || '{}');
        answers[questionId] = { index, type };
        localStorage.setItem('answersRecord', JSON.stringify(answers));
    }

    // 恢复答案
    function restoreAnswer(question, questionId) {
        const answers = JSON.parse(localStorage.getItem('answersRecord') || '{}');
        const savedAnswer = answers[questionId];
        
        if (savedAnswer) {
            // 恢复选择
            selectAnswer(question, savedAnswer.index, savedAnswer.type);
            
            // 恢复题号状态
            const questionNumber = questionId.replace('question', '');
            const answerSheetItem = document.querySelector(`#answerSheet${questionNumber}`);
            if (answerSheetItem) {
                answerSheetItem.classList.add('active');
                // 确保颜色正确
                answerSheetItem.style.backgroundColor = '#BFDAFF';
                answerSheetItem.style.color = '#6BA9FF';
            }
        } else {
            // 如果没有保存的答案,移除题号的active类并重置颜色
            const questionNumber = questionId.replace('question', '');
            const answerSheetItem = document.querySelector(`#answerSheet${questionNumber}`);
            if (answerSheetItem) {
                answerSheetItem.classList.remove('active');
                answerSheetItem.style.backgroundColor = '#fff';
                answerSheetItem.style.color = '#6BA9FF';
            }
        }
    }

    // 切换题目标记状态
    function toggleMarkQuestion(question, markButton) {
        const questionId = question.getAttribute('id');
        if (!questionId) return;

        let marks = JSON.parse(localStorage.getItem('questionMarks') || '{}');
        const isMarked = marks[questionId];

        // 获取题号元素
        const questionNumber = questionId.replace('question', '');
        const answerSheetItem = document.querySelector(`#answerSheet${questionNumber}`);

        if (isMarked) {
            // 取消标记
            delete marks[questionId];
            markButton.textContent = '标记题目';
            markButton.style.backgroundColor = '#fff';
            markButton.style.color = '#666';
            question.style.backgroundColor = '';
            if (answerSheetItem) {
                const markIcon = answerSheetItem.querySelector('.mark-icon');
                if (markIcon) {
                    markIcon.remove();
                }
            }
        } else {
            // 添加标记
            marks[questionId] = true;
            markButton.textContent = '取消标记';
            markButton.style.backgroundColor = '#FFA500';
            markButton.style.color = '#fff';
            question.style.backgroundColor = '#FFF3E0';
            if (answerSheetItem) {
                // 添加标记图标
                if (!answerSheetItem.querySelector('.mark-icon')) {
                    const markIcon = document.createElement('span');
                    markIcon.className = 'mark-icon';
                    markIcon.innerHTML = '★';
                    markIcon.style.color = '#FF4444';
                    answerSheetItem.appendChild(markIcon);
                }
            }
        }

        localStorage.setItem('questionMarks', JSON.stringify(marks));
    }

    // 清除所有标记
    function clearAllMarks() {
        if (confirm('确定要清除所有标记吗?')) {
            // 清除localStorage中的标记
            localStorage.removeItem('questionMarks');

            // 移除所有标记图标和样式
            document.querySelectorAll('.mark-icon').forEach(icon => icon.remove());
            document.querySelectorAll('.questionLi').forEach(question => {
                const markButton = question.querySelector('.custom-answer-buttons button:first-child');
                if (markButton) {
                    markButton.textContent = '标记题目';
                    markButton.style.backgroundColor = '#fff';
                    markButton.style.color = '#666';
                }
                question.style.backgroundColor = '';
            });
        }
    }

    // 添加样式
    const style = document.createElement('style');
    style.textContent = `
        /* 通用样式 */
        .mark_letter li,
        .custom-answer-buttons button,
        .questionLi,
        .topicNumber_list li {
            transition: all 0.3s;
        }

        /* 按钮和选项样式 */
        .custom-answer-buttons button:hover,
        .clear-answers-button:hover {
            opacity: 0.9;
        }

        .mark_letter li {
            padding: 5px 10px;
            border-radius: 3px;
            cursor: pointer;
        }

        /* 隐藏元素 */
        .questionLi .mark_answer,
        .mark_answer .colorDeep.marginRight40.fl,
        .mark_answer .element-invisible-hidden.colorDeep {
            display: none !important;
        }

        /* 题号样式 */
        .topicNumber_list li {
            position: relative;
            background-color: #fff !important;
            color: #6BA9FF !important;
        }
        
        .topicNumber_list li.active {
            background-color: #BFDAFF !important;
        }

        /* 标记图标样式 */
        .mark-icon {
            position: static;
            display: inline;
            margin-left: 2px;
            font-size: inherit;
            color: #FF4444 !important;
        }

        /* 清除按钮样式 */
        .clear-answers-button:hover,
        .clear-marks-button:hover {
            opacity: 0.9;
        }

        .clear-answers-button:hover {
            background-color: #d32f2f !important;
        }

        .clear-marks-button:hover {
            background-color: #FF8C00 !important;
        }
    `;
    document.head.appendChild(style);

    // 页面加载完成后添加按钮
    waitForElement('.questionLi', () => {
        addAnswerButtons();
    });
})();