根据条件向我的应用程序动态添加脚本

时间:2019-02-07 11:22:07

标签: javascript html angularjs ionic-framework

我创建了一个plunker与我的问题相关。

我有一个包含多个页面的应用程序,该应用程序从登录页面开始。当我的应用程序首次加载时,它会加载[ string.split() for string in a ] #=> [['rabbit', 'panda', 'bird', 'rabbit'], ['bird', 'gecko', 'ant', 'panda'], ['wasp', 'snake', 'gecko', 'ant']] 并运行我设置的名为index.html的脚本,然后将其重定向到config.js。这只是管理我要在整个应用中使用的一些设置。

login.html中,我设置了config.js,我想在window.localStorage.setItem("use_minified",true)中使用它来确定是否为我的应用程序使用缩小的文件。

我看了几个问题,例如:

Dynamically add script tag with src that may include document.write

我曾经尝试过(如您在我的扬声器中所见),但是却遇到了错误:

  

未捕获的错误:[$ injector:modulerr]无法实例化模块   myAppdue至:错误:[$ injector:nomod]模块'myApp'不是   可用!您可能拼错了模块名称,或者忘记了加载它。   如果注册模块,请确保将依赖项指定为   第二个参数。

2 个答案:

答案 0 :(得分:1)

我的答案

我将index.html保持不变,以便它调用config.js并重定向到login.html

我将这些添加到了我的config.js文件中:

function init_scripts() {
    var jsDirectory = "js";
    var jsExtension = ".js";

    if (JSON.parse(window.localStorage.config).use_minified) {
        jsDirectory = "js_min";
        jsExtension = ".min.js";
    }

    loadScripts([
        "../lib/ionic/js/ionic.bundle.js",
        "../cordova.js",
        "https://cdnjs.cloudflare.com/ajax/libs/angularjs-toaster/1.1.0/toaster.min.js",
        "/lib/ionic-datepicker-fork-ionic1/dist/ionic-datepicker.bundle.min.js",
        "/" + jsDirectory + "/app" + jsExtension,
        "/" + jsDirectory + "/page1" + jsExtension,
        "/" + jsDirectory + "/page2" + jsExtension,
        "/" + jsDirectory + "/page3" + jsExtension

    ], null);
}

function loadScripts(array, callback) {
    var loader = function(src, handler) {
        var script = document.createElement("script");
        script.src = src;
        script.onload = script.onreadystatechange = function() {
            script.onreadystatechange = script.onload = null;
            handler();
        }
        var head = document.getElementsByTagName("head")[0];
        (head || document.body).appendChild(script);
    };

    (function run() {
        if (array.length != 0) {
            loader(array.shift(), run);
        } else {
            callback && callback();
        }
    })();
}

在我的<head>的{​​{1}}中,我删除了所有login.html标签并替换了它们:

<script>

这似乎运行得很好。我对样式表也做了类似的操作,如您所见,我调用了使用相同概念的函数<head> <script src="/js/config.js"></script> <!-- Functions found in config.js --> <script> init_scripts(); init_stylesheets(); </script> </head>

答案 1 :(得分:0)

您应该使用诸如requirejs之类的任何依赖项/模块加载器,以使依赖项加载在应用程序中更有条理。

要在DOM中动态加载脚本,可以使用如下函数-

var loadScript = function (url, callback) {
    var script = document.createElement("script");
    script.type = "text/javascript";

    if (script.readyState) {  //IE
        script.onreadystatechange = function () {
            if (script.readyState == "loaded" || script.readyState == "complete") {
                script.onreadystatechange = null;

                console.log(url + ' loaded successfully.');

                if ($.isFunction(callback)) {
                    callback();
                }
            }
        };
    } else {  //Others
        script.onload = function () {
            console.log(url + ' loaded successfully.');

            if ($.isFunction(callback)) {
                callback();
            }
        };
    }

    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
}

此函数应驻留在任何预先加载的脚本(即config.js)中。如果不需要,可以避免第二个参数。脚本加载后,如果需要一次操作,它只是为您提供了一种执行某项功能的工具。

这是使用myApp的脚本加载功能的演示调用-

var myApp = angular.module('myApp', ['ionic','ionic-datepicker','ui.router','toaster','ngAnimate']);

myApp.run(function(){
  config.loadScript('yourScriptPath', null);
})
.config(function($stateProvider, $urlRouterProvider) {

    //==========================================================================//
    // Build the pages up for the application with their respective controllers //
    //==========================================================================//
    $stateProvider
    .state('login', {
        cache               : false,
        url                 : '/',
        controller          : "LoginController",
        templateUrl         : 'login.html'
    })
    .state('page1', {
        cache               : false,
        url                 : '/page1',
        controller          : "page1controller",
        templateUrl         : 'page1.html'
    })
    .state('page2', {
        cache               : false,
        url                 : '/page2',
        controller          : "page2controller",
        templateUrl         : 'page2.html'
    })
    .state('page3', {
        cache               : false,
        url                 : '/page3',
        controller          : "page3controller",
        templateUrl         : 'page3.html'
    });

    $urlRouterProvider.otherwise('/');
});

谢谢