wuyuedefeng / blogs

博客文章在issue中
5 stars 0 forks source link

tampermonkey scripts #7

Open wuyuedefeng opened 4 years ago

wuyuedefeng commented 4 years ago

三木开发专用

// ==UserScript==
// @name         三木
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @include     *://*
// @grant        none
// ==/UserScript==
// 添加 jquery 可以将下面一行代码 放入到 UserScript中
// @require     http://libs.baidu.com/jquery/2.0.0/jquery.min.js

(function() {
    'use strict';

    // https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.css
    //dynamicLoadCss('https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.css')
    // http://libs.baidu.com/jquery/2.0.0/jquery.min.js
    //dynamicLoadJs('http://libs.baidu.com/jquery/2.0.0/jquery.min.js',function(){alert('加载成功')})
    // Your code here...
})();

/**
* 动态加载CSS
* @param {string} url 样式地址
*/
function dynamicLoadCss(url) {
    var head = document.getElementsByTagName('head')[0];
    var link = document.createElement('link');
    link.type='text/css';
    link.rel = 'stylesheet';
    link.href = url;
    head.appendChild(link);
}
/**
* 动态加载JS
* @param {string} url 脚本地址
* @param {function} callback  回调函数
*/
function dynamicLoadJs(url, callback) {
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    if(typeof(callback)=='function'){
        script.onload = script.onreadystatechange = function () {
            if (!this.readyState || this.readyState === "loaded" || this.readyState === "complete"){
                callback();
                script.onload = script.onreadystatechange = null;
            }
        };
    }
    head.appendChild(script);
}
/**
* 动态加载css脚本
* @param {string} cssText css样式
*/
function loadStyleString(cssText) {
    var style = document.createElement("style");
    style.type = "text/css";
    try{
        // firefox、safari、chrome和Opera
        style.appendChild(document.createTextNode(cssText));
    }catch(ex) {
        // IE早期的浏览器 ,需要使用style元素的stylesheet属性的cssText属性
        style.styleSheet.cssText = cssText;
    }
    document.getElementsByTagName("head")[0].appendChild(style);
}
/**
* 动态加载js脚本
* @param {string} code js脚本
*/
function loadScriptString(code) {
    var script = document.createElement("script");
    script.type = "text/javascript";
    try{
        // firefox、safari、chrome和Opera
        script.appendChild(document.createTextNode(code));
    }catch(ex) {
        // IE早期的浏览器 ,需要使用script的text属性来指定javascript代码。
        script.text = code;
    }
    document.getElementsByTagName("head")[0].appendChild(script);
}

Table of Contents Everywhere 自动生成目录

// ==UserScript==
// @name           Table of Contents Everywhere
// @description    On pages which do not have a Table of Contents, but should do, create one!  (I actually use this as a bookmarklet, so I can load it onto the current page only when I want it.)
// @downstreamURL  http://userscripts.org/scripts/source/123255.user.js
// @license        ISC
// @version        1.0.5
// @include        http://*/*
// @include        https://*/*
// @include        file://*
// @grant          none
// ==/UserScript==

var minimumItems = 4;    // Don't display a TOC for fewer than this number of entries.
var maximumItems = 800;  // Don't display a TOC for more than this number of entries.
var delayBeforeRunning = 3000;
var showAnchors = true;
var pushAnchorsToBottom = true;   // They can look messy interspersed amongst TOC tree
var startRolledUp = false;
var runInIframes = false;

// 2015-05-12  Improved shadow styling
// 2015-01-02  Improved styling
// 2012-02-19  Removed verbose log.  Added showAnchors.  Added https since everyone is forcing that now (e.g. github).
// 2012-02-18  Fixed sorting of TOC elements.  Added anchor unicode.
// 2012-01-30  Implemented GM_log and GM_addStyle so this script can be included on any web page.

// TODO: derbyjs.com is an example of a site with a <div id=toc> that has no
// hide or close buttons.  Perhaps we should add close and rollup buttons if we
// cannot find any recognisable buttons.  (Medawiki tocs for example, do have a
// show/hide button, so we don't want to add to them!)

// TODO: whatwg.org presents its own TOC but with no title.  Our buttons appear in the wrong place!

// BUG: Displays links for elements which may be invisible due to CSS.  (e.g. see github markdown pages)

