这段油猴(Tampermonkey)脚本是用来提取学习通(Chaoxing)平台上作业和考试题目的个人答案,并将其转换成Excel格式的题库,方便浏览或分享给他人。让我们逐步分析脚本的功能和结构:
脚本功能概述
-
样式插入 (
insertStyle
函数):- 功能:插入自定义的CSS样式,美化题库提取工具的界面。
- 样式包括设置列表无序化、题目容器的样式、logo的样式等。
-
题目展示 (
displayQuestions
函数):- 功能:根据提取的题目数据,将题目和答案显示在浮动框中。
- 使用了模板字符串构建题目列表,展示每道题的题目内容、选项、个人答案和正确答案。
-
Excel下载 (
downloadExcel
函数):- 功能:将提取的题目数据转换为Excel文件并下载。
- 使用了
xlsx.full.min.js
库来实现将数据转换为Excel的功能。
-
界面创建和拖动支持 (
createMenuBox
和setupDraggableBox
函数):createMenuBox
函数:创建了一个浮动的题目显示框,包含标题、解析和下载按钮等。setupDraggableBox
函数:实现了浮动框的拖动功能,使用户可以移动浮动框的位置。
-
题目解析 (
parseQuestions
函数):- 功能:从页面中解析出所有的题目数据,包括题目名称、选项内容、个人答案和正确答案。
- 使用了 DOM 查询和操作来获取并解析每个题目的相关信息,并将解析后的数据存储在
allQsObject
和allStr
中。
-
初始化 (
init
函数):- 功能:初始化整个脚本,包括插入样式、创建界面、设置按钮点击事件等。
- 在初始化过程中,将页面中的题目数据提取并显示,同时设置了解析和下载按钮的点击事件。
注意事项
- 匹配规则 (
@match
和@require
): 脚本通过@match
指定了可以运行的页面地址,确保只在学习通平台相关页面上执行。 - 数据处理: 脚本通过 DOM 操作和字符串处理来提取和展示题目数据,需要保证页面结构和元素的正确性和稳定性。
- Excel导出: 使用了第三方库
xlsx.full.min.js
来处理Excel文件的生成,需要确保网络环境能够正常访问该库。
这段脚本的主要功能是帮助用户将学习通上的作业和考试题目以Excel的形式整理和导出,便于后续分析或分享。
function displayQuestions(qObject) {
let qULs = "";
qObject.forEach(qNode => {
let qLIs = "";
qNode.nodeList.forEach(qItem => {
let qSltString = qItem.slt.map(slt => `<li>${slt}</li>`).join('');
let qLI = `
<li style="padding-left: 5px; margin: 10px 0;">
<div>${qItem.q}</div>
${qSltString}
<div style="color: blue;">${qItem.myAn}</div>
<div style="color: red; text-align: right">${qItem.an}</div>
</li>
`;
qLIs += qLI;
});
let qUL = `<ul style="padding: 0;">${qNode.nodeName}${qLIs}</ul>`;
qULs += qUL;
});
document.getElementById("qList").innerHTML = qULs;
}
function parseQuestions() {
allQsObject = [];
allStr = "";
const nodeBox = document.getElementsByClassName("mark_item");
Array.from(nodeBox).forEach(qNode => {
let node = { nodeName: "", nodeList: [] };
const typeTitle = qNode.querySelector(".type_tit")?.innerText || "";
allStr += `${typeTitle}\n`;
node.nodeName = typeTitle;
const questions = qNode.querySelectorAll(".questionLi");
questions.forEach(question => {
let qItem = { slt: [], q: "", myAn: "", an: "" };
const qName = question.querySelector(".mark_name").innerText;
allStr += `${qName}\n`;
qItem.q = qName;
const qSelectBox = question.querySelector(".mark_letter");
if (qSelectBox) {
const qSelectItems = qSelectBox.getElementsByTagName("li");
Array.from(qSelectItems).forEach(qSelectItem => {
const qSelectText = qSelectItem.innerText;
if (qSelectText) {
allStr += `${qSelectText}\n`;
qItem.slt.push(qSelectText);
}
});
}
try {
const qAnswer = question.querySelector(".mark_answer .colorGreen")?.innerText || "";
const qMyAnswer = question.querySelector(".mark_answer .colorDeep")?.innerText || "";
allStr += `${qMyAnswer}\n${qAnswer}\n`;
qItem.myAn = qMyAnswer;
qItem.an = qAnswer;
} catch (err) {
console.log(err);
}
node.nodeList.push(qItem);
});
allQsObject.push(node);
});
displayQuestions(allQsObject);
}
function init() {
insertStyle();
createMenuBox();
setupDraggableBox();
document.getElementById("qTitle").innerHTML = document.querySelector(".mark_title").innerText;
document.getElementById("jxBtn").onclick = parseQuestions;
document.getElementById("xzBtn").onclick = () => {
const filename = document.querySelector(".mark_title").innerText + ".xlsx";
const data = allQsObject.reduce((arr, qNode) => {
qNode.nodeList.forEach(qItem => {
arr.push({
'题目': qItem.q,
'选项': qItem.slt.join("\n"),
'我的答案': qItem.myAn,
'正确答案': qItem.an
});
});
return arr;
}, []);
downloadExcel(data, filename);
};
}
let allQsObject = [];
let allStr = "";
init();
})();
感兴趣的可以根据以上去完善一下基本能实现了