希赛

希赛页面优化

目前为 2022-10-08 提交的版本。查看 最新版本

// ==UserScript==
// @name               EduCity
// @name:zh-CN         希赛
// @description        Optimize the website of educity.cn.
// @description:zh-CN  希赛页面优化
// @namespace          https://github.com/HaleShaw
// @version            1.3.8
// @author             HaleShaw
// @copyright          2021+, HaleShaw (https://github.com/HaleShaw)
// @license            AGPL-3.0-or-later
// @homepage           https://github.com/HaleShaw/TM-EduCity
// @supportURL         https://github.com/HaleShaw/TM-EduCity/issues
// @contributionURL    https://www.jianwudao.com/
// @icon               https://www.educity.cn/favicon.ico
// @match              https://www.educity.cn/wangxiao2/*
// @match              http://www.educity.cn/wangxiao2/*
// @match              https://uc.educity.cn/personalCenter/studyCenter.html
// @match              https://uc.educity.cn/tiku/testReport.html*
// @match              https://uc.educity.cn/tiku/examinationMode.html*
// @match              https://uc.educity.cn/tiku/examinationModeCopy.html*
// @match              https://wangxiao.xisaiwang.com/*
// @match              https://wangxiao.xisaiwang.com/wangxiao2/*
// @match              https://wangxiao.xisaiwang.com/tiku2/exam*
// @match              https://wangxiao.xisaiwang.com/tiku2/ctjx*
// @compatible	       Chrome
// @grant              GM_addStyle
// @grant              GM_info
// ==/UserScript==

// ==OpenUserJS==
// @author             HaleShaw
// @collaborator       HaleShaw
// ==/OpenUserJS==

