如何使用<script>标记

时间:2016-12-11 14:22:59

标签: javascript google-chrome-extension browser-plugin

我在使用 content_script 脚本中的&lt; script&gt; 标记加载我插入到页面上下文中的所有脚本时遇到了麻烦,因为它们必须是以正确的加载顺序执行,因为一些依赖于其他顺序。在一个实际的HTML文件中,我猜有一个队列来加载文件,但是插入&lt; script&gt; 标签似乎是一个脚本延迟了一点时间,下一个脚本开始加载然后是立即执行,尽管它必须等待仍在加载的依赖库。

&#xA;&#xA;

以下是由于 x-tag-core引起的错误的网络输出.min.js primeui-all.min.js eventPage.js 之前加载,它们使用 jquery-ui.min.js ,在它之前加载:

&#xA;&#xA;

&#xA;&#xA;
  // manifest.js&#xA;“content_scripts”:[&#xA; {&#xA; “匹配”:[&#xA; “&LT; all_urls&gt;” 中&#XA; ],&#XA; “js”:[&#xA; “JS / jQuery的3.1.1.min.js”,&#XA; “JS / main.js” &#XA; ]&#xA;}&#xA;]&#xA;  
&#xA;&#xA;
  // main .js&#xA; var s = document.createElement('script');&#xA; s.src = chrome.extension.getURL('js / jquery-3.1.1.min.js');&#xA; $(document.head).append(s);&#xA;&#xA; s = document.createElement('script');&#xA; s.src = chrome.extension.getURL('js / jquery- ui.min.js');&#xA; $(document.head).append(s);&#xA;&#xA; s = document.createElement('script');&#xA; s.src = chrome.extension.getURL('js / primeui-all.min.js');&#xA; $(document.head).append(s);&#xA;&#xA; s = document.createElement( 'script');&#xA; s.src = chrome.extension.getURL('js / x-tag-core.min.js');&#xA; $(document.head).append(s); &#xA;&#xA; s = document.createElement('script');&#xA; s.src = chrome.extension.getURL('js / primeelements.min.js');&#xA; $( document.head).append(s);&#xA;&#xA; s = document.createElement('script');&#xA; s.src = chrome.extension.getURL('js / eventPage.js' );&#XA; $(document.head).append(S);&#XA;  
&#XA;

1 个答案:

答案 0 :(得分:1)

在代码段

中复制您的问题

以下代码段通过顺序插入<script>元素来重复您的问题。我正在使用网络资源,因为没有在Stack Overflow上存储此类脚本的方法。鉴于您只提供了jQuery的版本信息,我不得不猜测您正在使用的其他库的适当版本。

为了与您在Chrome扩展程序中使用的代码保持一致,chrome.extension.getURL()是伪造的。在这些片段中,该函数返回您正在使用的库的功能网络URL。很明显,在Chrome扩展程序中,您需要继续使用扩展程序中包含的库文件。

此外,eventPage.js的代码是伪造的,有一些代码报告jQuery是否存在,$(document).puidialog是否为函数,和/或是否定义了xtag。您看到的错误是$([something]).puidialog不是函数,xtag未定义。此fakeEventPageJS代码可准确显示脚本是否已正确加载。

在您的问题重复中,由于后续库无法找到先前的库,因此各种库也会产生错误。

var s = document.createElement('script');
s.src = chrome.extension.getURL('js/jquery-3.1.1.min.js');
document.head.appendChild(s);

s = document.createElement('script');
s.src = chrome.extension.getURL('js/jquery-ui.min.js');
document.head.appendChild(s);

s = document.createElement('script');
s.src = chrome.extension.getURL('js/primeui-all.min.js');
document.head.appendChild(s);

s = document.createElement('script');
s.src = chrome.extension.getURL('js/x-tag-core.min.js');
document.head.appendChild(s);

s = document.createElement('script');
s.src = chrome.extension.getURL('js/primeelements.min.js');
document.head.appendChild(s);

s = document.createElement('script');
//s.src = chrome.extension.getURL('js/eventPage.js');
//Fake js/eventPage.js with an actual script.
s.textContent = fakeEventPageJS;
document.head.appendChild(s);
<!-- The JavaScript code included in this HTML section is used to fake the chrome API
     and part of faking the existence of a js/eventPage.js file by inserting code. -->
    
<!-- Using HTML <script> tags to test that loading it via these works prior to testing
       using JavaScript inserts. If you want to verify that the code works when the
       scripts are included in the original HTML, you can uncomment the <script>
       tags here. -->

<!-- jquery-3.1.1.min.js -->
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script><!--  -->
<!-- jquery-ui.min.js -->
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script><!--  -->

<!-- primeui-all.min.js -->
<link rel="stylesheet" href="https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeui-all.min.css">
<!-- <script src="https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeui-all.min.js"></script><!--  -->

<!-- x-tag-core.min.js -->
<!-- <script src="https://cdn.rawgit.com/x-tag/core/master/dist/x-tag-core.min.js"></script>

<!-- primeelements.min.js -->
<!-- <script src="https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeelements.min.js"></script> <!-- -->

<script>
  //Fake chrome.extension.getURL
  var netScriptLoations = {
    'js/jquery-3.1.1.min.js':'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js',
    'js/jquery-ui.min.js':'https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js',
    'js/primeui-all.min.js':'https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeui-all.min.js',
    'js/x-tag-core.min.js':'https://cdn.rawgit.com/x-tag/core/master/dist/x-tag-core.min.js',
    'js/primeelements.min.js':'https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeelements.min.js'
}
if(typeof chrome !== 'object'){
  var chrome = {};
}
if(typeof chrome.extension !== 'object'){
  chrome.extension = {};
}
if(typeof chrome.extension.getURL !== 'function'){
  chrome.extension.getURL = function(script){
    //console.log(netScriptLoations[script]);
    return netScriptLoations[script];
  };
}

