【MOOC】JS脚本|便于复制粘贴中国大学MOOC网站的测试题和选项

运行结果

添加三个按钮,DEL删除多余元素,(刷新复原)
COPY一键复制所有题目和选项的文本至剪切板中,暂不支持图片复制。(不记录正确答案)
鼠标移至文字上方即可显示“复制”、“必应搜索”两个按钮。
DISABLE可以禁用“复制”、“必应搜索”避免影响做题,禁用后将变成ABLE按钮。
可以用"x"关闭按钮,关闭后会变成"s",再次点击按钮会重现。

下图是个GIF图,如果不会动,请右键在新标签页打开它。
在这里插入图片描述

完整代码

GreasyFork链接(可直接安装)

Github:shandianchengzi/mooc-copy-search: 给中国大学生mooc网站删除多余广告、复制全部题目、复制题干或选项、搜索题干或选项、任意视频倍速。

具体代码有点长,就不贴了,下面记录部分实现细节。

可复用的部分

1. 删除指定Class或Id的DOM元素

function delAll(){
    var delClass=["qaCate","m-nav-container","scoreLabel","m-learnhead","m-learnleft","totalScore","u-learn-moduletitle","j-activityBanner","j-activityBanner"],i,j;
    var delId=['j-activityBanner'];
    //注意倒序删除,先删除前面的结点时,js会自动补全dom列表
    for(i=delClass.length-1;i>=0;i--)
    {
        let list=document.getElementsByClassName(delClass[i]);
        for(j=list.length-1;j>=0;j--)
        {
            list[j].remove();
        }
    }
    for(i=delId.length-1;i>=0;i--)
    {
        let dom=document.getElementById(delId[i]);
        dom.remove();
    }
}

2. 在页面上添加按钮并绑定事件、添加css、class

function createAButton(element,value,onclick,css,cla="temp"){
    var Button = document.createElement("input");
    Button.type="button";
    Button.value=value;
    Button.onclick=onclick;
    Button.setAttribute("style",css) ;
    Button.setAttribute("class",cla) ;
    element.appendChild(Button);
    return Button;
}

3. 等待页面加载完成,运行异步函数

async function mainFunc(){
    //code here.
}

(function() {
    'use strict';
    // add mainFunc to onload
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = mainFunc;
    }
    else {
        window.onload = function() {
            oldonload();
            mainFunc();
        }
    }
    // Your code here...
})();

4. 选中某个DOM元素的文本并复制

默认不移除被复制节点

function selectText(element) {
    if (document.createRange) {
        let range = document.createRange();
        range.selectNodeContents(element);
        var selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
    } else {
        alert('none');
    }
}
function copyAll(element,del=0){
    selectText(element);
    if (document.execCommand('copy')) {
        Toast("复制成功",500);
        if(del){
            element.remove();
        }
    }
}

5. 数组去重(ES6支持)

function unique (arr) {
    return Array.from(new Set(arr))
}

6. 递归获得特定Class或者Id的子节点

var childList=[];
function getDeepChildByOrder(limit){
    let copyClass=["position","f-richEditorText","optionPos"],i,j;
    let copyId=[];
    var child=limit.children;
    for(i=0;i<child.length;i++){
        for(j=0;j<copyClass.length;j++){
            if(child[i].className.includes(copyClass[j])){
                childList.push(child[i]);
                //console.log(child[i].innerText);
            }
        }
        for(j=0;j<copyId.length;j++){
            if(child[i].id==copyId[i]){
                childList.push(child[i]);
                //console.log(child[i]);
            }
        }
        if(child[i].children){
            getDeepChildByOrder(child[i]);
        }
    }
}

7. 向DOM元素中追加文本(包括\n换行)

换行用<br>元素实现。

function addTextWithBR(element,str){
	var textNode,i;
	str=str.split(/[\n]/);//分割字符串
	for(i=0;i<str.length;i++){
		textNode=document.createTextNode(str[i]);
    	element.appendChild(textNode);
    	//注:appendChild不能通过重复调用添加两个相同节点
    	//所以最好重新定义一个br节点添加
    	//注2:为保证换行的正确性,最后一个分割字符串末尾不需要加换行
    	if(i!=str.length-1){
			let br=document.createElement('br');
    		element.appendChild(br);
    	}
    }
}

8. Toast实现(轻弹窗)

2025/01/04更新:更新了一下让这个Toast能够支持多行显示。

// Toast function for displaying messages
function Toast(msg, duration) {
  duration = isNaN(duration) ? 3000 : duration;
  var m = document.createElement('div');
  m.innerHTML = msg;
  m.style.fontFamily = 'siyuan';
  m.style.maxWidth = '60%';
  m.style.minWidth = '150px';
  m.style.padding = '0 14px';
  m.style.height = 'auto';
  m.style.color = 'rgb(255, 255, 255)';
  m.style.lineHeight = '1.5';
  m.style.textAlign = 'center';
  m.style.borderRadius = '4px';
  m.style.position = 'fixed';
  m.style.top = '50%';
  m.style.left = '50%';
  m.style.transform = 'translate(-50%, -50%)';
  m.style.zIndex = '999999';
  m.style.background = 'rgba(0, 0, 0, 0.7)';
  m.style.fontSize = '16px';
  document.body.appendChild(m);
  setTimeout(function() {
      m.style.transition = 'opacity 0.5s ease-in';
      m.style.opacity = '0';
      setTimeout(function() {
          document.body.removeChild(m);
      }, 500);
  }, duration);
}

9. sleep函数以及正确使用方式

function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}
async function Func(){
  await sleep(1000);
  console.log('结合async使用就不至于阻塞');
}
Func();

10. forEach不能对空数组遍历

……我刚发现自己的博客丢失内容了……什么时候补一下吧。

以上便是本次代码的所有需求和难点。

本账号所有文章均为原创,欢迎转载,请注明文章出处:https://blog.csdn.net/qq_46106285/article/details/117947943
。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shandianchengzi

谢谢你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值