document.createElement(“script”) synchronously

前端 未结 11 2325
执念已碎
执念已碎 2020-11-22 12:56

Is it possible to call in a .js file synchronously and then use it immediately afterward?



        
11条回答
  •  暗喜
    暗喜 (楼主)
    2020-11-22 13:35

    I had the following problem(s) with the existing answers to this question (and variations of this question on other stackoverflow threads):

    • None of the loaded code was debuggable
    • Many of the solutions required callbacks to know when loading was finished instead of truly blocking, meaning I would get execution errors from immediately calling loaded (ie loading) code.

    Or, slightly more accurately:

    • None of the loaded code was debuggable (except from the HTML script tag block, if and only if the solution added a script elements to the dom, and never ever as individual viewable scripts.) => Given how many scripts I have to load (and debug), this was unacceptable.
    • Solutions using 'onreadystatechange' or 'onload' events failed to block, which was a big problem since the code originally loaded dynamic scripts synchronously using 'require([filename, 'dojo/domReady']);' and I was stripping out dojo.

    My final solution, which loads the script before returning, AND has all scripts properly accessible in the debugger (for Chrome at least) is as follows:

    WARNING: The following code should PROBABLY be used only in 'development' mode. (For 'release' mode I recommend prepackaging and minification WITHOUT dynamic script loading, or at least without eval).

    //Code User TODO: you must create and set your own 'noEval' variable
    
    require = function require(inFileName)
    {
        var aRequest
            ,aScript
            ,aScriptSource
            ;
    
        //setup the full relative filename
        inFileName = 
            window.location.protocol + '//'
            + window.location.host + '/'
            + inFileName;
    
        //synchronously get the code
        aRequest = new XMLHttpRequest();
        aRequest.open('GET', inFileName, false);
        aRequest.send();
    
        //set the returned script text while adding special comment to auto include in debugger source listing:
        aScriptSource = aRequest.responseText + '\n////# sourceURL=' + inFileName + '\n';
    
        if(noEval)//<== **TODO: Provide + set condition variable yourself!!!!**
        {
            //create a dom element to hold the code
            aScript = document.createElement('script');
            aScript.type = 'text/javascript';
    
            //set the script tag text, including the debugger id at the end!!
            aScript.text = aScriptSource;
    
            //append the code to the dom
            document.getElementsByTagName('body')[0].appendChild(aScript);
        }
        else
        {
            eval(aScriptSource);
        }
    };
    

提交回复
热议问题