在覆盖页面上注入时,脚本如何在 HTML 模板中工作? (正在导入 jQuery)

How do I scripts work in HTML template on injection on the overriden page? (Importing jQuery)

显然,HTML 模板中的脚本仅适用于 HTML 模板本身,而不适用于 HTML 模板注入的页面。 (脚本仍然执行,但它们依赖于 jQuery,即使它在 之前 导入其他脚本,它也会吐出错误。)

详细说明,这是我的代码:

function cleanDocument(names) {
    var element = document.documentElement;
    for (var i = element.attributes.length - 1; i >= 0; i--) {
        element.removeAttribute(element.attributes[i].name);
    }
    for (var i = 0; i < names.length; i++) {
        var elements = document.getElementsByTagName(names[i]);
        if (elements.length === 0)
            document.documentElement.appendChild(document.createElement(names[i]));
    }
    window.stop();
}

var documentElements = ['html'];
cleanDocument(documentElements);

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
    // Typical action to be performed when the document is ready:
        
        var PBSKPage = xhttp.responseText;
        document.querySelector('html').innerHTML = "";
        loadPBSKPage();
        function loadPBSKPage() {
            
            document.querySelector('html').innerHTML = PBSKPage;
        }
    }
};

var actualpage = chrome.runtime.getURL('/2015/wildkratts/wk_homepage.html')
xhttp.open("GET", actualpage, true);
xhttp.send();

function insertAndExecute() {
    var scripts = Array.prototype.slice.call(document.getElementsByTagName("script"));
    var jquery = document.createElement("script");
    jquery.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js";
    document.head.appendChild(jquery);
    for (var i = 0; i < scripts.length; i++) {
        if (scripts[i].src != "") {
            var tag = document.createElement("script");
            tag.src = scripts[i].src;
            document.getElementsByTagName("head")[0].appendChild(tag);
        }
        else {
            eval(scripts[i].innerHTML);
        }
    }
}

此代码适用于https://pbskids.org/wildkratts/

基本上,它所做的是清除文档,然后使用 XMLHttpRequest,将扩展中的 HTML 模板注入页面。但是,HTML 模板中的所有脚本都需要 jQuery,并且在访问覆盖页面 (pbskids.org/wildkratts/) 时,由于未捕获的错误(即Uncaught ReferenceError: $ is not defined) 如果导入 jQuery 将被解决。

然后我访问了 HTML 模板 URL 本身,你知道吗,脚本实际上执行没有问题。

这是我的脚本标签在 HTML 模板中的顺序:

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
        <script src="chrome-extension://niabfndainielhgpcjenbpodannhfofj/jquery_libraries/1.11.0/jquery.min.js"></script>
        <script>window.jQuery || document.write('<script src="chrome-extension://niabfndainielhgpcjenbpodannhfofj/2015/pbsk_resources/wildkratts/js/vendor/jquery-1.11.0.min.js"><\/script>')</script>
        <script src="chrome-extension://niabfndainielhgpcjenbpodannhfofj/2015/pbsk_resources/wildkratts/js/vendor/jquery-1.11.0.min.js"></script>
        <script src="chrome-extension://niabfndainielhgpcjenbpodannhfofj/2015/pbsk_resources/wildkratts/js/vendor/jquery.nivo.slider.pack.js" type="text/javascript"></script>
        <script src="chrome-extension://niabfndainielhgpcjenbpodannhfofj/2015/pbsk_resources/wildkratts/js/vendor/jquery.touchSwipe.min.js" type="text/javascript"></script>
        <script src="chrome-extension://niabfndainielhgpcjenbpodannhfofj/2015/pbsk_resources/wildkratts/js/vendor/retina.min.js"></script>
        <script src="chrome-extension://niabfndainielhgpcjenbpodannhfofj/2015/pbsk_resources/wildkratts/js/plugins.js"></script>
        <script type="text/javascript" src="chrome-extension://niabfndainielhgpcjenbpodannhfofj/2015/pbsk_resources/wildkratts/js/swfobject.js"></script>    
        <script type="text/javascript" src="chrome-extension://niabfndainielhgpcjenbpodannhfofj/2015/pbsk_resources/wildkratts/js/vendor/jquery.mobile.custom.min.js"></script>
        <script type="text/javascript" src="chrome-extension://niabfndainielhgpcjenbpodannhfofj/2015/pbsk_resources/wildkratts/js/vendor/jquery.nivo.slider.3.2.plus.sliding.js"></script> 
        <script src="chrome-extension://niabfndainielhgpcjenbpodannhfofj/2015/pbsk_resources/wildkratts/js/pxaudio.min.js"></script>
        <script type="text/javascript" src="https://www-tc.pbskids.org/includes/javascript/bridge.urls.js"></script>
        <script type="text/javascript" src="https://www-tc.pbskids.org/includes/javascript/bridge.js"></script>        

我想做到这一点,以便脚本在覆盖页面本身而不是 HTML 模板上时能够正常工作。我想我可以让它重定向到 HTML 模板,但我真的不想那样。

当通过 appendChild 或类似的 DOM 方法单独添加脚本元素时,每个带有 src 的脚本都是异步 运行ning 的,即它不等待前一个脚本,因此它可能运行 在 jQuery 运行 秒之前。解决方案是在 运行 下一个脚本之前等待 load 事件:

async function insertAndExecute() {
  for (const orig of document.querySelectorAll('script')) {
    const copy = document.createElement('script');
    copy.textContent = orig.textContent;
    copy.src = orig.src;
    orig.replaceWith(copy);
    if (copy.src) {
      await new Promise(resolve => copy.addEventListener('load', resolve, {once: true}));
    }
  }
}