// TODO CONSIDER: TOC hijacking _whitelist_ to avoid creeping fixes for per-site issues.  Different problems are appearing on a small proportion of websites when we try to consume/hijack their existing TOC.  It would be better to create our own *separate* TOC as standard, and only hijack *known* friendly TOCs such as WikiMedia's / Wikia's.
// (We might offer a tiny button "Try to Use Page TOC" allowing us to test hijack before adding the site to the whitelist.)

// Do not run in iframes
if (self !== window.top && !runInIframes) {
  return
}

function run() {

  // Implementing these two means we can run as a stand-alone script on any page.
  if (typeof GM_log == "undefined") {
    GM_log = function () {
      // Firefox's console.log does not have apply or call functions!
      var txt = Array.prototype.join.call(arguments, " ");
      console.log(txt);
    };
  }
  if (typeof GM_addStyle == "undefined") {
    this.GM_addStyle = function (css) {
      var s = document.createElement("style");
      s.type = 'text/css';
      s.innerHTML = css;
      document.getElementsByTagName("head")[0].appendChild(s);
    };
  }

// Implementing these allows us to remember toggled state.  (Chrome's set/getValue don't work.)
  if (typeof GM_setValue == 'undefined' || window.navigator.vendor.match(/Google/)) {
    GM_log("[TOCE] Adding fallback implementation of GM_set/getValue");

    if (typeof localStorage == 'undefined') {

      GM_getValue = function (name, defaultValue) {
        return defaultValue;
      };

    } else {

      GM_setValue = function (name, value) {
        value = (typeof value)[0] + value;
        localStorage.setItem(name, value);
      };

      GM_getValue = function (name, defaultValue) {
        var value = localStorage.getItem(name);
        if (!value)
          return defaultValue;
        var type = value[0];
        value = value.substring(1);
        switch (type) {
          case 'b':
            return value == 'true';
          case 'n':
            return Number(value);
          default:
            return value;
        }
      };

    }

  }

  function loadScript(url, thenCallFn) {
    GM_log("[TOCE] Loading fallback: " + url);
    var scr = document.createElement("script");
    scr.src = url;
    scr.type = "text/javascript";   // Konqueror 3.5 needs this!
    if (thenCallFn) {
      var called = false;

      function onceOnlyCallback(evt) {
        if (!called) {
          called = true;
          thenCallFn(evt);
        }
      }

      function errorCallback(evt) {
        GM_log("[TOCE] Failed to load: " + url, evt);
        onceOnlyCallback(evt);
      }

      scr.addEventListener('load', onceOnlyCallback, false);
      scr.addEventListener('error', errorCallback, false);
      // Fallback in case above events unsupported by browser (e.g. Konq 3.5)
      setTimeout(onceOnlyCallback, 5000);
    }
    document.body.appendChild(scr);
  }

// Modified for this script's needs.
// Returns e.g. "/*[2]/*[4]/*[9]"
  function getXPath(node) {
    var parent = node.parentNode;
    if (!parent) {
      return '';
    }
    var siblings = parent.childNodes;
    var totalCount = 0;
    var thisCount = -1;
    for (var i = 0; i < siblings.length; i++) {
      var sibling = siblings[i];
      if (true /*sibling.nodeType == node.nodeType*/) {
        totalCount++;
      }
      if (sibling == node) {
        thisCount = totalCount;
        break;
      }
    }
    // return getXPath(parent) + '/*' /*node.nodeName.toLowerCase()*/ + (totalCount>1 ? '[' + thisCount + ']' : '' );
    // Remain consistent:
    return getXPath(parent) + '/*' + '[' + thisCount + ']';
  }

// Konqueror 3.5 lacks some things!
  if (!Array.prototype.map) {
    Array.prototype.map = function (fn) {
      var l = [];
      for (var i = 0; i < this.length; i++) {
        l.push(fn(this[i]));
      }
      return l;
    };
  }
  if (!String.prototype.trim) {
    String.prototype.trim = function () {
      return this.replace(/^[ \t]+/, '').replace(/[ \t]+$/, '');
    };
  }

// The following block is mirrored in wikiindent.user.js

// See also: resetProps
  function clearStyle(elem) {
    // We set some crucial defaults, so we don't inherit CSS from the page:
    elem.style.display = 'inline';
    elem.style.position = 'static';
    elem.style.top = 'auto';
    elem.style.right = 'auto';
    elem.style.bottom = 'auto';
    elem.style.left = 'auto';
    elem.style.color = 'black';
    elem.style.backgroundColor = '#f4f4f4';
    elem.style.border = '0px solid magenta';
    elem.style.padding = '0px';
    elem.style.margin = '1px';
    return elem;
  }

  function newNode(tag, data) {
    var elem = document.createElement(tag);
    if (data) {
      for (var prop in data) {
        elem[prop] = data[prop];
      }
    }
    return elem;
  }

  function newSpan(text) {
    return clearStyle(newNode("span", {textContent: text}));
  }

  function addCloseButtonTo(where, toc) {
    var closeButton = newSpan("[X]");
    // closeButton.style.float = 'right';
    // closeButton.style.cssFloat = 'right'; // Firefox
    // closeButton.style.styleFloat = 'right'; // IE7
    closeButton.style.cursor = 'pointer';
    closeButton.style.paddingLeft = '5px';
    closeButton.onclick = function () {
      toc.parentNode.removeChild(toc);
    };
    closeButton.id = "closeTOC";
    where.appendChild(closeButton);
  }

  function addHideButtonTo(toc, tocInner) {
    var rollupButton = newSpan("[-]");
    // rollupButton.style.float = 'right';
    // rollupButton.style.cssFloat = 'right'; // Firefox
    // rollupButton.style.styleFloat = 'right'; // IE7
    rollupButton.style.cursor = 'pointer';
    rollupButton.style.paddingLeft = '10px';

    function toggleRollUp() {
      if (tocInner.style.display == 'none') {
        tocInner.style.display = '';
        rollupButton.textContent = "[-]";
      } else {
        tocInner.style.display = 'none';
        rollupButton.textContent = "[+]";
      }
      setTimeout(function () {
        GM_setValue("TOCE_rolledUp", tocInner.style.display == 'none');
      }, 5);
    }

    rollupButton.onclick = toggleRollUp;
    rollupButton.id = "togglelink";
    toc.appendChild(rollupButton);
    if (startRolledUp || GM_getValue("TOCE_rolledUp", false)) {
      toggleRollUp();
    }
  }

  function addButtonsConditionally(toc) {

    function verbosely(fn) {
      return function () {
        // GM_log("[WI] Calling: "+fn+" with ",arguments);
        return fn.apply(this, arguments);
      };
    };

    // Provide a hide/show toggle button if the TOC does not already have one.

    // Wikimedia's toc element is actually a table.  We must put the
    // buttons in the title div, if we can find it!

    var tocTitle = document.getElementById("toctitle"); // Wikipedia
    tocTitle = tocTitle || toc.getElementsByTagName("h2")[0]; // Mozdev
    // tocTitle = tocTitle || toc.getElementsByTagName("div")[0]; // Fingers crossed for general
    tocTitle = tocTitle || toc.firstChild; // Fingers crossed for general

    // Sometimes Wikimedia does not add a hide/show button (if the TOC is small).
    // We cannot test this immediately, because it gets loaded in later!
    function addButtonsNow() {

      var hideShowButton = document.getElementById("togglelink");
      if (!hideShowButton) {
        var tocInner = toc.getElementsByTagName("ol")[0]; // Mozdev (can't get them all!)
        tocInner = tocInner || toc.getElementsByTagName("ul")[0]; // Wikipedia
        tocInner = tocInner || toc.getElementsByTagName("div")[0]; // Our own
        if (tocInner) {
          verbosely(addHideButtonTo)(tocTitle || toc, tocInner);
        }
      }

      // We do this later, to ensure it appears on the right of
      // any existing [hide/show] button.
      if (document.getElementById("closeTOC") == null) {
        verbosely(addCloseButtonTo)(tocTitle || toc, toc);
      }

    }

    // Sometimes Wikimedia does not add a hide/show button (if the TOC is small).
    // We cannot test this immediately, because it gets loaded in later!
    if (document.location.href.indexOf("wiki") >= 0) {
      setTimeout(addButtonsNow, 2000);
    } else {
      addButtonsNow();
    }

  }

// End mirror.

// == Main == //

  function buildTableOfContents() {

    // Can we make a TOC?
    var headers = "//h1 | //h2 | //h3 | //h4 | //h5 | //h6 | //h7 | //h8";
    var anchors = "//a[@name]";
    // For coffeescript.org:
    var elementsMarkedAsHeader = "//*[@class='header']";
    // However on many sites that might be the thing opposite the footer, and probably not of note.

    var xpathQuery = headers + (showAnchors ? "|" + anchors : "") + "|" + elementsMarkedAsHeader;
    var nodeSnapshot = document.evaluate(xpathQuery, document, null, 6, null);
    //// Chrome needs lower-case 'h', Firefox needs upper-case 'H'!
    // var nodeSnapshot = document.evaluate("//*[starts-with(name(.),'h') and substring(name(.),2) = string(number(substring(name(.),2)))]",document,null,6,null);
    // var nodeSnapshot = document.evaluate("//*[starts-with(name(.),'H') and substring(name(.),2) = string(number(substring(name(.),2)))]",document,null,6,null);

    if (nodeSnapshot.snapshotLength > maximumItems) {
      GM_log("[TOCE] Too many nodes for table (sanity): " + nodeSnapshot.snapshotLength);
    } else if (nodeSnapshot.snapshotLength >= minimumItems) {

      GM_log("[TOCE] Making TOC with " + nodeSnapshot.snapshotLength + " nodes.");

      var toc = newNode("div");
      toc.id = 'toc';

      // var heading = newSpan("Table of Contents");
      var heading = clearStyle(newNode("h2", {textContent: "目录"}));
      heading.id = 'toctitle';   // Like Wikipedia
      heading.style.fontWeight = "bold";
      heading.style.fontSize = "100%";
      toc.appendChild(heading);

      var table = newNode("div");
      // addHideButtonTo(toc,table);
      table.id = 'toctable';   // Our own
      toc.appendChild(table);

      // We need to do this *after* adding the table.
      addButtonsConditionally(toc);

      // The xpath query did not return the elements in page-order.
      // We sort them back into the order they appear in the document
      // Yep it's goofy code, but it works.
      var nodeArray = [];
      for (var i = 0; i < nodeSnapshot.snapshotLength; i++) {
        var node = nodeSnapshot.snapshotItem(i);
        nodeArray.push(node);
        // We need to sort numerically, since with strings "24" < "4"
        node.magicPath = getXPath(node).substring(3).slice(0, -1).split("]/*[").map(Number);
        if (pushAnchorsToBottom && node.tagName === "A") {
          node.magicPath.unshift(+Infinity);
        }
      }
      nodeArray.sort(function (a, b) {
        // GM_log("[TOCE] Comparing "+a.magicPath+" against "+b.magicPath);
        for (var i = 0; i < a.magicPath.length; i++) {
          if (i >= b.magicPath.length) {
            return +1; // b wins (comes earlier)
          }
          if (a.magicPath[i] > b.magicPath[i]) {
            return +1; // b wins
          }
          if (a.magicPath[i] < b.magicPath[i]) {
            return -1; // a wins
          }
        }
        return -1; // assume b is longer, or they are equal
      });

      for (var i = 0; i < nodeArray.length; i++) {
        var node = nodeArray[i];

        var level = (node.tagName.substring(1) | 0) - 1;
        if (level < 0) {
          level = 0;
        }

        var linkText = node.textContent && node.textContent.trim() || node.name;
        if (!linkText) {
          continue;   // skip things we cannot name
        }

        var link = clearStyle(newNode("A"));
        if (linkText.length > 40) {
          link.title = linkText;   // Show full title on hover
          linkText = linkText.substring(0, 32) + "...";
        }
        link.textContent = linkText;
        /* Dirty hack for Wikimedia: */
        if (link.textContent.substring(0, 7) == "[edit] ") {
          link.textContent = link.textContent.substring(7);
        }
        if (node.tagName == "A") {
          link.href = '#' + node.name;
        } else {
          (function (node) {
            link.onclick = function (evt) {
              node.scrollIntoView();

              // Optional: CSS animation
              // NOT WORKING!
              /*
              node.id = "toc_current_hilight";
              ["","-moz-","-webkit-"].forEach(function(insMode){
                GM_addStyle("#toc_current_hilight { "+insMode+"animation: 'fadeHighlight 4s ease-in 1s alternate infinite'; }@"+insMode+"keyframes fadeHighlight { 0%: { background-color: yellow; } 100% { background-color: rgba(255,255,0,0); } }");
              });
              */

              evt.preventDefault();
              return false;
            };
          })(node);
          link.href = '#';
        }
        table.appendChild(link);

        // For better layout, we will now replace that link with a neater li.
        liType = "li";
        if (node.tagName == "A") {
          liType = "div";
        }
        var li = newNode(liType);
        // clearStyle(li); // display:inline; is bad on LIs!
        // li.style.display = 'list-item';   // not working on Github
        link.parentNode.replaceChild(li, link);
        if (node.tagName == "A") {
          li.appendChild(document.createTextNode("\u2693 "));
        }
        li.appendChild(link);
        li.style.paddingLeft = (1.5 * level) + "em";
        li.style.fontSize = (100 - 6 * (level + 1)) + "%";
        li.style.size = li.style.fontSize;

        // Debugging:
        /*
        li.title = node.tagName;
        if (node.name)
          li.title += " (#"+node.name+")";
        li.title = getXPath(node);
        */

      }

      document.body.appendChild(toc);

      // TODO scrollIntoView if newly matching 1.hash exists

      postTOC(toc);

    } else {
      GM_log("[TOCE] Not enough items found to create toc.");
    }

    return toc;

  }

  function postTOC(toc) {
    if (toc) {

      // We make the TOC float regardless whether we created it or it already existed.
      // Interestingly, the overflow settings seems to apply to all sub-elements.
      // E.g.: http://mewiki.project357.com/wiki/X264_Settings#Input.2FOutput
      // FIXED: Some of the sub-trees are so long that they also get scrollbars, which is a bit messy!
      // FIXED : max-width does not do what I want!  To see, find a TOC with really wide section titles (long lines).

      // Also in Related_Links_Pager.user.js
      // See also: clearStyle
      var resetProps = " width: auto; height: auto; max-width: none; max-height: none; ";

      if (toc.id === "") {
        toc.id = "toc";
      }
      var tocID = toc.id;
      GM_addStyle("#" + tocID + " { position: fixed; top: 10%; right: 4%; background-color: #f4f4f4; color: black; font-weight: normal; padding: 5px; border: 1px solid grey; z-index: 9999999; " + resetProps + " }" // max-height: 80%; max-width: 32%; overflow: auto;
        + "#" + tocID + "               { opacity: 0.4; }"
        + "#" + tocID + ":hover         { box-shadow: 0px 2px 10px 1px rgba(0,0,0,0.4); }"
        + "#" + tocID + ":hover         { -webkit-box-shadow: 0px 1px 4px 0px rgba(0,0,0,0.4); }"
        + "#" + tocID + ":hover         { opacity: 1.0; }"
        + "#" + tocID + "       > * > * { opacity: 0.0; }"
        + "#" + tocID + ":hover > * > * { opacity: 1.0; }"
        + "#" + tocID + " , #" + tocID + " > * > * { transition: opacity; transition-duration: 400ms; }"
        + "#" + tocID + " , #" + tocID + " > * > * { -webkit-transition: opacity; -webkit-transition-duration: 400ms; }"
      );
      GM_addStyle("#" + tocID + " > * { " + resetProps + " }");

      var maxWidth = window.innerWidth * 0.40 | 0;
      var maxHeight = window.innerHeight * 0.80 | 0;

      var table = document.getElementById("toctable");
      table = table || toc.getElementsByTagName("ul")[0];   // Wikipedia
      table = table || toc;   // Give up, set for whole element
      table.style.overflow = 'auto';
      table.style.maxWidth = maxWidth + "px";
      table.style.maxHeight = maxHeight + "px";

    }
  }

  function searchForTOC() {

    try {

      var tocFound = document.getElementById("toc");
      // Konqueror 3.5 does NOT have document.getElementsByClassName(), so we check for it.
      tocFound = tocFound || (document.getElementsByClassName && document.getElementsByClassName("toc")[0]);
      tocFound = tocFound || document.getElementById("article-nav");   // developer.mozilla.org
      tocFound = tocFound || document.getElementById("page-toc");      // developer.mozilla.org
      tocFound = tocFound || (document.getElementsByClassName && document.getElementsByClassName("twikiToc")[0]);      // TWiki
      tocFound = tocFound || document.getElementById("TOC");           // meteorpedia.com
      tocFound = tocFound || document.location.host === "developer.android.com" && document.getElementById("qv");
      if (document.location.host.indexOf("dartlang.org") >= 0) {
        tocFound = null;   // The toc they gives us contains top-level only.  It's preferable to generate our own full tree.
      }
      // whatwg.org:
      /* if (document.getElementsByTagName("nav").length == 1) {
        GM_log("[TOCE] Using nav element.");
        tocFound = document.getElementsByTagName("nav")[0];
      } */

      var toc = tocFound;

      // With the obvious exception of Wikimedia sites, most found tocs do not contain a hide/close button.
      // TODO: If we are going to make the toc float, we should give it rollup/close buttons, unless it already has them.
      // The difficulty here is: where to add the buttons in the TOC, and which part of the TOC to hide, without hiding the buttons!
      // Presumably we need to identify the title element (first with textContent) and collect everything after that into a hideable block (or hide/unhide each individually when needed).

      if (toc) {

        postTOC(toc);

        addButtonsConditionally(toc);

      } else {

        toc = buildTableOfContents();

      }

    } catch (e) {
      GM_log("[TOCE] Error! " + e);
    }

  }

  if (document.evaluate /*this.XPathResult*/) {
    searchForTOC();
  } else {
    loadScript("http://hwi.ath.cx/javascript/xpath.js", searchForTOC);
  }
}

