上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

哥哥们,咨询一个问题。发现脚本执行到视频完成后,就无法获取到页面元素了

[复制链接]
  • TA的每日心情

    2022-3-13 15:56
  • 签到天数: 1 天

    [LV.1]初来乍到

    3

    主题

    10

    回帖

    20

    积分

    助理工程师

    积分
    20
    发表于 6 天前 | 显示全部楼层 | 阅读模式
    本帖最后由 Kinjaz 于 2025-3-20 19:17 编辑

    我想实现一个播放视频完,然后自动下一节的功能,发现脚本执行到视频完成后,就无法获取到页面元素了。
    这种是什么情况? 视频播放的时候是可以获取到对应的元素,在nextVideo方法里就无法获得了,这一点有点百思不得其解了。
    1. nextVideo() {
    2.       plugMain.tipsMsg("视频即将结束,等待下一步操作", { time: 10 * 1000 });

    3.       // 精确选择器方案
    4.       const catalogItem = document.querySelector('li[data-plugin="task-list"]');

    5.       if (catalogItem) {
    6.         // 创建真实点击事件
    7.         catalogItem.click()
    8.       }

    9.       setTimeout(() => {

    10.         // plugMain.showPaidContent(`自动下一集启动失败,免费版本不包含自动换课、无人值守功能,如需使用请安装收费版本`);
    11.       }, 10 * 1000);
    12.     },
    复制代码
    全部代码
    1. // ==UserScript==
    2. // [url=home.php?mod=space&uid=23356]@name[/url]   🌱成教融合平台
    3. // @namespace    http://jb.zhanyc.cn/
    4. // [url=home.php?mod=space&uid=155137]@icon[/url]    https://js.zhanyc.cn/img/js-logo.svg
    5. // @version      1.0
    6. // @description
    7. // [url=home.php?mod=space&uid=49579]@include[/url]    *://*xjtudlc.com*
    8. // @grant       GM_getValue
    9. // @grant       GM_setValue
    10. // @grant       GM_addStyle
    11. // @grant       GM_deleteValue
    12. // @grant       GM_setClipboard
    13. // @grant       GM_registerMenuCommand
    14. // @grant       GM_getResourceURL
    15. // @grant       GM_addValueChangeListener
    16. // @grant       GM_removeValueChangeListener
    17. // @grant       GM_getResourceText
    18. // @grant       window.close
    19. // @run-at      document-body
    20. // @require https://code.jquery.com/jquery-2.2.4.min.js
    21. // @require https://update.greasyfork.org/scripts/498507/1398070/sweetalert2.js
    22. // @antifeature
    23. // @license GPL
    24. // @downloadURL https://update.greasyfork.org/scripts/529590/%F0%9F%8C%B1%E3%80%90%E5%85%8D%E8%B4%B9%E7%89%88%E3%80%91%E6%88%90%E6%95%99%E8%9E%8D%E5%90%88%E5%B9%B3%E5%8F%B0%7C%E8%A5%BF%E5%AE%89%E4%BA%A4%E9%80%9A%E5%A4%A7%E5%AD%A6%E5%AD%A6%E5%8E%86%E7%BB%A7%E7%BB%AD%E6%95%99%E8%82%B2%E6%9C%8D%E5%8A%A1%E5%B9%B3%E5%8F%B0%7C%E5%AD%A6%E4%B9%A0%E7%BB%A7%E7%BB%AD%E6%95%99%E8%82%B2%E5%AD%A6%E4%B9%A0%E7%B3%BB%E7%BB%9F%7C%E6%94%B6%E8%B4%B9%E7%89%88%E6%9C%AC%E8%A7%81%EF%BC%9Ahttps%3Adoczhanyccnpagesc8e852.user.js
    25. // @updateURL https://update.greasyfork.org/scripts/529590/%F0%9F%8C%B1%E3%80%90%E5%85%8D%E8%B4%B9%E7%89%88%E3%80%91%E6%88%90%E6%95%99%E8%9E%8D%E5%90%88%E5%B9%B3%E5%8F%B0%7C%E8%A5%BF%E5%AE%89%E4%BA%A4%E9%80%9A%E5%A4%A7%E5%AD%A6%E5%AD%A6%E5%8E%86%E7%BB%A7%E7%BB%AD%E6%95%99%E8%82%B2%E6%9C%8D%E5%8A%A1%E5%B9%B3%E5%8F%B0%7C%E5%AD%A6%E4%B9%A0%E7%BB%A7%E7%BB%AD%E6%95%99%E8%82%B2%E5%AD%A6%E4%B9%A0%E7%B3%BB%E7%BB%9F%7C%E6%94%B6%E8%B4%B9%E7%89%88%E6%9C%AC%E8%A7%81%EF%BC%9Ahttps%3Adoczhanyccnpagesc8e852.meta.js
    26. // ==/UserScript==
    27. (function () {
    28.   let $jq = $;
    29.   unsafeWindow.$jq = $;
    30.   let baseConfig = {}

    31.   let freeTips = "当前是免费版本,只包含了视频页面自动播放、解除播放暂停限制功能。如需自动下一集、自动换课程、视频页面答题等高级功能,可点击下方按钮查看付费版本"
    32.   let docUrl = "https://doc.zhanyc.cn/pages/yykt/";
    33.   let plugMain = Object.assign(baseConfig, {
    34.     config: {
    35.       maxComment: 100,
    36.     },
    37.     pageData: {
    38.       directoryElement: null,
    39.       userNameIndex: null,
    40.       closeTipsIndex: null,
    41.       confirmRunIndex: null,
    42.       confirmRunZIndex: 19991018,
    43.       waitTime: 0,
    44.       index: {
    45.         list: null,
    46.       },
    47.       video: {
    48.         index: null,
    49.       },
    50.     },
    51.     async init() {

    52.       console.log("%c pg init", "background:rgb(0,0,0);color:#fff");
    53.       var lockResolver;
    54.       if (navigator && navigator.locks && navigator.locks.request) {
    55.         const promise = new Promise((res) => {
    56.           lockResolver = res;
    57.         });

    58.         navigator.locks.request("unique_lock_name", { mode: "shared" }, () => {
    59.           return promise;
    60.         });
    61.       }
    62.       plugMain.addStyle();
    63.       let run = true;
    64.       if (run) plugMain.firstRun();
    65.     },
    66.     async autoNext() {
    67.       await plugMain.waitOf(a => plugMain.getElByText($("a"), '目录') != null)
    68.       plugMain.directoryElement = plugMain.getElByText($("a"), '目录'); // 保存目录元素
    69.       plugMain.confirmRun().then(a => {
    70.         if (plugMain.directoryElement && plugMain.directoryElement.length > 0) {
    71.           plugMain.setGMData("autoNext", plugMain.directoryElement[0]);
    72.           const ml = plugMain.getGMData("autoNext", '')
    73.           console.log(ml)
    74.         }
    75.       })

    76.     },
    77.     async addMenu() {
    78.       await plugMain.waitOf(a => $("body:visible").length > 0)
    79.       if ($("#zfkLeftMenuContainer").length > 0) return;
    80.       GM_addStyle(`#zfkLeftMenuContainer{z-index:9999;position:fixed;left:0;top:40%;color:#fff;box-shadow:0 0 10px #00ffcc,0 0 20px #00ffcc,0 0 30px #00ffcc;animation:glowAnimation 3s infinite alternate;}@keyframes glowAnimation{0%{box-shadow:0 0 10px #00ffcc,0 0 20px #00ffcc,0 0 30px #00ffcc;}20%{box-shadow:0 0 15px #ff66cc,0 0 25px #ff66cc,0 0 35px #ff66cc;}40%{box-shadow:0 0 10px #ffcc33,0 0 20px #ffcc33,0 0 30px #ffcc33;}60%{box-shadow:0 0 15px #66ff66,0 0 25px #66ff66,0 0 35px #66ff66;}80%{box-shadow:0 0 10px #3399ff,0 0 20px #3399ff,0 0 30px #3399ff;}100%{box-shadow:0 0 10px #fffb00,0 0 20px #fffb00,0 0 30px #fffb00;}}#zfkLeftMenuContainer .zfkLeftMenuStep{position:absolute;background:#3498db;width:max-content;top:-35px;display:block;padding:6px}#zfkLeftMenuContainer .zfkLeftMenu{background:rgba(0,0,0,0.4);border-radius:0 4px 4px 0;padding:6px}#zfkLeftMenuContainer .zfkLeftMenu:hover .zfkLeftMenuBtn-titile{width:auto}#zfkLeftMenuContainer .zfkLeftMenu .zfkLeftMenuBtn-titile{cursor:pointer;word-wrap:break-word;width:1em;display:inline-block}#zfkLeftMenuContainer .zfkLeftMenu .zfkLeftMenuBtnUl{display:none;margin:0 -6px;box-sizing:border-box}#zfkLeftMenuContainer .zfkLeftMenu .zfkLeftMenuBtnUl li{list-style:none;color:#fff !important;cursor:pointer;padding:6px}#zfkLeftMenuContainer .zfkLeftMenu .zfkLeftMenuBtnUl li:hover{background:#000}#zfkLeftMenuContainer .zfkLeftMenu .zfkLeftMenuBtnUl li::before{content:"+ "}#zfkIp51Config{padding:10px}#zfkLeftMenuContainer *{font-size:14px}`);
    81.       $(`<div id="zfkLeftMenuContainer">
    82.         <div class="zfkLeftMenu">
    83.           <span class="zfkLeftMenuBtn-titile">菜单</span>
    84.           <ul class="zfkLeftMenuBtnUl">
    85.           </ul>

    86.         </div>
    87.         </div>`).appendTo("body");
    88.       $(".zfkLeftMenu").hover(
    89.         () => {
    90.           $(".zfkLeftMenuBtnUl").show();
    91.         },
    92.         () => {
    93.           $(".zfkLeftMenuBtnUl").hide();
    94.         }
    95.       );
    96.     },
    97.     async runByUrl(url) {

    98.       if (url.includes("/player.html?")) {
    99.         plugMain.page_video();
    100.       } else if (url.includes("/my/course/")) {
    101.         plugMain.page_course();
    102.       } else if (url.includes("/StudentCenter/right.aspx")) {
    103.         // plugMain.showPaidContent(`免费版本不包含自动换课、无人值守功能,如需使用请安装收费版本`);
    104.       } else if (/\/task\/\d+\/activity_show/.test(url) ||
    105.         /testpaper\/result\/\d+\/show/.test(url)
    106.       ) {
    107.         // plugMain.showPaidContent(`免费版本不包含答题功能,如需使用请安装收费版本`);
    108.       } else if (/testpaper\/\d+\/show/.test(url)) {
    109.         // plugMain.showPaidContent(`免费版本不包含答题功能,如需使用请安装收费版本`);
    110.       }



    111.     },
    112.     async page_course() {
    113.       console.log("%c page_course", "background:rgb(0,0,0);color:#fff");
    114.       await plugMain.waitOf(a => plugMain.getElByText($("a"), '继续学习') != null)
    115.       plugMain.confirmRun().then(a => {
    116.         plugMain.getElByText($("a"), '继续学习')[0].click()
    117.       })
    118.     },
    119.     async page_video() {

    120.       plugMain.closeWaitConfrimWin()
    121.       console.log("%c page_video", "background:rgb(0,0,0);color:#fff");
    122.       let timeout = 2;
    123.       let lastTime = null;
    124.       let checkTimeTimesBak = 60;
    125.       let checkTimeTimes = checkTimeTimesBak;
    126.       plugMain.closeWaitConfrimWin();
    127.       if (plugMain.pageData.video.index != null) {
    128.         return;
    129.       }
    130.       plugMain.waitOf(a => typeof (unsafeWindow.player.pause) == 'function').then(a => {
    131.         unsafeWindow.player.pause = () => { }
    132.       })
    133.       plugMain.pageData.video.index = setInterval(async () => {
    134.         try {
    135.           if (plugMain.pageData.waitTime > 0) {
    136.             plugMain.pageData.waitTime -= timeout;
    137.             return;
    138.           }
    139.           if (!plugMain.getVideo()) {
    140.             console.log("%c zfk no video", "background:rgb(0,0,0);color:#fff");
    141.             return;
    142.           }
    143.           let curTime = plugMain.getCurTime();
    144.           if (curTime == lastTime) {
    145.             lastTime = plugMain.getCurTime();
    146.             checkTimeTimes -= timeout;
    147.             if (checkTimeTimes <= 0) {
    148.               checkTimeTimes = checkTimeTimesBak;
    149.               plugMain.confirmRun("貌似卡死了,刷新下页面").then((a) => {
    150.                 // location.reload()
    151.               });
    152.               plugMain.pageData.waitTime = 10;
    153.               return;
    154.             }
    155.           } else {
    156.             lastTime = curTime;
    157.             checkTimeTimes = checkTimeTimesBak;
    158.           }
    159.           plugMain.getVideo().volume = 0;
    160.           let title = `进度:${plugMain.getCurTime().toFixed(0)}/${plugMain
    161.             .getTotalTime()
    162.             .toFixed(0)}`;
    163.           $("title").text(title);

    164.           console.log("%c video run", "background:rgb(255,0,0);color:#fff");

    165.           let isFinish = await plugMain.isPlayFinish();
    166.           if (isFinish) {
    167.             plugMain.pageData.waitTime = 15;

    168.             plugMain.alertMsg("视频即将结束,等待下一步操作", { time: 10 * 1000 });
    169.             // plugMain.pageData.waitTime = plugMain.getTotalTime() - plugMain.getCurTime() + 1;
    170.             plugMain.nextVideo();

    171.             clearInterval(plugMain.pageData.video.index)
    172.             plugMain.pageData.video.index = null
    173.             return;
    174.           }
    175.           let isPlay = await plugMain.videoIsPlay();
    176.           if (!isPlay) {
    177.             if (!isFinish) {
    178.               plugMain.play();
    179.             }
    180.           }
    181.         } catch (e) {
    182.           console.error("视频页面定时器出错", e);
    183.         }
    184.       }, timeout * 1000);
    185.     },
    186.     nextVideo() {
    187.       plugMain.tipsMsg("视频即将结束,等待下一步操作", { time: 10 * 1000 });

    188.       // 精确选择器方案
    189.       const catalogItem = document.querySelector('li[data-plugin="task-list"]');

    190.       if (catalogItem) {
    191.         // 创建真实点击事件
    192.         catalogItem.click()
    193.       }

    194.       setTimeout(() => {

    195.         // plugMain.showPaidContent(`自动下一集启动失败,免费版本不包含自动换课、无人值守功能,如需使用请安装收费版本`);
    196.       }, 10 * 1000);
    197.     },
    198.     firstRun() {
    199.       if (top === window && plugMain.getGMData("showDoc", true)) {
    200.         plugMain.confirmMsg(
    201.           freeTips,
    202.           {
    203.             icon: 3, title: "首次使用?", btn: ["查看付费版本", "继续使用免费版本"],
    204.             fun1: function (index) {
    205.               plugMain.openDoc();
    206.               Swal.close()
    207.               plugMain.setGMData("showDoc", false);
    208.               plugMain.begin("");
    209.             },
    210.             fun2: function () {
    211.               plugMain.setGMData("showDoc", false);
    212.               plugMain.begin("");
    213.             }
    214.           });
    215.       } else {
    216.       }
    217.       plugMain.begin("");
    218.     },
    219.     async begin(key) {
    220.       if (window === top) {
    221.         plugMain.registerMenuCommand();
    222.         plugMain.addMenu()
    223.       }
    224.       // let lastUrl =location.href;

    225.       // setInterval(async () => {
    226.       //   if (lastUrl != location.href) {
    227.       //     lastUrl = location.href;
    228.       //     plugMain.runByUrl(location.href);
    229.       //   }
    230.       // }, 500);
    231.       plugMain.runByUrl(location.href);
    232.     },

    233.     // async showPaidContent(msg = "此页面为付费内容,免费脚本不包含", withPostfix = true) {
    234.     //   if (withPostfix) {
    235.     //     msg += "<span style='font-weight:bold;'>*重要:一个学员付费一次,永久使用,永久更新!</span>"
    236.     //   }
    237.     //   if (!plugMain.pageData.paidIndexArr) {
    238.     //     plugMain.pageData.paidIndexArr = []
    239.     //   }
    240.     //   if (plugMain.pageData.paidIndexArr.length > 0) {
    241.     //     for (let i = 0; i < plugMain.pageData.paidIndexArr.length; i++) {
    242.     //       const index = plugMain.pageData.paidIndexArr[i];
    243.     //       Swal.close()
    244.     //     }
    245.     //   }
    246.     //   Swal.fire({
    247.     //     title: "免费版本提示",
    248.     //     html: `<div style="padding:14px;">${msg}</div>`,
    249.     //     showCancelButton: true,
    250.     //     confirmButtonColor: "#3085d6",
    251.     //     position: "bottom-end",
    252.     //     backdrop: false,
    253.     //     padding: "1em",
    254.     //     cancelButtonColor: "#d33",
    255.     //     confirmButtonText: "查看收费版本"
    256.     //   }).then((result) => {
    257.     //     if (result.isConfirmed) {
    258.     //       plugMain.openDoc()
    259.     //       return false
    260.     //     }
    261.     //   });
    262.     // },
    263.     localSaveQa(qaArr) {
    264.       let list = plugMain.getGMData("qaList", []);
    265.       qaArr.forEach((item) => {
    266.         let old = list.find((a) => a.key == item.key);
    267.         item.value = item.value.replace(/#split#/g, "|");
    268.         if (!old) {
    269.           list.push(item);
    270.         } else {
    271.           old.value = item.value;
    272.         }
    273.       });
    274.       plugMain.setGMData("qaList", list);
    275.     },
    276.     play() {
    277.       plugMain.getVideo().volume = 0;
    278.       setTimeout(() => {
    279.         plugMain.getVideo().play();
    280.       }, 200);
    281.       // });
    282.     },
    283.     setVideoVolume() {
    284.       try {
    285.         if (plugMain.getVideo().volume != 0) {
    286.           plugMain.getVideo().volume = 0;
    287.         }
    288.       } catch (e) {
    289.         console.error(e);
    290.       }
    291.     },
    292.     isPlayFinish() {
    293.       try {
    294.         return (
    295.           plugMain.getTotalTime() > 0 && plugMain.getCurTime() + 5 >= plugMain.getTotalTime()
    296.         );
    297.       } catch (e) {
    298.         return false;
    299.       }
    300.     },
    301.     getVideo() {
    302.       return $("video")[0];
    303.     },
    304.     getCurTime() {
    305.       let res = 0;
    306.       try {
    307.         res = $("video")[0].currentTime;
    308.       } catch (e) {
    309.         console.error(e);
    310.       }
    311.       return res;
    312.     },
    313.     getTotalTime() {
    314.       let res = 0;
    315.       try {
    316.         res = $("video")[0].duration;
    317.       } catch (e) {
    318.         console.error(e);
    319.       }
    320.       return res;
    321.     },
    322.     // 题库方法
    323.     formatAnswerOption(option) {
    324.       // 检查输入是否是单个字母且在 A-Z 范围内
    325.       if (/^[a-zA-Z]$/.test(option)) {
    326.         option = option.toUpperCase();
    327.         return option.charCodeAt(0) - 'A'.charCodeAt(0);
    328.       } else {
    329.         let arr = [
    330.           ["正确", "错误"],
    331.           ["对", "错"],
    332.         ];
    333.         let opt = option.toUpperCase();
    334.         let res = -1;
    335.         arr.forEach((subArr) => {
    336.           if (subArr.includes(opt)) {
    337.             res = subArr.indexOf(opt);
    338.             return false;
    339.           }
    340.         });
    341.         return res;
    342.       }
    343.     },

    344.     // 题库方法
    345.     formatAnswerOptionNo(index) {
    346.       return ["A", "B", "C", "D", "E", "F", "G", "H"][index]
    347.     },
    348.     isMatchQAText(txt1, txt2) {
    349.       return (
    350.         txt1 == txt2 ||
    351.         plugMain.simpleHtml(txt1) == plugMain.simpleHtml(txt2) ||
    352.         plugMain.simpleText(txt1) == plugMain.simpleText(txt2)
    353.       );
    354.     },
    355.     simpleHtml(html) {
    356.       html = html.replace(/&nbsp;|<br\/>|<br>|\n|\r/gi, "");
    357.       html = html.trim();
    358.       if (!html) return html;
    359.       if (html.startsWith("<") && html.endsWith(">")) {
    360.         return $(html).text().trim();
    361.       }
    362.       return html.trim();
    363.     },
    364.     simpleText(text) {
    365.       return text
    366.         .replace(/[^\u4e00-\u9fa5a-zA-Z0-9#split#√×]/g, "")
    367.         .replace(/[的]/g, "");
    368.     },
    369.     async videoIsPlay() {
    370.       return new Promise((resolve) => {
    371.         try {
    372.           let curTime = $("video")[0].currentTime;
    373.           setTimeout(() => {
    374.             let time1 = $("video")[0].currentTime;
    375.             let res = time1 > curTime;
    376.             if (res) {
    377.               setTimeout(() => {
    378.                 let time2 = $("video")[0].currentTime;
    379.                 let res2 = time2 > time1;
    380.                 resolve(res2);
    381.               }, 100);
    382.             } else {
    383.               return resolve(false);
    384.             }
    385.           }, 100);
    386.         } catch (e) {
    387.           resolve(false);
    388.         }
    389.       });
    390.     },
    391.     beginMan() {
    392.       console.log("%c beginMan", "background:rgb(0,0,0);color:#fff");
    393.     },
    394.     stop() {
    395.       location.href = location.href;
    396.     },

    397.     openDoc() {
    398.       if (docUrl) {
    399.         window.open(docUrl);
    400.       } else {
    401.         window.open("http://doc.zhanyc.cn/pages/auth/");
    402.       }
    403.     },
    404.     isDZKFMode() {
    405.       let res = typeof (loadFun) == 'function' && loadFun.toString().includes('var data = res.response;')
    406.       if (!res)
    407.         res = typeof isDZKF == "boolean" && !!isDZKF;
    408.       return res
    409.     },
    410.     async callRegisterMenuCommand(name, fun) {
    411.       if (!plugMain.pageData.menuBtnIndex) {
    412.         plugMain.pageData.menuBtnIndex = 0;
    413.       }
    414.       GM_registerMenuCommand(name, fun)
    415.       await plugMain.waitOf(a => $("body:visible").length > 0)
    416.       await plugMain.waitTimeout(500)
    417.       if ($("#zfkLeftMenuContainer").length > 0) {
    418.         plugMain.pageData.menuBtnIndex++;
    419.         $("#zfkLeftMenuContainer .zfkLeftMenuBtnUl").append(`<li id="zfkMenuBtn_${plugMain.pageData.menuBtnIndex}">${name}</li>`)
    420.         $(`#zfkMenuBtn_${plugMain.pageData.menuBtnIndex}`).click(function () {
    421.           fun();
    422.         });
    423.       }
    424.     },
    425.     registerMenuCommand() {
    426.       plugMain.callRegisterMenuCommand("当前是免费版", plugMain.openDoc);
    427.       plugMain.callRegisterMenuCommand("点此安装付费版本", plugMain.openDoc);
    428.       plugMain.callRegisterMenuCommand("联系脚本客服", plugMain.linkAuthor);
    429.     },
    430.     linkAuthor() {
    431.       window.open("http://doc.zhanyc.cn/contact-me/");
    432.     },
    433.     addStyle() {
    434.       GM_addStyle(`
    435.     .zfk-btn{background-color:#0fbcf9;color:white;padding:4px 12px;border:none;box-sizing:content-box;font-size:14px;height:20px;border-radius:4px;cursor:pointer;display:inline-block;border:1px solid transparent;white-space:nowrap;user-select:none;text-align:center;vertical-align:middle}.zfk-btn:hover{opacity:.8}.zfk-btn.success{background-color:#38b03f}.zfk-btn.warning{background-color:#f1a325}.zfk-btn.info{background-color:#03b8cf}.zfk-btn.danger{background-color:#ea644a}.zfk-form-tips{font-size:1.2em;color:red}.tips{color:red}.zfk-form textarea,.zfk-form input[type=text],.zfk-form input[type=number],.zfk-form input[type=password]{border:1px solid #888;border-radius:4px;padding:5px;box-sizing:border-box}.zfk-form textarea{width:100%}.zfk-form-item{margin-bottom:10px}.zfk-form-item>label:first-child{width:7em;text-align:right;display:inline-block;padding-right:5px;margin-right:0}.zfk-form-item label{margin-right:4px}.zfk-form-item.block>label:first-child{text-align:left;display:block;width:100%;font-weight:bold}.text-l{text-align:left !important}.text-c{text-align:center !important}.text-r{text-align:right !important}.p-0{padding:0px !important}.p-5{padding:5px !important}.p-10{padding:10px !important}.p-15{padding:15px !important}.p-20{padding:20px !important}.p-t-0{padding-top:0px !important}.p-t-5{padding-top:5px !important}.p-t-10{padding-top:10px !important}.p-t-15{padding-top:15px !important}.p-t-20{padding-top:20px !important}.p-b-0{padding-bottom:0px !important}.p-b-5{padding-bottom:5px !important}.p-b-10{padding-bottom:10px !important}.p-b-15{padding-bottom:15px !important}.p-b-20{padding-bottom:20px !important}.p-l-0{padding-left:0px !important}.p-l-5{padding-left:5px !important}.p-l-10{padding-left:10px !important}.p-l-15{padding-left:15px !important}.p-l-20{padding-left:20px !important}.p-r-0{padding-right:0px !important}.p-r-5{padding-right:5px !important}.p-r-10{padding-right:10px !important}.p-r-15{padding-right:15px !important}.p-r-20{padding-right:20px !important}.p-0{padding:0px !important}.p-5{padding:5px !important}.p-10{padding:10px !important}.p-15{padding:15px !important}.p-20{padding:20px !important}.m-t-0{margin-top:0px !important}.m-t-5{margin-top:5px !important}.m-t-10{margin-top:10px !important}.m-t-15{margin-top:15px !important}.m-t-20{margin-top:20px !important}.m-b-0{margin-bottom:0px !important}.m-b-5{margin-bottom:5px !important}.m-b-10{margin-bottom:10px !important}.m-b-15{margin-bottom:15px !important}.m-b-20{margin-bottom:20px !important}.m-l-0{margin-left:0px !important}.m-l-5{margin-left:5px !important}.m-l-10{margin-left:10px !important}.m-l-15{margin-left:15px !important}.m-l-20{margin-left:20px !important}.m-r-0{margin-right:0px !important}.m-r-5{margin-right:5px !important}.m-r-10{margin-right:10px !important}.m-r-15{margin-right:15px !important}.m-r-20{margin-right:20px !important}.bold{font-weight:bold !important}.tips-box{padding:10px;border:1px solid red;background-color:#fff0f0;color:red}.bold{font-weight:bold}.font-l{font-size:1.2em}.font-xl{font-size:40px}.font-l{font-size:25px}.color-default{color:#ea644a !important}.color-success{color:#38b03f !important}.color-warning{color:#f1a325 !important}.color-danger{color:#ea644a !important}.bg-default{background-color:#ea644a !important}.bg-success{background-color:#38b03f !important}.bg-warning{background-color:#f1a325 !important}.bg-danger{background-color:#ea644a !important}.zfk-table{border-collapse:collapse}.zfk-table thead{background-color:#1abc9c}.zfk-table td,.zfk-table th{text-align:center;padding:6px;border:1px solid #888}.zfk-table tr:nth-child(2n){background-color:#f2f2f2}.zfk-table tr:hover{background-color:#fff799}.zfk-container *{font-size:17px}
    436.     `);
    437.     },
    438.     closeWaitConfrimWin() {
    439.       plugMain.setGMData("closeLJTS", plugMain.now());
    440.     },
    441.     removeArrEmpty(arr) {
    442.       let res = [];
    443.       arr.forEach((item) => {
    444.         if (!!item && item.trim() != "") {
    445.           res.push(item);
    446.         }
    447.       });
    448.       return res;
    449.     },
    450.     confirmRun(msg = "脚本:3秒后执行下一步操作", time = 3000) {
    451.       return new Promise((resolve, reject) => {
    452.         let isRun = true;
    453.         Swal.fire({
    454.           title: "脚本:是否继续执行?",
    455.           text: msg,
    456.           icon: "warning",
    457.           showCancelButton: true,
    458.           confirmButtonColor: "#3085d6",
    459.           cancelButtonColor: "#d33",
    460.           confirmButtonText: "取消执行"
    461.         }).then((result) => {
    462.           isRun = false;
    463.           Swal.close()
    464.           reject();
    465.         });
    466.         setTimeout(() => {
    467.           Swal.close()
    468.           resolve(true);
    469.         }, time);
    470.       });
    471.     },
    472.     waitTimeout(timeout) {
    473.       return new Promise((resolve, reject) => {
    474.         setTimeout(() => {
    475.           resolve();
    476.         }, timeout);
    477.       });
    478.     },
    479.     waitOf(fun, interval = 1000, timeout = 30) {
    480.       console.log("%c waitOf", "background:rgb(0,0,0);color:#fff", fun);
    481.       return new Promise((resolve, reject) => {
    482.         let _timeOut = timeout * 1000;
    483.         try {
    484.           if (fun()) {
    485.             return resolve();
    486.           }
    487.         } catch (e) {
    488.           console.error(e);
    489.         }
    490.         let index = setInterval(() => {
    491.           try {
    492.             if (timeout != -1) {
    493.               _timeOut -= interval;
    494.               if (_timeOut < 0) {
    495.                 clearInterval(index);
    496.                 return reject();
    497.               }
    498.             }
    499.             if (fun()) {
    500.               clearInterval(index);
    501.               return resolve();
    502.             }
    503.           } catch (e) {
    504.             console.error(e);
    505.           }
    506.         }, interval);
    507.       });
    508.     },
    509.     getUrlParam(url, name) {
    510.       if (arguments.length == 1) {
    511.         name = url;
    512.         url = window.location;
    513.       }
    514.       var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
    515.       var r = url.search.substr(1).match(reg);
    516.       if (r != null) return unescape(r[2]);
    517.       return "";
    518.     },
    519.     objectToQueryString(obj) {
    520.       var queryParams = [];
    521.       for (var key in obj) {
    522.         if (obj.hasOwnProperty(key)) {
    523.           var value = obj[key];
    524.           // 如果值为数组,则将其转换为多个参数
    525.           if (Array.isArray(value)) {
    526.             for (var i = 0; i < value.length; i++) {
    527.               queryParams.push(
    528.                 encodeURIComponent(key) + "=" + encodeURIComponent(value[i])
    529.               );
    530.             }
    531.           } else {
    532.             queryParams.push(
    533.               encodeURIComponent(key) + "=" + encodeURIComponent(value)
    534.             );
    535.           }
    536.         }
    537.       }
    538.       return queryParams.join("&");
    539.     },
    540.     parseQueryString(url = window.location.href) {
    541.       //url参数转对象
    542.       url = !url ? window.location.href : url;
    543.       if (url.indexOf("?") === -1) {
    544.         return {};
    545.       }
    546.       let search =
    547.         url[0] === "?"
    548.           ? url.substr(1)
    549.           : url.substring(url.lastIndexOf("?") + 1);
    550.       if (search === "") {
    551.         return {};
    552.       }
    553.       search = search.split("&");
    554.       let query = {};
    555.       for (let i = 0; i < search.length; i++) {
    556.         let pair = search[i].split("=");
    557.         query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || "");
    558.       }
    559.       return query;
    560.     },
    561.     getAttrName(el, key) {
    562.       if (el.jquery) el = el.get(0);
    563.       let propName = Object.keys(el).find((a) => a.startsWith(key));
    564.       return propName;
    565.     },
    566.     getAttrNameList(el, key) {
    567.       if (el.jquery) el = el.get(0);
    568.       let propName = Object.keys(el).filter((a) => a.startsWith(key));
    569.       return propName;
    570.     },
    571.     alertMsg(msg, timeout = 0) {
    572.       Swal.fire({
    573.         title: "脚本提示" + (timeout == 0 ? '' : `(${(timeout / 1000).toFixed(2)}秒后自动关闭})`),
    574.         text: msg,
    575.         timerProgressBar: true,

    576.       });
    577.     },
    578.     tipsMsg(msg, timeout = 3000) {
    579.       Swal.fire({
    580.         title: msg,
    581.         timer: timeout,
    582.         position: "top-end",
    583.         timerProgressBar: true,
    584.         backdrop: false,
    585.         showConfirmButton: false,
    586.       });
    587.     },
    588.     confirmMsg(msg = "请确认", option = {}) {
    589.       let defConfig = {
    590.         title: "脚本提示",
    591.         btn: ["确定", "关闭"],
    592.         offset: "100px",
    593.         area: ["500px"],
    594.         shade: 0.3,
    595.         fun1() { },
    596.         fun2() { },
    597.         fun3() { }
    598.       }
    599.       Object.assign(defConfig, option)
    600.       Swal.fire({
    601.         title: defConfig.title,
    602.         text: msg,
    603.         icon: "warning",
    604.         showCancelButton: true,
    605.         confirmButtonColor: "#3085d6",
    606.         cancelButtonColor: "#d33",
    607.         confirmButtonText: defConfig.btn[0],
    608.         cancelButtonText: defConfig.btn[1]
    609.       }).then((result) => {
    610.         if (result.isConfirmed) {
    611.           defConfig.fun1()
    612.         } else {
    613.           defConfig.fun2()
    614.         }
    615.       });
    616.     },
    617.     matchUrl(urlKeyword, mode = "like", url = location.href) {
    618.       let res = false;
    619.       switch (mode) {
    620.         case "eq":
    621.           res = urlKeyword == url;
    622.           break;
    623.         case "like":
    624.           res = url.indexOf(urlKeyword) != -1;
    625.           break;
    626.         case "left":
    627.           res = url.startsWith(urlKeyword);
    628.           break;
    629.         case "right":
    630.           res = url.endsWith(urlKeyword);
    631.           break;
    632.       }
    633.       return res;
    634.     },
    635.     getPromiseWithAbort(p) {
    636.       let obj = {};
    637.       let p1 = new Promise(function (resolve, reject) {
    638.         obj.abort = reject;
    639.       });
    640.       obj.promise = Promise.race([p, p1]);
    641.       return obj;
    642.     },
    643.     page_yhwelcome() {
    644.       console.log("%c page_yhwelcome", "background:rgb(255,0,0);color:#fff");
    645.       var token = sessionStorage.getItem("token");
    646.       this.setGMData("token", token);
    647.       this.setGMData("login", { login: true, time: plugMain.now() });
    648.     },
    649.     createWorker(f) {
    650.       var blob = new Blob(["(" + f + ")()"]);
    651.       var url = window.URL.createObjectURL(blob);
    652.       var worker = new Worker(url);
    653.       return worker;
    654.     },
    655.     createIntervalWorker(callback, time) {
    656.       var pollingWorker = plugMain.createWorker(`async function (e) {
    657.             setInterval(async function () {
    658.               this.postMessage(null)
    659.             }, ${time})
    660.           }`);
    661.       pollingWorker.onmessage = callback;
    662.       return pollingWorker;
    663.     },
    664.     createTimeoutWorker(callback, time) {
    665.       var pollingWorker = plugMain.createWorker(`async function (e) {
    666.               setTimeout(async function () {
    667.                 this.postMessage(null)
    668.               }, ${time})
    669.             }`);
    670.       pollingWorker.onmessage = function () {
    671.         callback();
    672.         plugMain.stopWorker(pollingWorker);
    673.       };
    674.       return pollingWorker;
    675.     },
    676.     stopWorker(vm) {
    677.       try {
    678.         vm && vm.terminate();
    679.       } catch (err) {
    680.         console.log(err);
    681.       }
    682.     },
    683.     getGMData(item, def) {
    684.       return GM_getValue(item, def);
    685.     },
    686.     setGMData(item, val) {
    687.       return GM_setValue(item, val);
    688.     },
    689.     delGMData(item, val) {
    690.       return GM_deleteValue(item);
    691.     },
    692.     generateRandomString(length) {
    693.       const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    694.       let randomString = "";

    695.       for (let i = 0; i < length; i++) {
    696.         const randomIndex = Math.floor(Math.random() * charset.length);
    697.         randomString += charset.charAt(randomIndex);
    698.       }

    699.       return randomString;
    700.     },
    701.     timeSecondsFormat(seconds) {
    702.       // 确保秒数为非负整数
    703.       seconds = Math.floor(Math.abs(seconds));

    704.       // 计算小时、分钟和秒
    705.       var hours = Math.floor(seconds / 3600);
    706.       var minutes = Math.floor((seconds % 3600) / 60);
    707.       var secs = seconds % 60;

    708.       // 如果小时、分钟或秒小于10,则在其前面添加一个0
    709.       hours = (hours < 10) ? "0" + hours : hours;
    710.       minutes = (minutes < 10) ? "0" + minutes : minutes;
    711.       secs = (secs < 10) ? "0" + secs : secs;

    712.       // 返回格式化的时间字符串
    713.       return hours + ":" + minutes + ":" + secs;
    714.     },
    715.     // 时间转换成秒
    716.     timeStringToSeconds(timeString) {
    717.       if (!timeString.includes("时")) {
    718.         timeString = '0时' + timeString
    719.       }
    720.       timeString = timeString
    721.         .replace("小时", ":")
    722.         .replace("时", ":")
    723.         .replace("分钟", ":")
    724.         .replace("分", ":")
    725.         .replace("秒", "");
    726.       if (timeString.endsWith(":")) {
    727.         timeString = timeString.substring(0, timeString.length - 1);
    728.       }
    729.       const parts = timeString.split(":");
    730.       if (parts.length !== 3) {
    731.         if (parts.length == 2) {
    732.           parts.push(0);
    733.         } else {
    734.           throw new Error("Invalid time string format. Expected 'hh:mm:ss'.");
    735.         }
    736.       }

    737.       const hours = parseInt(parts[0]);
    738.       const minutes = parseInt(parts[1]);
    739.       const seconds = parseInt(parts[2]);

    740.       if (isNaN(hours) || isNaN(minutes) || isNaN(seconds)) {
    741.         throw new Error("Invalid time string format. Expected numeric values.");
    742.       }

    743.       return hours * 3600 + minutes * 60 + seconds;
    744.     },
    745.     getLocalData(item, def) {
    746.       var val = localStorage.getItem(item);
    747.       if (val == null) return def;

    748.       return JSON.parse(val).val;
    749.     },
    750.     setLocalData(item, val) {
    751.       return localStorage.setItem(item, JSON.stringify({ val: val }));
    752.     },
    753.     setFormVal(selector, formVal) {
    754.       $.each(formVal, function (key, val) {
    755.         let $el = $(selector).find(`[name="${key}"]`);
    756.         // console.log($el);
    757.         // console.log(key, $el.eq(0).attr("type"));
    758.         if ($el.length == 0) return true;
    759.         else if ($el.length == 1) {
    760.           let type = $el.eq(0).attr("type");
    761.           switch (type) {
    762.             case "radio":
    763.             case "checkbox":
    764.               if ($el.val() == val) $el.prop("checked", true);
    765.               break;
    766.             default:
    767.               $el.val(val);
    768.               break;
    769.           }
    770.         } else {
    771.           $el.each((i, el) => {
    772.             // console.log($(el), $(el).val());
    773.             if (val.includes($(el).val())) {
    774.               $(el).prop("checked", true);
    775.             }
    776.           });
    777.         }
    778.       });
    779.     },
    780.     getFormVal(selector) {
    781.       let formVal = {};
    782.       var arr = $(selector).serializeArray();
    783.       let tempArr = [];
    784.       $.each(arr, function () {
    785.         console.log(this);
    786.         if (!tempArr.includes(this.name)) {
    787.           tempArr.push(this.name);
    788.           formVal[this.name] = this.value;
    789.         } else {
    790.           let oldVal = formVal[this.name];
    791.           if (Array.isArray(oldVal)) {
    792.             formVal[this.name].push(this.value);
    793.           } else {
    794.             formVal[this.name] = [formVal[this.name], this.value];
    795.           }
    796.         }
    797.       });
    798.       return formVal;
    799.     },
    800.     now() {
    801.       return new Date().getTime();
    802.     },
    803.     getElByText(query, text, mode = "eq", visible = true) {
    804.       let $el = null;
    805.       $(query).each((i, el) => {
    806.         if (visible && !$(el).is(":visible")) {
    807.           return true;
    808.         }
    809.         if (mode == "eq" && $(el).text().trim() == text) {
    810.           $el = $(el);
    811.           return false;
    812.         } else if (
    813.           mode == "startsWith" &&
    814.           $(el).text().trim().startsWith(text)
    815.         ) {
    816.           $el = $(el);
    817.           return false;
    818.         } else if (mode == "endsWith" && $(el).text().trim().endsWith(text)) {
    819.           $el = $(el);
    820.           return false;
    821.         } else if (mode == "like" && $(el).text().trim().includes(text)) {
    822.           $el = $(el);
    823.           return false;
    824.         }
    825.       });
    826.       return $el;
    827.     },
    828.     getElListByText(query, text, mode = "eq", visible = true) {
    829.       let arr = [];
    830.       $(query).each((i, el) => {
    831.         if (visible && !$(query).is(":visible")) {
    832.           return true;
    833.         }
    834.         if (mode == "eq" && $(el).text().trim() == text) {
    835.           arr.push($(el));
    836.         } else if (
    837.           mode == "startsWith" &&
    838.           $(el).text().trim().startsWith(text)
    839.         ) {
    840.           arr.push($(el));
    841.         } else if (mode == "endsWith" && $(el).text().trim().endsWith(text)) {
    842.           arr.push($(el));
    843.         }
    844.       });
    845.       return arr;
    846.     },
    847.     random(min, max) {
    848.       // 生成随机数范围
    849.       if (arguments.length === 2) {
    850.         return Math.floor(min + Math.random() * (max + 1 - min));
    851.       } else {
    852.         return null;
    853.       }
    854.     },
    855.     downloadTxt(filename, text) {
    856.       var element = document.createElement("a");
    857.       element.setAttribute(
    858.         "href",
    859.         "data:text/plain;charset=utf-8," + encodeURIComponent(text)
    860.       );
    861.       element.setAttribute("download", filename);

    862.       element.style.display = "none";
    863.       document.body.appendChild(element);

    864.       element.click();

    865.       document.body.removeChild(element);
    866.     },
    867.     dateFormat(date = new Date(), fmt = "yyyy-MM-dd HH:mm") {
    868.       let ret;
    869.       if (typeof date === "number") date = new Date(date);
    870.       const opt = {
    871.         "y+": date.getFullYear().toString(), // 年
    872.         "M+": (date.getMonth() + 1).toString(), // 月
    873.         "d+": date.getDate().toString(), // 日
    874.         "H+": date.getHours().toString(), // 时
    875.         "m+": date.getMinutes().toString(), // 分
    876.         "s+": date.getSeconds().toString(), // 秒
    877.         // 有其他格式化字符需求可以继续添加,必须转化成字符串
    878.       };
    879.       for (let k in opt) {
    880.         ret = new RegExp("(" + k + ")").exec(fmt);
    881.         if (ret) {
    882.           fmt = fmt.replace(
    883.             ret[1],
    884.             ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, "0")
    885.           );
    886.         }
    887.       }
    888.       return fmt;
    889.     },
    890.   });
    891.   plugMain.tipsMsg("脚本加载中")
    892.   setTimeout(() => {
    893.     if (!unsafeWindow.zfk) {
    894.       if (unsafeWindow.plugMainInitialized) {
    895.         console.log("init 已经执行过,跳过");
    896.         return;
    897.       }
    898.       unsafeWindow.plugMainInitialized = true;
    899.       plugMain.init();

    900.       console.log(document.querySelector('li[data-plugin="task-list"]'))
    901.       console.log(document.querySelector('li[data-plugin="task-list"]'))
    902.       console.log(document.querySelector('li[data-plugin="task-list"]'))
    903.       // plugMain.autoNext();
    904.     } else {
    905.       console.log('skip init');
    906.     }
    907.   }, 3000);
    908.   if (!unsafeWindow.plugMain) unsafeWindow.plugMain = plugMain;
    909. })();
    复制代码


    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表