#dev
Yet another 自动评教
一年一度的选课又来了。去年写的东西已经不能用了。今年再写一个:
Tampermonkey 脚本在这里
// ==UserScript==
// @name SJTU Auto Evaluator
// @namespace http://tampermonkey.net/
// @version 1.1
// @description Automatically clicks the first radio button ("非常认同") and fills text areas for SJTU teaching evaluations.
// @author You
// @match *://i.sjtu.edu.cn/*
// @match *://*/xspjgl/*
// @match *://*/*xspj*
// @run-at document-end
// @grant none
// ==/UserScript==
(function() {
'use strict';
function injectButton() {
// Prevent duplicate buttons if the script runs multiple times
if (document.getElementById('auto-eval-btn')) return;
if (!document.body) return;
const btn = document.createElement('button');
btn.id = 'auto-eval-btn';
btn.innerText = 'Auto Select All: 非常认同';
Object.assign(btn.style, {
position: 'fixed',
top: '20px',
right: '20px',
zIndex: '999999', // Increased z-index
padding: '10px 15px',
backgroundColor: '#28a745',
color: 'white',
border: 'none',
borderRadius: '5px',
cursor: 'pointer',
fontWeight: 'bold',
boxShadow: '0 2px 5px rgba(0,0,0,0.2)'
});
btn.onclick = function(e) {
e.preventDefault();
let radioCount = 0;
let textCount = 0;
// Target the first option in every metric group
const firstOptions = document.querySelectorAll('.input-xspj-1 input[type="radio"]');
firstOptions.forEach(radio => {
if (!radio.checked) {
radio.click();
radioCount++;
}
});
// Target the required subjective text areas
const textareas = document.querySelectorAll('textarea.input-zgpj');
textareas.forEach(ta => {
if (!ta.value.trim()) {
ta.value = "老师上课十分认真负责,教学内容丰富,非常满意。";
ta.dispatchEvent(new Event('input', { bubbles: true }));
ta.dispatchEvent(new Event('change', { bubbles: true }));
textCount++;
}
});
const originalText = btn.innerText;
btn.innerText = `Done! (${radioCount} options, ${textCount} texts)`;
btn.style.backgroundColor = '#1e7e34';
setTimeout(() => {
btn.innerText = originalText;
btn.style.backgroundColor = '#28a745';
}, 2000);
};
document.body.appendChild(btn);
}
// 1. Try to inject immediately
injectButton();
// 2. Try again after the DOM is fully loaded
window.addEventListener('DOMContentLoaded', injectButton);
// 3. Brute-force fallback for delayed iframe/AJAX rendering
setTimeout(injectButton, 1500);
setTimeout(injectButton, 3000);
})();javascript