// We want it to run fairly soon but it can be quite heavy on large pages - big XPath search.
let oldHash = ''
setInterval(function() {
  if (location.hash !== oldHash) {
    let beforeToc = document.querySelector('#toc')
    beforeToc && beforeToc.parentNode.removeChild(beforeToc)
    oldHash = location.hash
    run()
  }
}, delayBeforeRunning)

For 钉钉新校招 - 点击任一dom直接拷贝文字

// ==UserScript==
// @name         for-新校招
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        *://*.dingtalk.com/*
// @grant        none
// @require     http://libs.baidu.com/jquery/2.0.0/jquery.min.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.4/clipboard.min.js
// ==/UserScript==
// 添加 jquery 可以将下面一行代码 放入到 UserScript中
// @require     http://libs.baidu.com/jquery/2.0.0/jquery.min.js

(function() {
    'use strict';
    // 文字可选

    loadStyleString("*{user-select:text!important;} #toast-container > .toast{width: 100% !important;}")
    dynamicLoadCss("https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css")
    dynamicLoadJs("https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js", () => {
        //toastr.options.timeOut = 0;
        //toastr.options.extendedTimeOut = 0;
        new ClipboardJS('body', {
            text: function(trigger) {
                console.log(111, window.event.srcElement.innerText)
                toastr.success(window.event.srcElement.innerText)
                return window.event.srcElement.innerText;
            }
        });
    })

})();

