🏠 

Greasy Fork is available in English.

超星 - 阅读任务显示已读时间

不要停下来啊!(指阅读)


安装此脚本?
// ==UserScript==
// @name        超星 - 阅读任务显示已读时间
// @description 不要停下来啊!(指阅读)
// @namespace   UnKnown
// @author      UnKnown
// @icon        https://imgsrc.baidu.com/forum/pic/item/6a63f6246b600c33c3d714d61c4c510fd9f9a106.jpg
// @version     1.1
// @match       https://*.chaoxing.com/course/*.html
// @grant       GM_getValue
// @grant       GM_setValue
// @inject-into page
// @run-at      document-start
// ==/UserScript==
const css = `
#top,
#readTime {
opacity: .9;
transition:
opacity 150ms ease-in-out,
filter   75ms ease-out;
}
#top:hover,
#readTime {
opacity: 1;
}
#top:active {
filter: brightness(1.5);
}
#readTime {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
right: 85px;
bottom: 150px;
width: 0;
overflow: visible;
white-space: nowrap;
}
#readTime > span {
padding: 1ex 1ch;
color: white;
background-color: #212121;
border-radius: 2px;
box-shadow:
0px 3px 1px -2px rgba(0, 0, 0, 0.2),
0px 2px 2px 0px rgba(0, 0, 0, 0.14),
0px 1px 5px 0px rgba(0, 0, 0, 0.12);
}
`.trim();
const sendLogs = function (para, url) {
/*
var para = {
courseid : courseid,
chapterid : chapterid,
height : document.getElementById("courseMainBox").clientHeight,
}
if (from != null && from != "") { p._from_ = from; }
if (rtag != null && rtag != "") { p.rtag   = rtag; }
var url = "/multimedia/readlog"
*/
// 多功能随机取整函数
/* 当 extra 存在时,范围为 base ~ base + extra
extra 不存在时,范围为 base ~ base * 2 */
var roll = function (base, extra) {
return Math.round(
base + Math.random() * ( extra || base )
);
};
// 发送频率
var interval = 5000;
var intervalInSecond = interval / 1000;
// 发送概率
var probability = 0.9;
// 页面边距
var pad = roll(200, 66);
// 滚动参数,之后由 init 函数设置属性
var scroll = {};
var init = function () {
para.h = 0;
// para.height / ( 32 ~ 64 )
scroll.base = para.height / roll(32);
// para.height / ( 16 ~ 32 )
scroll.extra = para.height / roll(16);
};
init();
// 检测并处理参数对象的 chapterid 属性
var setCourseid = function (paramObj) {
if (
// 传入的参数对象 paramObj 拥有 chapterid 属性
paramObj.chapterid &&
// window.courselist 对象存在,且为数组
window.courselist &&
Array.isArray(window.courselist)
) {
for( var i = 0; i < window.courselist.length; i++ ) {
var course     = window.courselist[i];
var coursenext = window.courselist[i + 1];
if (
// coursenext 不存在,
coursenext == undefined || // (
// 或者 coursenext 存在,但是当前滚动高度 paramObj.h
// 的大小在 course.h 和 coursenext.h 之间
course.h <= paramObj.h &&
paramObj.h < coursenext.h // )
) {
// 按照 course.knowledgeid 是否存在,设置 chapterid
paramObj.chapterid =
course && course.knowledgeid || 0;
break;
}
}
}; // return paramObj;
};
var ajax = function (paramObj, baseUrl) {
setCourseid(paramObj);
var xhr = new XMLHttpRequest();
xhr.open(
"GET",
baseUrl + "?" + new URLSearchParams(paramObj).toString(),
true
);
xhr.send(null);
};
ajax(para, url);
// 在右下角显示浏览器本地记录的本次已读时间
// 后面的 time 和 duration 的单位都是秒
var tick;
var top = document.getElementById("top");
if ( top ) {
var toReadableTime = function (time) { // 传入总时长 duration
if (time > 0) {
var result = "";
if (time >= 3600)
result += Math.floor(time / 3600) + " 小时 ";
if (time >= 60)
result += Math.floor(time / 60 % 60) + " 分钟 ";
// if (time >= 0)
result += Math.floor(time % 60) + " 秒";
return result;
} else {
return "0 秒";
}
};
var div = document.createElement("div");
var span = document.createElement("span");
var style = document.createElement("style");
// 总时长
var duration = GM_getValue(para.courseid) || 0;
div.id = "readTime";
span.textContent =  toReadableTime(duration);
style.textContent = css ||
"#readTime { display: flex; justify-content: center; align-items: center;" +
"position: fixed; right: 85px; bottom: 150px; width: 0; overflow: visible;" +
"white-space: nowrap; }" +
"#readTime > span { padding: 1ex 1ch; color: white; background-color: #212121; }";
div.appendChild(span);
div.appendChild(style);
document.body.appendChild(div);
tick = function (time) { // 传入每次增加的时长 intervalInSecond
duration += time;
span.textContent = toReadableTime(duration);
para.courseid && GM_setValue(para.courseid, duration);
};
} else {
tick = function () {};
}
setInterval(
function () {
if ( Math.random() <= probability ) {
para.h += roll( scroll.base, scroll.extra );
if ( para.h > ( para.height + pad ) ) {
init();
}
ajax(para, url);
tick(intervalInSecond);
}
}, interval
);
}
Object.defineProperty(
unsafeWindow, "sendLogs", {
configurable: false,
enumerable: true,
writable: false,
value: sendLogs
}
);