您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
若页面存在 <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"> 做两次点击事件。新增键盘按键 a,b,c,d 快捷选择对应选项。按钮移至左下角。
// ==UserScript== // @name sophia 考试快速选题 // @namespace http://tampermonkey.net/ // @version 0.3 // @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"> 做两次点击事件。新增键盘按键 a,b,c,d 快捷选择对应选项。按钮移至左下角。 // @author 3588 // @match https://app.sophia.org/spcc/* // @grant none // ==/UserScript== (function () { 'use strict'; // 检查页面是否存在指定按钮 const submitMilestoneButton = document.getElementById('submitMyMilestone'); if (!submitMilestoneButton) { console.log('Sophia Script: "Submit Milestone" button not found. Script will not run.'); return; // 如果不存在指定按钮,脚本不执行后续操作 } console.log('Sophia Script: "Submit Milestone" button found. Initializing script.'); // 创建按钮容器 const buttonContainer = document.createElement('div'); buttonContainer.style.position = 'fixed'; // 修改这里:将按钮定位到左下角 buttonContainer.style.bottom = '10px'; // 原来是 top buttonContainer.style.left = '10px'; buttonContainer.style.zIndex = '9999'; // 确保按钮在最上层 // 定义按钮文本和对应的 input ID 后缀 const buttonDetails = [ { text: 'a', key: 'a', inputIndex: 0 }, { text: 'b', key: 'b', inputIndex: 1 }, { text: 'c', key: 'c', inputIndex: 2 }, { text: 'd', key: 'd', inputIndex: 3 } ]; const choiceButtons = {}; // 用于存储按钮引用,方便键盘事件调用 buttonDetails.forEach(detail => { const button = document.createElement('button'); button.textContent = detail.text; button.id = `sophia_quick_select_${detail.text}`; // 给按钮添加ID,方便键盘事件查找 // 设置按钮字体大小为 50px button.style.fontSize = '50px'; button.style.padding = '10px 20px'; // 增加内边距,使按钮更大更易点击 button.style.marginRight = '10px'; // 增加按钮间距 button.style.backgroundColor = 'red'; // 设置按钮背景为红色 button.style.color = 'white'; // 设置文字颜色为白色,提高对比度 button.style.border = 'none'; // 移除边框 button.style.borderRadius = '5px'; // 添加圆角 button.style.cursor = 'pointer'; // 设置鼠标指针为手型 button.addEventListener('click', function () { console.log(`Sophia Script: Button "${detail.text}" clicked.`); const inputId = `answer_cb_${detail.inputIndex}`; 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'); } } }); // 模拟点击当前选项来让页面自动处理激活逻辑 // 这个 click() 很重要,它会触发 Sophia 页面的内部逻辑来识别答案已被选中 try { console.log(`Sophia Script: Clicking input element: ${inputId}`); inputElement.click(); } catch (error) { console.error('Sophia Script: Error clicking input element:', error); } // 再次确保勾选当前选项并添加 checked 类 (Sophia的click可能不会立即更新checked状态) inputElement.checked = true; inputElement.classList.add('checked'); const labelElement = document.querySelector(`label[for="${inputId}"]`); if (labelElement) { labelElement.classList.add('checked'); } console.log(`Sophia Script: Input ${inputId} and its label should now be checked.`); // 假设要点击的 div 的 XPath,你需要根据实际情况修改 // 注意: XPath 非常脆弱,如果页面结构改变,这里可能会失效 // 建议使用更可靠的选择器,如 ID 或稳定的 class 组合 const divXpath = '/html/body/div[3]/div[2]/div[2]/div[1]/div[2]/div/div/div/div[3]/div[2]/div[3]'; try { const divResult = document.evaluate(divXpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); const targetDiv = divResult.singleNodeValue; if (targetDiv) { console.log('Sophia Script: Found targetDiv by XPath, attempting click.'); targetDiv.click(); } else { console.warn('Sophia Script: Did not find targetDiv by XPath:', divXpath); } } catch (error) { console.error('Sophia Script: Error finding or clicking targetDiv by XPath:', error); } // 对 <div class="question" tabindex="0"> 做两次点击事件 const questionDiv = document.querySelector('div.question[tabindex="0"]'); if (questionDiv) { console.log('Sophia Script: Found questionDiv, attempting two clicks.'); for (let j = 0; j < 2; j++) { try { questionDiv.click(); } catch (error) { console.error('Sophia Script: Error clicking <div class="question" tabindex="0">:', error); } } } else { console.warn('Sophia Script: Did not find <div class="question" tabindex="0">.'); } // 等待 250 毫秒后自动点击保存按钮及其父级 div setTimeout(() => { // 通过 XPath 查找保存按钮和其父级 div // 注意: XPath 非常脆弱 const saveButtonXPath = '/html/body/div[3]/div[2]/div[2]/div[1]/div[2]/div/div/div/div[3]/div[2]/div[1]/button'; let saveButton; try { const saveResult = document.evaluate(saveButtonXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); saveButton = saveResult.singleNodeValue; } catch (error) { console.error('Sophia Script: Error evaluating XPath for save button:', error); } const submitDiv = saveButton ? saveButton.parentNode : null; if (saveButton && submitDiv) { console.log('Sophia Script: Found save button and its parent div. Attempting clicks.'); try { // 点击保存按钮 saveButton.click(); console.log('Sophia Script: Clicked save button.'); // 点击保存按钮的父级 div // submitDiv.click(); // 通常点击按钮本身就足够了,父级div的点击可能不需要或引起意外行为 // console.log('Sophia Script: Clicked parent div of save button.'); } catch (error) { console.error('Sophia Script: Error clicking save button or its parent div:', error); } } else { if (!saveButton) console.warn('Sophia Script: Did not find save button using XPath:', saveButtonXPath); if (saveButton && !submitDiv) console.warn('Sophia Script: Found save button, but it has no parentNode.'); } }, 250); } else { console.warn(`Sophia Script: Input element with ID "${inputId}" not found.`); } }); buttonContainer.appendChild(button); choiceButtons[detail.key] = button; // 存储按钮引用 }); // 添加“手动保存”按钮 const saveCustomButton = document.createElement('button'); saveCustomButton.textContent = '手动保存'; saveCustomButton.style.fontSize = '50px'; saveCustomButton.style.padding = '10px 20px'; saveCustomButton.style.marginRight = '5px'; saveCustomButton.style.backgroundColor = 'green'; // 设置按钮背景为绿色 saveCustomButton.style.color = 'white'; saveCustomButton.style.border = 'none'; saveCustomButton.style.borderRadius = '5px'; saveCustomButton.style.cursor = 'pointer'; saveCustomButton.addEventListener('click', function () { console.log('Sophia Script: "手动保存" button clicked.'); // 通过 XPath 查找保存按钮和其父级 div const saveButtonXPath = '/html/body/div[3]/div[2]/div[2]/div[1]/div[2]/div/div/div/div[3]/div[2]/div[1]/button'; let saveButton; try { const saveResult = document.evaluate(saveButtonXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); saveButton = saveResult.singleNodeValue; } catch (error) { console.error('Sophia Script: Error evaluating XPath for manual save button:', error); } const submitDiv = saveButton ? saveButton.parentNode : null; if (saveButton && submitDiv) { console.log('Sophia Script: Manual save - Found save button and its parent div. Attempting clicks.'); try { // 点击保存按钮 saveButton.click(); console.log('Sophia Script: Manual save - Clicked save button.'); // 点击保存按钮的父级 div // submitDiv.click(); // 如上,可能不需要 // console.log('Sophia Script: Manual save - Clicked parent div of save button.'); } catch (error) { console.error('Sophia Script: Manual save - Error clicking elements:', error); } } else { if (!saveButton) console.warn('Sophia Script: Manual save - Did not find save button using XPath:', saveButtonXPath); if (saveButton && !submitDiv) console.warn('Sophia Script: Manual save - Found save button, but it has no parentNode.'); } }); buttonContainer.appendChild(saveCustomButton); // 将按钮容器添加到页面 document.body.appendChild(buttonContainer); console.log('Sophia Script: Buttons added to page.'); // 添加键盘快捷键监听 document.addEventListener('keydown', function(event) { // 防止在输入框或文本区域中触发快捷键 if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA' || event.target.isContentEditable) { return; } const key = event.key.toLowerCase(); // 获取按下的键,并转换为小写 if (choiceButtons[key]) { console.log(`Sophia Script: Keyboard shortcut "${key}" pressed.`); event.preventDefault(); // 阻止可能的默认浏览器行为 (例如,'a' 可能用于快速查找) choiceButtons[key].click(); // 模拟点击对应的按钮 } }); console.log('Sophia Script: Keyboard listener added.'); })();