🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

Greasy Fork is available in English.

Lib_MyAPI

封装了一些常用的API,用于方便调用

אין להתקין סקריפט זה ישירות. זוהי ספריה עבור סקריפטים אחרים // @require https://update.greasyfork.org/scripts/489184/1338830/Lib_MyAPI.js

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==UserScript==
// @name Lib_MyAPI
// @namespace AC-API
// @include *
// @run-at document-start
// @version 2024.03.07
// @grant   GM_xmlhttpRequest
// @description 封装了一些常用的API,用于方便调用
// ==/UserScript==

// 避免函数污染
const ACMO = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;

// 不能用unsafeWindow来暴露MyApi,否则会有http的安全问题
const MyApi = (() => {
  /**
   * @param css CSS的正文内容
   * @param className 被添加的css节点的class,用于onlyOne检测
   * @param isReload 是否自动更新:移除后重新添加
   */
  function addStyle(css, className = '', isReload = false){ // 添加CSS代码,不考虑文本载入时间,带有className
    const tout = setInterval(function() {
      if (document.body != null) {
        clearInterval(tout);
        if (className) {
          // 节点不存在,或者是准备覆盖的时候
          if (isReload === false && document.querySelector("." + className) != null) {
            return;
          }

          // 节点已经存在,并且不准备覆盖
          try {
            document.querySelector("." + className).remove();
          } catch (e) {
          }
        }
        const cssNode = document.createElement("style");
        if (className) {
          cssNode.className = className;
        }
        cssNode.innerHTML = css;
        try {
          document.body.appendChild(cssNode);
        } catch (e) {
          console.log(e.message);
        }
      }
    }, 200);
  }

  function addScript(scriptInner) {
    const scriptNode = document.createElement('script')
    scriptNode.innerText = scriptInner
    document.head.appendChild(scriptNode)
  }

  const safeWaitFunc = function waitForElm(selector, callbackFunc = node => {}, findTick = 200, clearAfterFind = true, timeout = 20000 * 1000) {
    const handle = () => {
      if ((typeof (selector) === "string")) {
        let res = document.querySelectorAll(selector);
        if(res && res.length) {
          callbackFunc(res);
        }
      } else if (typeof (selector) === "function") {
        const res =  selector()
        if(res && res.length) {
          callbackFunc(res);
        }
      }
    }
    let lastRunAt = 0 // 最近一次运行的时间
    let onlyTimer;
    const firstRunAt = Date.now()
    
    // 其他时间增加监听即可
    const watcher = new ACMO(() => {
      // 超过节流时间间隔,立即执行事件处理函数
      if(Date.now() - lastRunAt > findTick) {
        handle()
        if(clearAfterFind) {
          watcher.disconnect();
        }
        lastRunAt = Date.now()
      } else {
        // 未超过节流时间间隔,设置定时器延迟执行事件处理函数
        clearTimeout(timer);
        onlyTimer = setTimeout(() => {
          handle();
          lastRunAt = Date.now()
        }, findTick);
      }
      
      // 超过最大时限,那么停止监听
      if(Date.now() - firstRunAt > timeout) {
        watcher.disconnect();
      }
    });

    watcher.observe(document.body, {
      childList: true,
      subtree: true
    });
  }

  function getUrlAttribute(attribute, needDecode = true){
    var searchValue = (window.location.search.substr(1) + "").split("&");
    for (var i = 0; i < searchValue.length; i++) {
      var key_value = searchValue[i].split("=");
      var reg = new RegExp("^"+attribute+"$");
      if (reg.test(key_value[0])) {
        var searchWords = key_value[1];
        return needDecode?decodeURIComponent(searchWords):searchWords;
      }
    }
  }

  const http = {
    async get(url) {
      return new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
          url,
          method: 'GET',
          timeout: 10000,
          onload: resp => resolve([null, resp.responseText]),
          onerror: resp => reject([resp, {}])
        })
      })
    },
    async post(url, data) {
      return new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
          url,
          data,
          method: 'POST',
          timeout: 10000,
          onload: resp => resolve([null, resp.responseText]),
          onerror: resp => reject([resp, {}])
        })
      })
    }
  }

  return {
    addStyle,
    addScript,
    safeWaitFunc,
    getUrlAttribute,
    http
  }
})()