function copyText(ele){  //复制文本 需要在文档中添加一个复制用的input
    var copyDOM = ele;  //要复制文字的节点
    var range = document.createRange(); //创建一个range
    window.getSelection().removeAllRanges();   //清楚页面中已有的selection
    range.selectNode(copyDOM);    // 选中需要复制的节点
    window.getSelection().addRange(range);   // 执行选中元素
    var successful = document.execCommand('copy');    // 执行 copy 操作
    if(successful){
        layer.msg('复制成功,如失败请手动复制!',{time: 2000});
    }else{
        layer.msg('复制失败,请手动复制!',{time: 2000});
    }
    // 移除选中的元素
    window.getSelection().removeAllRanges();

}

/**
* 动态加载CSS
* @param {string} url 样式地址
*/
function dynamicLoadCss(url) {
    var head = document.getElementsByTagName('head')[0];
    var link = document.createElement('link');
    link.type='text/css';
    link.rel = 'stylesheet';
    link.href = url;
    head.appendChild(link);
}
/**
* 动态加载JS
* @param {string} url 脚本地址
* @param {function} callback  回调函数
*/
function dynamicLoadJs(url, callback) {
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    if(typeof(callback)=='function'){
        script.onload = script.onreadystatechange = function () {
            if (!this.readyState || this.readyState === "loaded" || this.readyState === "complete"){
                callback();
                script.onload = script.onreadystatechange = null;
            }
        };
    }
    head.appendChild(script);
}
/**
* 动态加载css脚本
* @param {string} cssText css样式
*/
function loadStyleString(cssText) {
    var style = document.createElement("style");
    style.type = "text/css";
    try{
        // firefox、safari、chrome和Opera
        style.appendChild(document.createTextNode(cssText));
    }catch(ex) {
        // IE早期的浏览器 ,需要使用style元素的stylesheet属性的cssText属性
        style.styleSheet.cssText = cssText;
    }
    document.getElementsByTagName("head")[0].appendChild(style);
}
/**
* 动态加载js脚本
* @param {string} code js脚本
*/
function loadScriptString(code) {
    var script = document.createElement("script");
    script.type = "text/javascript";
    try{
        // firefox、safari、chrome和Opera
        script.appendChild(document.createTextNode(code));
    }catch(ex) {
        // IE早期的浏览器 ,需要使用script的text属性来指定javascript代码。
        script.text = code;
    }
    document.getElementsByTagName("head")[0].appendChild(script);
}
wuyuedefeng commented 3 years ago
/*
* runScript:一个promise同步方法。可以代替创建一个script标签,然后加载服务
* */
const runScript = async (url) => {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script')
    script.src = url
    script.onload = resolve
    script.onerror = reject
    // const firstScript = document.getElementsByTagName('script')[0]
    // firstScript.parentNode.insertBefore(script, firstScript)
    document.querySelector('head').appendChild(script)
  })
}
wuyuedefeng commented 2 years ago
function loadScriptWithUrl(url) {
    return new Promise((resolve, reject) => {
        const script = document.createElement('script')
        script.src = url
        script.language = 'javascript'
        script.onload = resolve
        script.onerror = reject
        // const firstScript = document.getElementsByTagName('script')[0]
        // firstScript.parentNode.insertBefore(script, firstScript)
        document.getElementsByTagName('head')[0].appendChild(script)
    })
}
wuyuedefeng commented 2 years ago