var fakeEventPageJS = 
      'var testResult = "Scripts did NOT load correctly. "' 
    + '               + "$(document).puidialog is NOT a function.";'
    + 'var passedChecks=0;'
    + 'if(typeof $ === "function"){'
    + '    var puidialogNot = " NOT";'
    + '    if(typeof $(document).puidialog === "function") {'
    + '        puidialogNot = "";'
    + '    }'
    + '    console.log("$(document).puidialog is" + puidialogNot + " a function");'
    + '} else {'
    + '    console.log("No jQuery");'
    + '}'
    + 'var xtagNot = " NOT";'
    + 'if(typeof xtag !== "undefined") {'
    + '    xtagNot = "";'
    + '}'
    + 'console.log("xtag is" + xtagNot + " defined.");'
    + 'if(puidialogNot + xtagNot === "") {'
    + '    testResult = "Scripts loaded CORRECTLY. "' 
    + '}'
    + 'console.log(testResult);';
</script>

将每个<script>插入前一个脚本的onload事件处理程序

很明显,插入的<script>元素是异步执行的。为了强制它们同步执行,我们需要在前一个脚本完成执行后插入下一个脚本。这可以通过为每个脚本使用load event来完成。

以下代码加载前一个脚本的load事件处理程序中的每个后续脚本。

函数createScriptElement创建了一个单独的<script>元素。由于不需要伪造 eventPage.js 脚本,因此可以在代码中简化此功能。

函数createScriptSequence创建一系列<script>元素,每个元素在其onload侦听器中插入下一个脚本。这使用script.addEventListerner('load',...)以免受正在加载的脚本的影响,从而更改script.onload属性/属性。

var scriptsToInsert = [
    'js/jquery-3.1.1.min.js',
    'js/jquery-ui.min.js',
    'js/primeui-all.min.js',
    'js/x-tag-core.min.js',
    'js/primeelements.min.js',
    'js/eventPage.js'
]

function createScriptElement(script){
    let scriptEl = document.createElement('script');
    let scriptElSource = chrome.extension.getURL(script);
    if(scriptElSource){
        scriptEl.src = scriptElSource;
    } else {
        //Only need this `else` because we are faking having js/eventPage.js by using
        //  some code to indicate if $(document).puidialog is a function.
        scriptEl.textContent = fakeEventPageJS;
    }
    return scriptEl;
}

function createScriptSequence(scriptArray){
    var scriptEls = [];
    //Create all the script elements
    scriptArray.forEach((script,index)=>{
        //console.log(script);
        scriptEls.push(createScriptElement(script));
        if(index>0){
            //Add an onload listener for each script (except the last) which loads
            //  the next one in the sequence.
            scriptEls[index - 1].addEventListener('load',function oneTime(){
                //Probably don't need to remove this, but better to clean things up.
                scriptEls[index - 1].removeEventListener('load',oneTime,false);
                document.head.appendChild(scriptEls[index]);
            },false);
        }
    });
    //Return the first script in the sequence
    return scriptEls[0];
}

document.head.appendChild(createScriptSequence(scriptsToInsert));
<!-- The JavaScript code included in this HTML section is used to fake the chrome API
     and part of faking the existence of a js/eventPage.js file by inserting code. -->

<!-- jquery-ui.min.js -->
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<!-- primeui-all.min.js -->
<link rel="stylesheet" href="https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeui-all.min.css">

<script>
  //Fake chrome.extension.getURL
  var netScriptLoations = {
    'js/jquery-3.1.1.min.js':'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js',
    'js/jquery-ui.min.js':'https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js',
    'js/primeui-all.min.js':'https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeui-all.min.js',
    'js/x-tag-core.min.js':'https://cdn.rawgit.com/x-tag/core/master/dist/x-tag-core.min.js',
    'js/primeelements.min.js':'https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeelements.min.js'
}
if(typeof chrome !== 'object'){
  var chrome = {};
}
if(typeof chrome.extension !== 'object'){
  chrome.extension = {};
}
if(typeof chrome.extension.getURL !== 'function'){
  chrome.extension.getURL = function(script){
    //console.log(netScriptLoations[script]);
    return netScriptLoations[script];
  };
}

var fakeEventPageJS = 
      'var testResult = "Scripts did NOT load correctly. "' 
    + '               + "$(document).puidialog is NOT a function.";'
    + 'var passedChecks=0;'
    + 'if(typeof $ === "function"){'
    + '    var puidialogNot = " NOT";'
    + '    if(typeof $(document).puidialog === "function") {'
    + '        puidialogNot = "";'
    + '    }'
    + '    console.log("$(document).puidialog is" + puidialogNot + " a function");'
    + '} else {'
    + '    console.log("No jQuery");'
    + '}'
    + 'var xtagNot = " NOT";'
    + 'if(typeof xtag !== "undefined") {'
    + '    xtagNot = "";'
    + '}'
    + 'console.log("xtag is" + xtagNot + " defined.");'
    + 'if(puidialogNot + xtagNot === "") {'
    + '    testResult = "Scripts loaded CORRECTLY. "' 
    + '}'
    + 'console.log(testResult);';
</script>