WHU教务成绩刮刮乐

隐藏教务系统成绩,改为紧张刺激的刮刮乐

  1. // ==UserScript==
  2. // @name WHU教务成绩刮刮乐
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2.1
  5. // @description 隐藏教务系统成绩,改为紧张刺激的刮刮乐
  6. // @author lyzlyslyc
  7. // @match http*://jwgl.whu.edu.cn/xtgl/index_initMenu.html*
  8. // @match http*://jwgl.whu.edu.cn/cjcx/cjcx_cxDgXscj.html*
  9. // @icon https://www.whu.edu.cn/favicon.ico
  10. // @resource switchcss https://cdn.bootcdn.net/ajax/libs/bootstrap-switch/3.3.4/css/bootstrap2/bootstrap-switch.min.css
  11. // @grant GM_addStyle
  12. // @grant GM_getResourceText
  13. // @run-at document-start
  14. // @license MIT
  15. // ==/UserScript==
  16. var mouseDown = false;
  17. var observer;
  18. (function() {
  19. 'use strict';
  20.  
  21. //====引入bootstrap-switch=====
  22. //脚本
  23. let script = document.createElement('script');
  24. script.setAttribute('type', 'text/javascript');
  25. script.src = "https://cdn.bootcdn.net/ajax/libs/bootstrap-switch/3.3.4/js/bootstrap-switch.min.js";
  26. document.documentElement.appendChild(script);
  27. //css
  28. let switchcss = GM_getResourceText('switchcss');
  29. GM_addStyle(switchcss);
  30. GM_addStyle(".bootstrap-switch-wrapper{float:right;margin-right:5px;}");
  31.  
  32. //隐藏总GPA
  33. if(location.href.search("cjcx_cxDgXscj.html")!=-1)hideTotalGpaNode();
  34.  
  35. //====初始化====
  36. window.addEventListener("load",()=>{
  37. //====主页初始化====
  38. if(location.href.search("index_initMenu.html")!=-1){
  39. let div_score = document.querySelector("#area_four");
  40. if(div_score!=null)$("#area_four").bind("DOMNodeInserted",function(e){
  41. e.target.querySelectorAll(".fraction.float_r").forEach((item)=>{
  42. item.style.background="#555";
  43. item.innerText="隐藏";
  44. });
  45. });
  46. }
  47. //====查询页初始化====
  48. else if(location.href.search("cjcx_cxDgXscj.html")!=-1){
  49. // 创建观察者对象,检测成绩列表变化
  50. observer = new MutationObserver(function(mutations) {
  51. mutations.forEach(function(mutation) {
  52. //新增列表隐藏信息,修改为刮刮乐
  53. mutation.addedNodes.forEach(hideInfo);
  54. });
  55. });
  56. observer.observe(document.querySelector("#tabGrid > tbody"),{childList:true});
  57. //创建刮刮乐对话框
  58. createScoreDialog();
  59. }
  60. //====添加切换按钮====
  61. let toggle = document.createElement("input");
  62. toggle.id = "hide_switch";
  63. toggle.type = "checkbox";
  64. toggle.style = "float: right;";
  65. document.querySelector("#searchForm > div").append(toggle);
  66. $("#hide_switch").bootstrapSwitch({
  67. onText:"开刮",
  68. offText:"不刮",
  69. state:"true",
  70. onColor:"success",
  71. offColor:"default",
  72. onSwitchChange:(event,state)=>{
  73. if(state==true){
  74. //开始观察
  75. try{
  76. document.querySelector("#tabGrid > tbody").childNodes.forEach(hideInfo);
  77. observer.observe(document.querySelector("#tabGrid > tbody"),{childList:true});
  78. document.querySelector("#div-data > div.col-md-2.col-sm-2 > span").hide();
  79. }
  80. catch(e){
  81. console.log(e);
  82. }
  83. }
  84. else{
  85. try{
  86. //暂停观察
  87. observer.disconnect();
  88. document.querySelector("#tabGrid > tbody").childNodes.forEach(showInfo);
  89. document.querySelector("#div-data > div.col-md-2.col-sm-2 > span").show();
  90. }
  91. catch(e){
  92. console.log(e);
  93. }
  94. }
  95. }
  96. });
  97. });
  98. })();
  99.  
  100. /************************函数部分***********************/
  101.  
  102. //创建刮刮乐模态框
  103. function createScoreDialog(){
  104. let div = document.createElement("div");
  105. div.className = "bootbox modal sl_mod my-modal";
  106. div.tabindex="-1";
  107. div.role="dialog";
  108. div.setAttribute("aria-labelledby","myModalLabel");
  109. div.setAttribute("aria-hidden","true");
  110. div.name = "scoreViewModal";
  111. div.id="scoreViewModal";
  112. div.style="display: hidden;";
  113. div.innerHTML=`
  114. <div class="modal-dialog modal-dialog-reset" style="width: 500px; left:30%; top:30%;">
  115. <div class="modal-content">
  116. <div class="modal-header ui-draggable-handle" style="cursor: move;">
  117. <input type="hidden" name="focusInput">
  118. <button type="button" class="bootbox-close-button btn-sm close bootbox-close" data-dismiss="modal">
  119. <span aria-hidden="true">×</span>
  120. <span class="sr-only">Close</span>
  121. </button>
  122. <h4 class="modal-title">查看成绩详情</h4>
  123. </div>
  124. <div class="modal-body" style="overflow-y: inherit;">
  125. <div class="bootbox-body" style="height:30px;">
  126. <div class="col-md-12 col-sm-12">
  127. <h5 class="dark">
  128. <i class="glyphicon glyphicon-hand-right"></i>
  129. <span class="bigger-120" role="button">课程名称<!-- 课程名称 -->:</span>
  130. <span class="red2" role="button" id="score_class_name"></span>
  131. </h5>
  132. </div>
  133. </div>
  134. <div style="position: relative;height: 300px; width: 400px; margin: auto;">
  135. <canvas width="400" height="300" style="z-index: 0;position: absolute;left: 0px;" id="scoreLayer"></canvas>
  136. <canvas width="400" height="300" style="z-index: 1;position: absolute;left: 0px;" id="maskLayer"></canvas>
  137. </div>
  138. </div>
  139. <div class="modal-footer ui-draggable-handle" style="cursor: move;">
  140. <button id="scoreDlg_btn_cancel" data-bb-handler="cancel" data-loading-text="关 闭" type="button" class="btn btn-sm btn-default" data-dismiss="modal">关 闭</button>
  141. </div>
  142. </div>
  143. </div>`;
  144.  
  145.  
  146. document.querySelector("body").appendChild(div);
  147.  
  148. let cMask = document.getElementById("maskLayer");
  149. let ctxMask = cMask.getContext("2d");
  150.  
  151. //刮刮乐事件
  152. function eventDown(e) {
  153. e.preventDefault();
  154. mouseDown = true;
  155. }
  156.  
  157. function eventUp(e) {
  158. e.preventDefault();
  159. mouseDown = false;
  160. }
  161.  
  162. function eventMove(e) {
  163. e.preventDefault();
  164. if (mouseDown) {
  165. // changedTouches 最近一次触发该事件的手指信息
  166. if (e.changedTouches) {
  167. e = e.changedTouches[e.changedTouches.length - 1];
  168. }
  169. var x = e.offsetX;
  170. var y = e.offsetY;
  171. ctxMask.beginPath();
  172. ctxMask.globalCompositeOperation = "destination-out";
  173. ctxMask.arc(x, y, 10, 0, Math.PI * 3);
  174. ctxMask.fill();
  175. }
  176. }
  177. cMask.addEventListener('touchstart', eventDown);
  178. cMask.addEventListener('touchend', eventUp);
  179. cMask.addEventListener('touchmove', eventMove);
  180. cMask.addEventListener('mousedown', eventDown);
  181. cMask.addEventListener('mouseup', eventUp);
  182. cMask.addEventListener('mousemove', eventMove);
  183. }
  184.  
  185. //显示分数对话框
  186. function showScore(courseName,score){
  187. document.getElementById("score_class_name").innerText=courseName;
  188. $("#scoreViewModal .modal-dialog").draggable({cancel:"canvas"});
  189.  
  190. let cScore = document.getElementById("scoreLayer");
  191. let cMask = document.getElementById("maskLayer");
  192. let ctxScore = cScore.getContext("2d");
  193. let ctxMask = cMask.getContext("2d");
  194.  
  195. ctxScore.font = '200px "Segoe UI"';
  196. ctxScore.textAlign="center";
  197. ctxScore.textBaseline = "middle";
  198. ctxScore.clearRect(0,0,ctxScore.canvas.width,ctxScore.canvas.height);
  199. ctxScore.fillText(score,ctxScore.canvas.width/2,ctxScore.canvas.height/2);
  200.  
  201. ctxMask.fillStyle="lightgray";
  202. ctxMask.globalCompositeOperation = "source-over";
  203. ctxMask.clearRect(0,0,ctxMask.canvas.width,ctxMask.canvas.height);
  204. ctxMask.fillRect(0,0,ctxMask.canvas.width,ctxMask.canvas.height);
  205. $("#scoreViewModal").modal('show');
  206. }
  207.  
  208. //隐藏总GPA节点
  209. function hideTotalGpaNode(){
  210. let totalGpaNode = document.querySelector("#div-data > div.col-md-2.col-sm-2 > span");
  211. if(totalGpaNode==null){
  212. setTimeout(hideTotalGpaNode,50);
  213. return;
  214. }
  215. if(totalGpaNode.querySelector("a")!=null)return;
  216. let gpa = totalGpaNode.innerText.match(/(\d*\.)?\d+/);
  217. if(gpa!=null){
  218. totalGpaNode.gpa = gpa[0];
  219. }
  220. totalGpaNode.hide = hideTotalGpa;
  221. totalGpaNode.show = showTotalGpa;
  222. totalGpaNode.hide();
  223. }
  224.  
  225. //隐藏总GPA
  226. function hideTotalGpa(){
  227. let a = document.createElement("a");
  228. a.className="clj ggl";
  229. a.href="#";
  230. a.innerText="显示";
  231. a.addEventListener("click",()=>{
  232. a.remove();
  233. this.innerText+=this.gpa;
  234. })
  235. this.innerText = this.innerText.replace(this.gpa,"");
  236. this.appendChild(a);
  237. }
  238.  
  239. //显示总GPA
  240. function showTotalGpa(){
  241. let a = this.querySelector("a");
  242. if(a!=null){
  243. a.remove();
  244. this.innerText+=this.gpa;
  245. }
  246. }
  247.  
  248. //隐藏列表项信息
  249. function hideInfo(node){
  250. if(!node.classList.contains("jqgrow"))return;
  251.  
  252. let scoreNode = node.querySelector("[aria-describedby=tabGrid_cj]");
  253. if(!scoreNode.score)scoreNode.score = scoreNode.title;
  254. scoreNode.title="开奖";
  255. scoreNode.course = node.querySelector("[aria-describedby=tabGrid_kcmc]").title;
  256. scoreNode.hide = hideGrade;
  257. scoreNode.show = showGrade;
  258. scoreNode.hide();
  259.  
  260. let gpaNode = node.querySelector("[aria-describedby=tabGrid_jd]");
  261. gpaNode.hide = hideNode;
  262. gpaNode.show = showNode;
  263. gpaNode.hide();
  264.  
  265. let creditNode = node.querySelector("[aria-describedby=tabGrid_xfjd]");
  266. creditNode.hide = hideNode;
  267. creditNode.show = showNode;
  268. creditNode.hide();
  269. }
  270.  
  271. //显示列表项信息
  272. function showInfo(node){
  273. if(!node.classList.contains("jqgrow"))return;
  274. let scoreNode = node.querySelector("[aria-describedby=tabGrid_cj]");
  275. let gpaNode = node.querySelector("[aria-describedby=tabGrid_jd]");
  276. let creditNode = node.querySelector("[aria-describedby=tabGrid_xfjd]");
  277. scoreNode.show();
  278. gpaNode.show();
  279. creditNode.show();
  280. }
  281.  
  282. //隐藏成绩
  283. function hideGrade(){
  284. let a = document.createElement("a");
  285. a.className="clj ggl";
  286. a.href="#";
  287. a.innerText="开奖";
  288. a.addEventListener("click",()=>{
  289. showScore(this.course,this.score);
  290. })
  291. this.innerHTML="";
  292. this.appendChild(a);
  293. }
  294.  
  295. //显示成绩
  296. function showGrade(){
  297. this.innerHTML=this.score;
  298. }
  299.  
  300. //隐藏节点
  301. function hideNode(){
  302. let title = this.title;
  303. let a = document.createElement("a");
  304. a.className="clj ggl";
  305. a.href="#";
  306. a.innerText="显示";
  307. a.addEventListener("click",()=>{
  308. this.innerHTML=title;
  309. })
  310. this.innerHTML="";
  311. this.appendChild(a);
  312. }
  313.  
  314. //显示节点
  315. function showNode(){
  316. this.innerHTML = this.title;
  317. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址