油猴页面引入CND的脚本封装

class NpmInstaller {
  constructor() {
    this.npmInstalled = {}
  }
  async install(originName) {
    // Trim string
    const name = originName.trim()
    if (this.npmInstalled[name]) {
      return
    } else {
      // 三种引入方式
      // 如果是一个有效的URL,直接通过<script />标签插入
      if (/^https?:\/\//.test(name)) {
        this.npmInstalled[name] = this.injectScript(name)
      }
      // 如果指定了版本,尝试使用unpkg加载
      else if (name.indexOf('@') !== -1) {
        this.npmInstalled[name] = this.unpkg(name)
      }
      // 否则,尝试使用cdnjs搜索
      else {
        this.npmInstalled[name] = this.cdnjs(name)
      }
      return await this.npmInstalled[name]
    }
  }
  async injectScript(url, pkgName = '') {
    return new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.onload = () => {
        resolve()
      }
      script.onerror = () => {
        reject()
      }
      document.body.appendChild(script);
      // document.body.removeChild(script);
    })
  }
  async unpkg(name) {
    await this.injectScript(`https://unpkg.com/${name}`, name)
  }
  async cdnjs(name) {
    const searchPromise = await fetch(
      `https://api.cdnjs.com/libraries?search=${name}`,
      // 不显示referrer的任何信息在请求头中
      { referrerPolicy: 'no-referrer' }
    )
    const { results, total } = await searchPromise.json()
    if (total === 0) {
      console.error('Sorry, ', name, ' not found, please try another keyword.')
      return
    }

    // 取结果中最相关的一条
    const { name: exactName, latest: url } = results[0]
    if (name !== exactName) {
      console.log(name, ' not found, import ', exactName, ' instead.')
    }
    // 通过<script />标签插入
    await this.injectScript(url, name)
  }
}
window.npmInstaller = window.npmInstaller || new NpmInstaller()

npmInstaller.install('moment').then(() => console.log("moment install success"))
npmInstaller.install('jquery').then(() => console.log("jquery install success"))