您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Calculates the average grade level from the past 10 (or fewer) quizzes available on ReadTheory
// ==UserScript== // @name ReadTheory Average Grade Level Calculator (Past 10 Quizzes) // @namespace https://greasyfork.org/en/users/567951-stuart-saddler // @version 1.6 // @description Calculates the average grade level from the past 10 (or fewer) quizzes available on ReadTheory // @author Stuart Saddler // @icon https://images-na.ssl-images-amazon.com/images/I/41Y-bktG5oL.png // @license MIT // @match http://readtheory.org/app/teacher/reports/* // @grant none // ==/UserScript== (function() { 'use strict'; // Function to convert grade level text to numbers function gradeTextToNumber(gradeText) { const gradeMap = { 'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7, 'eight': 8, 'nine': 9, 'ten': 10, 'eleven': 11, 'twelve': 12 }; return gradeMap[gradeText.toLowerCase().trim()] || 0; // Convert text to lowercase and trim whitespace } // Function to calculate the average of an array of numbers function calculateAverage(grades) { const total = grades.reduce((acc, grade) => acc + grade, 0); return (grades.length > 0) ? (total / grades.length).toFixed(1) : 0; // Rounded to 1 decimal place } // Function to extract grades and display average function calculateAndDisplayAverage() { console.log('Attempting to calculate average grade level...'); // Extract the grade levels from the table by searching for "Grade Level" column header const gradeHeaders = document.querySelectorAll('th'); let gradeColumnIndex = -1; gradeHeaders.forEach((header, index) => { if (header.innerText.toLowerCase().includes('grade level')) { gradeColumnIndex = index + 1; // Get the 1-based index of the column } }); if (gradeColumnIndex === -1) { console.error('Could not find the "Grade Level" column.'); return; } const gradeElements = [...document.querySelectorAll(`tbody td:nth-child(${gradeColumnIndex})`)]; if (gradeElements.length === 0) { console.error('Grade elements not found. Is the table loaded?'); return; } console.log('Found grade elements:', gradeElements); // Extract grades for the last 10 or fewer quizzes const lastGrades = gradeElements.slice(0, 10).map(td => gradeTextToNumber(td.innerText)); console.log('Extracted grade numbers:', lastGrades); // Calculate the average grade level const averageGrade = calculateAverage(lastGrades); console.log('Calculated average grade level:', averageGrade); // Create or update a floating window to display the result let floatingWindow = document.querySelector('#average-grade-floating-window'); if (!floatingWindow) { floatingWindow = document.createElement('div'); floatingWindow.id = 'average-grade-floating-window'; floatingWindow.style.position = 'fixed'; floatingWindow.style.bottom = '100px'; floatingWindow.style.right = '20px'; floatingWindow.style.padding = '10px'; floatingWindow.style.backgroundColor = '#f1f1f1'; floatingWindow.style.border = '2px solid #333'; floatingWindow.style.zIndex = '9999'; floatingWindow.style.boxShadow = '0px 4px 8px rgba(0, 0, 0, 0.1)'; floatingWindow.style.fontSize = '16px'; floatingWindow.style.color = '#333'; document.body.appendChild(floatingWindow); } floatingWindow.innerText = `Average Grade Level (Last ${lastGrades.length} Quizzes): ${averageGrade}`; console.log('Floating window displayed or updated with average grade.'); } // Function to wait for the quiz history table to be available in the DOM function waitForTableAndCalculateAverage() { const observer = new MutationObserver((mutationsList, observer) => { for (const mutation of mutationsList) { if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { const gradeHeader = document.querySelector('th'); if (gradeHeader) { console.log('Quiz history table detected, calculating...'); observer.disconnect(); // Stop observing once the table is detected calculateAndDisplayAverage(); return; } } } }); // Start observing the entire document for changes observer.observe(document.body, { childList: true, subtree: true }); } // Function to monitor the studentid for changes in the quiz history panel function observeStudentIDChange() { const quizPanel = document.querySelector('.quiz-history-panel'); if (quizPanel) { const observer = new MutationObserver((mutationsList, observer) => { for (const mutation of mutationsList) { if (mutation.type === 'attributes' && mutation.attributeName === 'studentid') { console.log('Detected change in studentid, recalculating...'); calculateAndDisplayAverage(); } } }); observer.observe(quizPanel, { attributes: true, attributeFilter: ['studentid'] }); console.log('Started observing changes in studentid attribute.'); } else { console.error('Quiz history panel not found.'); } } // Function to monitor the student dropdown for changes function observeStudentDropdown() { const dropdown = document.querySelector('select'); // Assuming dropdown is a select element if (dropdown) { dropdown.addEventListener('change', () => { console.log('Student dropdown changed, waiting for studentid update...'); setTimeout(() => { observeStudentIDChange(); // Check for studentid updates }, 1000); // Wait 1 second before recalculating to allow time for data load }); console.log('Started observing student dropdown for changes.'); } else { console.error('Student dropdown not found.'); } } // Ensure the page is fully loaded, then start observing window.addEventListener('load', () => { console.log('Page fully loaded, waiting for table...'); waitForTableAndCalculateAverage(); // Recalculate on page load observeStudentDropdown(); // Also watch for student selection changes observeStudentIDChange(); // Watch for studentid changes // NEW LINE ADDED HERE: document.addEventListener('change', event => { if(event.target.tagName === 'SELECT') setTimeout(calculateAndDisplayAverage, 1500); }); }); })();