(function () {
  "use strict";

  const mainStyle = `
    /* 顶部菜单 */
    div.ecv2_header_tools > div.fl > ul > li:not(:first-child),
    div.ecv2_header_tools > div.fr > :not(:last-child),

    /* Footer */
    .ecv2_footer {
      display: none !important;
    }
  `;

  const zhiBoStyle = `
/* 左上角标题 */
#mainVid > div.vid_head > div.vid_hleft > a:not(:last-child),

/* 右上角“返回旧版、视频课程” */
#mainVid > div.vid_head > div.vid_hright > a,

/* 离线观看 */
#mainVid > div.vid_mid > div.vid_midL > div.vid_midL_top,

/* 右侧笔记、提问 */
#mainVid > div.vid_mid > div.vid_midR > div.vid_midR_tab > div > a:nth-child(2),
#mainVid > div.vid_mid > div.vid_midR > div.vid_midR_tab > div > a:nth-child(3),

/* 鼠标混入视频时的浮标按钮“新建笔记” */
.vid_bj_new,

/* 顶部横条 */
.vid_head {
	display: none !important;
}

.vid_head .vid_hright {
  padding-top: 0 !important;
}

.vid_mid .vid_midL {
  padding: 0 !important;
}

.vid_midR_tab,
.vid_midR_tab > a,
.vid_midR_tab > a > i,
.vid_midR_tab > .vid_midR_ul,
.vid_midR_tab > .vid_midR_ul > a,
.vid_midR_tab > .vid_midR_ul > a > i,
.tabhide .vid_midR{
	width: 28px !important;
}

.tabhide .vid_mid {
  padding-right: 28px;
}
.vid_mid {
	padding-right: 439px;
}

.vid_midR {
	width: 439px;
}

.vid_tab_content {
	padding-bottom: 0;
}

/* 进度条上的时间 */
.time-span {
  margin: 0 10px;
}
`;

  // 错题解析
  const ctjxStyle = `
  /* 顶部图片Header */
  #accountSettingsHeader,

  /* 右上角二维码 */
  div.zt_top_right,

  /* 正确答案与错误答案选项 */
  .analysisAnswer>div.bg-fff.box-shadow.mgt10:first-child,

  /* “查看答案与解析”按钮 */
  #exeModeMsg > div.col-md-4.center.bottomCenter.bp20 > span,

  /* 答案解析中的“笔记”和“提问” */
  div.tknew.doPane.note,
  div.tknew.doPane.question {
    display: none !important;
  }

  /* 选项前的CheckBox */
  div.answerContentList> span.cbox {
    display: inline-block !important;
  }

  /* 标题 */
  .zt_top_zong {-
      height: 50px;
      background: none !important;
  }

  .right-title {
      padding: 0px 20px !important;
      margin-bottom: 0px !important;
  }

  /* 进度条 */
  .jindu_div {
      margin: 5px 0 !important;
  }

  .bp20 {
      padding: 5px !important;
  }

  div.answerList.mgb20 {
    padding: 0 15px 0 25px !important;
    margin-bottom: 0px !important;
  }

  /* 题干 */
  .subject-content {
      padding: 5px 30px !important;
  }

  /* 参考解析 */
  div.analysisAnswer > div {
    padding-bottom: 0px !important;
  }
  `;

  // 考试或练习页面
  const examStyle = `
div.col-md-12 > div > div.zt_top_right,
.lh2 > span,
#accountSettingsHeader,
.center.answerCard,
.pull-right > span:not(:first-child),
.answerTitle,

/* 答案解析中的“笔记”和“提问” */
div.tknew.doPane.note,
div.tknew.doPane.question {
	display: none !important;
}

.zt_top_zong {
	height: 65px !important;
	background: none !important;
}

.bp20 {
	padding: 6px !important;
}

.ISpan {
	margin-bottom: 2px !important;
	margin-right: 0 !important;
}

.subject-content {
	padding: 0px 30px !important;
	background: none !important;
}

.lh2 {
	margin-bottom: 5px !important;
}

.countTime {
	padding: 0 !important;
}

#ztsetWrap > div.bg-fff.box-shadow {
	margin-bottom: 0 !important;
}

/* 顶部标题高度 */
.mgt10 {
	margin-top: 0px !important;
}

.lh2 {
	font-weight: bolder !important;
	color: #337ab7 !important;
	font-size: 1.125em !important;
}

.spanExplain {
	padding: 5px 20px !important;
}

.exBtn {
	margin-top: 5px !important;
}

.answerWrap {
	padding: 0px 30px !important;
}

.mgb20 {
	margin-bottom: 0px !important;
}

.singleR {
    font-size: 16px;
}
`;

  setTimeout(() => { main(); }, 1500);

  function main() {
    logInfo(GM_info.script.name, GM_info.script.version);
    GM_addStyle(mainStyle);

    let url = window.location.href;
    // 个人中心添加播放按钮
    if ("https://uc.educity.cn/personalCenter/studyCenter.html" == url) {
      updatePlayTitle();
    } else if (
      url.startsWith("https://www.educity.cn/wangxiao2") ||
      url.startsWith("http://www.educity.cn/wangxiao2") ||
      url.startsWith('https://wangxiao.xisaiwang.com/wangxiao2/')
    ) {
      // 直播回放调节播放速度
      updateSpeed();
      removeListener();
    } else if (url.startsWith("https://uc.educity.cn/tiku/testReport.html") ||
      url.startsWith("https://wangxiao.xisaiwang.com/tiku2/ctjx")) {
      // 测试报告中,自动填充答案
      GM_addStyle(ctjxStyle);
      addLeftRightKeyListener();
    } else if (
      url.startsWith("https://uc.educity.cn/tiku/examinationModeCopy.html") ||
      url.startsWith("https://uc.educity.cn/tiku/examinationMode.html") ||
      url.startsWith("https://wangxiao.xisaiwang.com/tiku2/exam")
    ) {
      // 添加键盘监听事件,按键答题
      GM_addStyle(examStyle);
      addKeyListener();
    }
  }

  // 个人中心,学习列表添加播放按钮,修改标题描述
  function updatePlayTitle() {
    setTimeout(function () {
      document.getElementById("loadStuWrap").lastElementChild.click();
      setTimeout(function () {
        addPlayBotton();
        adjustDes();
      }, 1000);
    }, 1500);
  }

  // 个人中心,学习列表添加播放按钮
  function addPlayBotton() {
    const urlPrefix = "https://www.educity.cn/courseCenter/zhibo.html?gsver=2&id=";
    if (document.getElementsByClassName("enterStudy")) {
      let spans = document.getElementsByClassName("enterStudy");
      console.log(spans.length);
      for (let i = 0; i < spans.length; i++) {
        let dataId = spans[i].getAttribute("data-id");
        let url = urlPrefix + dataId;
        let aEle = document.createElement("a");
        aEle.setAttribute("href", url);
        aEle.setAttribute("target", "_blank");
        aEle.innerHTML = '<i class="icon_index_login_me inline-block icon-st"> </i>';
        spans[i].parentElement.append(aEle);
        spans[i].style.display = "none";
      }
    }
  }

  // 将描述移动到标题上
  function adjustDes() {
    let titleDivs = document.querySelectorAll("div.cMenuTitle.clearfix");
    for (let i = 0; i < titleDivs.length; i++) {
      let content = "";
      let aEle = titleDivs[i].nextElementSibling.querySelector("h4.panel-title>a");
      if (aEle) {
        content = aEle.innerText;
      }
      let childEle = document.createElement("div");
      childEle.setAttribute("class", "pull-left");
      childEle.innerHTML = "<span>" + content + "</span>";
      titleDivs[i].append(childEle);
      titleDivs[i].nextElementSibling.style.display = "none";
    }
  }

  function updateSpeed() {
    GM_addStyle(zhiBoStyle);

    addRemainingTime();
    addRateButton();
    addRateListener();
    updateSideHeight();
    addPersonalCenter();
  }


  /**
   * 添加倍速按钮
   */
  function addRateButton() {
    if (!$('.pv-rate-select') || $('.pv-rate-select').length == 0) {
      return;
    }
    $('<div data-rate="4">4x</div><div data-rate="3.5">3.5x</div><div data-rate="3">3x</div><div data-rate="2.5">2.5x</div>').insertBefore($('.pv-rate-select').children().eq(0));
  }

  // 获取当前倍速
  function getCurrentRate() {
    let rate = 1.0;
    let rateEle = document.querySelector('button.pv-rate-btn>span');
    if (!rateEle) {
      return rate;
    }
    rate = rateEle.textContent.replace("x", "");

    return rate;
  }

  /**
   * 添加控制播放速度的监听事件,仅用于更新显示当前速度,速度控制通过其他通用三方脚本实现。
   */
  function addRateListener() {
    let rateEle = document.querySelector('button.pv-rate-btn>span');

    document.onkeyup = function (e) {
      var theEvent = e || window.event;
      var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
      if (code == 88) {
        // X,减速
        let rate = getCurrentRate();
        let newRate = (new Number(rate) - new Number(0.1)).toFixed(1);
        let rateStr = newRate + "x";
        rateEle.textContent = rateStr;
        updateRate(rateStr);
      }
      if (code == 67) {
        // C,加速
        let rate = getCurrentRate();
        let newRate = (new Number(rate) + new Number(0.1)).toFixed(1);
        let rateStr = newRate + "x";
        rateEle.textContent = rateStr;
        updateRate(rateStr);
      }
      if (code == 90) {
        // Z,恢复正常速度
        rateEle.textContent = "1x";
        updateRate("1x");
      }
    };
  }

  /**
   * 更新右侧边栏上的播放倍率
   * @param {String} rate 播放倍率
   */
  function updateRate(rate) {
    let rateEle = document.querySelector('span.rateRight');
    if (rateEle) {
      rateEle.textContent = rate;
    } else {
      document.querySelector('.vid_midR_tab').appendChild($(`<span class="rateRight">${rate}</span>`)[0]);
    }
  }

  /**
   * 更新右侧侧边栏高度
   */
  function updateSideHeight() {
    let sideBar = document.querySelector('.vid_midR_tab');
    if (!sideBar) {
      return;
    }
    sideBar.style.height = sideBar.parentElement.previousElementSibling.offsetHeight + 'px';
    document.querySelector('.vid_midR_wrap').style.height = sideBar.parentElement.previousElementSibling.offsetHeight + 'px';
  }

  /**
   * 添加个人中心按钮
   */
  function addPersonalCenter() {
    $('<a href="/ucenter2/personal/index.html" target="_blank">个人中心</a>').insertBefore($('.vid_midR_tab').children().eq(0));
  }


  // 添加键盘监听事件,按键答题
  function addKeyListener() {
    document.onkeyup = function (e) {
      var theEvent = e || window.event;
      var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
      // 	Spacebar. 查看答案解析
      if (code == 32 && document.getElementsByClassName("col-md-4 center bottomCenter bp20")[0]) {
        document.getElementsByClassName("col-md-4 center bottomCenter bp20")[0].click();
      }
      // Left Arrow.
      if (code == 37 && document.getElementsByClassName("col-md-4 center bp20 bLeftWrap")[0]) {
        document.getElementsByClassName("col-md-4 center bp20 bLeftWrap")[0].click();
      }
      // Right Arrow.
      if (code == 39 && document.getElementsByClassName("col-md-4 center bp20 bRightWrap")[0]) {
        document.getElementsByClassName("col-md-4 center bp20 bRightWrap")[0].click();
      }
      // A,1.
      if (code == 49 || code == 65 || code == 97) {
        document.getElementById("slec0A").click();
      }
      // B,2.
      if (code == 50 || code == 66 || code == 98) {
        document.getElementById("slec0B").click();
      }
      // C,3.
      if (code == 51 || code == 67 || code == 99) {
        document.getElementById("slec0C").click();
      }
      // D,4.
      if (code == 52 || code == 68 || code == 100) {
        document.getElementById("slec0D").click();
      }
      // J. 标记
      if (code == 74 && document.getElementsByClassName("bj_icon addBiaoji")[0]) {
        document.getElementsByClassName("bj_icon addBiaoji")[0].click();
        setTimeout(function () {
          if (document.getElementsByClassName("swal-button swal-button--confirm")[0]) {
            document.getElementsByClassName("swal-button swal-button--confirm")[0].click();
            document.getElementsByClassName("col-md-4 center bp20 bRightWrap")[0].click();
          }
        }, 300);
      }
      // J. 取消标记
      if (code == 74 && document.getElementsByClassName("bj_icon cancelBiaoji")[0]) {
        document.getElementsByClassName("bj_icon cancelBiaoji")[0].click();
        setTimeout(function () {
          if (document.getElementsByClassName("swal-button swal-button--confirm")[0]) {
            document.getElementsByClassName("swal-button swal-button--confirm")[0].click();
          }
        }, 300);
      }
      // P.暂停
      if (code == 80 && document.getElementsByClassName("inline-block zanTing")[0]) {
        document.getElementsByClassName("inline-block zanTing")[0].click();
      }
      // P.继续做题
      if (code == 80 && document.getElementsByClassName("swal-button swal-button--confirm")[0] && document.getElementsByClassName("swal-button swal-button--confirm")[0].textContent == '继续做题') {
        document.getElementsByClassName("swal-button swal-button--confirm")[0].click();
      }
    };
  }

  // 添加左右方向键监听事件
  function addLeftRightKeyListener() {
    document.onkeyup = function (e) {
      var theEvent = e || window.event;
      var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
      // Left Arrow.
      if (code == 37 && document.getElementsByClassName("col-md-4 center bp20 bLeftWrap")[0]) {
        document.getElementsByClassName("col-md-4 center bp20 bLeftWrap")[0].click();
      }
      // Right Arrow.
      if (code == 39 && document.getElementsByClassName("col-md-4 center bp20 bRightWrap")[0]) {
        document.getElementsByClassName("col-md-4 center bp20 bRightWrap")[0].click();
      }
    };
  }

  // ---------------------------------------------------
  // 添加剩余时间
  function addRemainingTime() {
    document.querySelector(".pv-time-current").addEventListener(
      "DOMSubtreeModified",
      function () {
        let remainingSeconds = getRemainingSeconds();
        let remainingTime = remainingSeconds > 0 ? formatSeconds(remainingSeconds) : "";
        let realRemainingSeconds = (new Number(remainingSeconds) / new Number(getCurrentRate())).toFixed(0);
        let realRemainingTime = formatSeconds(realRemainingSeconds);
        let overTime = getOverTime(realRemainingSeconds);

        let currentEle = document.querySelector('.pv-time-current');
        if (currentEle) {
          let parent = currentEle.parentElement;

          let remainingTimeSpan = document.querySelector('.pv-time-remaining.time-span');
          if (!remainingTimeSpan) {
            remainingTimeSpan = document.createElement("span");
            remainingTimeSpan.setAttribute("class", "pv-time-remaining time-span");
            parent.append(remainingTimeSpan);
          }
          remainingTimeSpan.textContent = '剩余时间:' + remainingTime;

          let realRemainingTimeSpan = document.querySelector('.pv-time-remaining-real.time-span');
          if (!realRemainingTimeSpan) {
            realRemainingTimeSpan = document.createElement("span");
            realRemainingTimeSpan.setAttribute("class", "pv-time-remaining-real time-span");
            parent.append(realRemainingTimeSpan);
          }
          realRemainingTimeSpan.textContent = '真实剩余时间:' + realRemainingTime;

          let overTimeSpan = document.querySelector('.pv-time-over.time-span');
          if (!overTimeSpan) {
            overTimeSpan = document.createElement("span");
            overTimeSpan.setAttribute("class", "pv-time-over time-span");
            parent.append(overTimeSpan);
          }
          overTimeSpan.textContent = '结束时间:' + overTime;
        }
        document.querySelector('.pv-video-wrap').nextElementSibling.setAttribute("class", "pv-skin-blue pv-video-bottom pv-subtitle-hide pv-show-fullscreen-page pv-base-control pv-first-h pv-first-hh");
      },
      false
    );
  }

  // 获取当前时间
  function getNowSeconds() {
    let nowSeconds = 0;
    let currentEle = document.querySelector('.pv-time-current');
    if (!currentEle) {
      return nowSeconds;
    }

    let nowTime = currentEle.textContent;
    let nowArr = nowTime.split(":");
    if (nowArr.length == 2) {
      nowSeconds = parseInt(nowArr[0]) * 60 + parseInt(nowArr[1]);
    } else if (nowArr.length == 3) {
      nowSeconds = parseInt(nowArr[0]) * 60 * 60 + parseInt(nowArr[1]) * 60 + parseInt(nowArr[2]);
    }

    return nowSeconds;
  }

  // 获取总时长
  function getAllSeconds() {
    let allSeconds = 0;
    let durationEle = document.querySelector(".pv-time-duration");
    if (!durationEle) {
      return allSeconds;
    }

    let allTime = durationEle.textContent;
    let allArr = allTime.split(":");
    if (allArr.length == 2) {
      allSeconds = parseInt(allArr[0]) * 60 + parseInt(allArr[1]);
    } else if (allArr.length == 3) {
      allSeconds = parseInt(allArr[0] * 60 * 60) + parseInt(allArr[1]) * 60 + parseInt(allArr[2]);
    }

    return allSeconds;
  }

  // 获取剩余时间
  function getRemainingSeconds() {
    let allSeconds = getAllSeconds();
    let nowSeconds = getNowSeconds();
    return allSeconds - nowSeconds;
  }

  // 获取结束时间
  function getOverTime(seconds) {
    let timestamp = new Date().getTime() + seconds * 1000;
    return dateFormat('HH:MM:SS', new Date(timestamp));
  }

  // 将秒格式化为时间格式
  function formatSeconds(value) {
    let result = parseInt(value);
    let h =
      Math.floor(result / 3600) < 10 ? "0" + Math.floor(result / 3600) : Math.floor(result / 3600);
    let m =
      Math.floor((result / 60) % 60) < 10
        ? "0" + Math.floor((result / 60) % 60)
        : Math.floor((result / 60) % 60);
    let s = Math.floor(result % 60) < 10 ? "0" + Math.floor(result % 60) : Math.floor(result % 60);

    let res = "";
    if (h !== "00") res += `${h}:`;
    if (m !== "00") res += `${m}:`;
    res += `${s}`;
    return res;
  }

  /**
   * Format date.
   * @param fmt format standard.
   * @param date date.
   * @returns {Time formatted string}
   */
  function dateFormat(fmt, date) {
    let ret;
    let opt = {
      'Y+': date.getFullYear().toString(),
      'm+': (date.getMonth() + 1).toString(),
      'd+': date.getDate().toString(),
      'H+': date.getHours().toString(),
      'M+': date.getMinutes().toString(),
      'S+': date.getSeconds().toString()
    };
    for (let k in opt) {
      ret = new RegExp('(' + k + ')').exec(fmt);
      if (ret) {
        fmt = fmt.replace(
          ret[1],
          ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0')
        );
      }
    }
    return fmt;
  }

  /**
   * Log the title and version at the front of the console.
   * @param {String} title title.
   * @param {String} version script version.
   */
  function logInfo(title, version) {
    console.clear();
    const titleStyle = 'color:white;background-color:#606060';
    const versionStyle = 'color:white;background-color:#1475b2';
    const logTitle = ' ' + title + ' ';
    const logVersion = ' ' + version + ' ';
    console.log('%c' + logTitle + '%c' + logVersion, titleStyle, versionStyle);
  }
})();

QingJ © 2025

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