Greasy Fork is available in English.

sophia 考试快速选题

若页面存在 <a id="submitMyMilestone" ...>Submit Milestone</a> 按钮,在页面左上角添加 a、b、c、d 四个红底按钮,点击按钮后勾选对应的 input 元素并为 input 和 label 添加 checked 类,同时处理单选逻辑,通过点击答案选项让 HTML 自动激活保存按钮;在按钮 d 后面添加“手动保存”按钮,点击 a、b、c、d 按钮完成操作后等待 250 毫秒自动点击保存按钮及其父级 div;勾选答案时点击指定 div,点击 a、b、c、d 后对 <div class="question" tabindex="0"> 做两次点击事件

// ==UserScript==
// @name         sophia 考试快速选题
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  若页面存在 <a id="submitMyMilestone" ...>Submit Milestone</a> 按钮,在页面左上角添加 a、b、c、d 四个红底按钮,点击按钮后勾选对应的 input 元素并为 input 和 label 添加 checked 类,同时处理单选逻辑,通过点击答案选项让 HTML 自动激活保存按钮;在按钮 d 后面添加“手动保存”按钮,点击 a、b、c、d 按钮完成操作后等待 250 毫秒自动点击保存按钮及其父级 div;勾选答案时点击指定 div,点击 a、b、c、d 后对 <div class="question" tabindex="0"> 做两次点击事件
// @author       3588
// @match        https://app.sophia.org/spcc/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // 检查页面是否存在指定按钮
    const submitMilestoneButton = document.getElementById('submitMyMilestone');
    if (!submitMilestoneButton) {
        return; // 如果不存在指定按钮,脚本不执行后续操作
    }

    // 创建按钮容器
    const buttonContainer = document.createElement('div');
    buttonContainer.style.position = 'fixed';
    buttonContainer.style.top = '10px';
    buttonContainer.style.left = '10px';
    buttonContainer.style.zIndex = '9999';

    // 定义按钮文本和对应的 input ID 后缀
    const buttonTexts = ['a', 'b', 'c', 'd'];
    for (let i = 0; i < buttonTexts.length; i++) {
        const button = document.createElement('button');
        button.textContent = buttonTexts[i];
        // 设置按钮字体大小为 50px
        button.style.fontSize = '50px';
        button.style.marginRight = '5px';
        button.style.backgroundColor = 'red'; // 设置按钮背景为红色
        button.addEventListener('click', function () {
            const inputId = `answer_cb_${i}`;
            const inputElement = document.getElementById(inputId);
            if (inputElement) {
                // 取消所有选项的勾选和 checked 类
                const allInputs = document.querySelectorAll('input[name="answer_cb"]');
                allInputs.forEach(input => {
                    if (input.id!== inputId) {
                        input.checked = false;
                        input.classList.remove('checked');
                        const label = document.querySelector(`label[for="${input.id}"]`);
                        if (label) {
                            label.classList.remove('checked');
                        }
                    }
                });

                // 模拟点击当前选项来让页面自动处理激活逻辑
                try {
                    inputElement.click();
                } catch (error) {
                    console.error('点击 input 元素时出错:', error);
                }

                // 勾选当前选项并添加 checked 类
                inputElement.checked = true;
                inputElement.classList.add('checked');
                const labelElement = document.querySelector(`label[for="${inputId}"]`);
                if (labelElement) {
                    labelElement.classList.add('checked');
                }

                // 假设要点击的 div 的 XPath,你需要根据实际情况修改
                const divXpath = '/html/body/div[3]/div[2]/div[2]/div[1]/div[2]/div/div/div/div[3]/div[2]/div[3]';
                const divResult = document.evaluate(divXpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
                const targetDiv = divResult.singleNodeValue;
                if (targetDiv) {
                    try {
                        targetDiv.click();
                    } catch (error) {
                        console.error('点击指定 div 时出错:', error);
                    }
                } else {
                    console.error('未找到指定 div');
                }

                // 对 <div class="question" tabindex="0"> 做两次点击事件
                const questionDiv = document.querySelector('div.question[tabindex="0"]');
                if (questionDiv) {
                    for (let j = 0; j < 2; j++) {
                        try {
                            questionDiv.click();
                        } catch (error) {
                            console.error('点击 <div class="question" tabindex="0"> 时出错:', error);
                        }
                    }
                } else {
                    console.error('未找到 <div class="question" tabindex="0">');
                }

                // 等待 250 毫秒后自动点击保存按钮及其父级 div
                setTimeout(() => {
                    // 通过 XPath 查找保存按钮和其父级 div
                    const saveXpath = '/html/body/div[3]/div[2]/div[2]/div[1]/div[2]/div/div/div/div[3]/div[2]/div[1]/button';
                    const saveResult = document.evaluate(saveXpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
                    const saveButton = saveResult.singleNodeValue;
                    const submitDiv = saveButton ? saveButton.parentNode : null;

                    if (saveButton && submitDiv) {
                        try {
                            // 点击保存按钮
                            saveButton.click();

                            // 点击保存按钮的父级 div
                            submitDiv.click();
                        } catch (error) {
                            console.error('点击元素时出错:', error);
                        }
                    } else {
                        console.error('未找到保存按钮或其父级 div');
                    }
                }, 250);
            }
        });
        buttonContainer.appendChild(button);
    }

    // 添加“手动保存”按钮
    const saveCustomButton = document.createElement('button');
    saveCustomButton.textContent = '手动保存';
    saveCustomButton.style.fontSize = '50px';
    saveCustomButton.style.marginRight = '5px';
    saveCustomButton.style.backgroundColor = 'green'; // 设置按钮背景为绿色
    saveCustomButton.addEventListener('click', function () {
        // 通过 XPath 查找保存按钮和其父级 div
        const saveXpath = '/html/body/div[3]/div[2]/div[2]/div[1]/div[2]/div/div/div/div[3]/div[2]/div[1]/button';
        const saveResult = document.evaluate(saveXpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
        const saveButton = saveResult.singleNodeValue;
        const submitDiv = saveButton ? saveButton.parentNode : null;

        if (saveButton && submitDiv) {
            try {
                // 点击保存按钮
                saveButton.click();

                // 点击保存按钮的父级 div
                submitDiv.click();
            } catch (error) {
                console.error('点击元素时出错:', error);
            }
        } else {
            console.error('未找到保存按钮或其父级 div');
        }
    });
    buttonContainer.appendChild(saveCustomButton);

    // 将按钮容器添加到页面
    document.body.appendChild(buttonContainer);
})();