显示灯箱后按需加载JavaScript

时间:2016-09-15 16:58:25

标签: javascript jquery angularjs

我网站的每个页面都有一个按钮。单击该按钮时,会出现一个灯箱。灯箱的内容是一种依赖于包括Angular在内的多个JavaScript文件的表单。这些JavaScript文件仅用于表单,而不是网站上的任何其他地方。

为了减少页面加载时间,我的目标是仅在用户单击按钮后加载JavaScript文件。

有这样做的最佳做法吗?我能想到的一些选择是:

  1. 灯箱的内容是iframe和源代码html 文档包含脚本标记。
  2. 使用jquery.getscript方法(或类似方法)加载脚本
  3. 有更好的方法吗?

7 个答案:

答案 0 :(得分:13)

通过了解你的问题,你想懒惰加载你的js / css / html。你可以使用两个插件来实现这个目的

Require.js

优点:

  1. 模块之间的显式依赖关系,在代码中列出。
  2. 异步模块加载。
  3. 懒惰(按需)模块加载。
  4. 支持其中一个标准模块包装器(AMD),很多 社区模块实现它,因此您的模块可以依赖它们。
  5. 缺点:

    1. 我们无法动态注入AngularJS模块。这会加载文件 仅在需要时,即RequireJS仅加载javascript文件,但它不会在此新代码中注册新的角度模块和组件
    2. OcLazyLoad

      优点:

      1. OcLazyLoad用于加载依赖项文件以及注入 动态的AngularJS模块。
      2. 轻松加载Js和Css文件。
      3. 缺点:

        1. 我们无法维护依赖文件结构。
        2. 因此,您可以使用Require.js加载代码和OcLazyLoad中列出的模块之间的依赖关系,以便快速注入Angular模块。对于你在飞行中关于angular本身的问题,在这种情况下,我认为你不能这样做。

答案 1 :(得分:0)

创建脚本标记并附加脚本src并使用javascript将其附加到头部。

var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', 'test.js');
document.head.appendChild(script);

另一种方法是使用jquery ajax调用加载js文件,如下所示。

$.ajax({
    url: "test.js",
    dataType: "script",
    cache: true,
    success: function() {
        //Execute the function which you want...
    }
});

答案 2 :(得分:0)

取决于您的项目架构以及您是否正在使用/想要使用像require.js这样的库可能有所帮助。

您可以使用它来要求灯箱的必要模块。

与仅动态加载一堆脚本相比,它的好处是,您将能够管理动态加载脚本之间的依赖关系,并确保它们在需要时(现在或将来)按特定顺序执行

另一个想法可能是在单击按钮时调用ajax函数,该按钮将返回html部分,其中包含灯箱脚本,然后您将附加到文档中,以便脚本再次动态加载。

答案 3 :(得分:0)

这里有一个如何实现的例子,我在我的网站上实现了类似的东西,外部JS只在需要时加载

<script type='text/javascript'>
$(elem).click(function() {
var d= document;
var id = 'ext-js';
if (d.getElementById(id)) return;
var t = d.createElement('script');
t.type = 'text/javascript';
t.src = '//path to external js';
t.id = id;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(t);
});
</script>

代码还检查脚本是否已经加载,因此它不会尝试加载每次点击,您可以轻松扩展以加载多个脚本,只需为每个脚本提供不同的ID并复制粘贴以下部分你需要的脚本。

var t = d.createElement('script');
t.type = 'text/javascript';
t.src = '//path to external js';
t.id = id;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(t);

我希望这会有所帮助

答案 4 :(得分:0)

对于浏览器的动态脚本加载,您可以使用load-script包。

  • require('load-script')返回以下接口的函数:function(url [,opts] [,cb]){}
  • load-script将脚本节点附加到dom中的<head>元素。

    实施例

      var load = require('load-script')
    
      load('foo.js', function (err, script) {
      if (err) {
                // print useful message 
      }
      else {
            console.log(script.src);// Prints 'foo'.js' 
            // use script 
            // note that in IE8 and below loading error wouldn't be reported 
                }
           })
    

或者,您可以将元素与DOM结合起来

实施例

 <script type="application/javascript">
   function loadJS(file) {
     // DOM: Create the script element
     var jsElement = document.createElement("script");
     // set the type attribute
     jsElement.type = "application/javascript";
     // make the script element load file
     jsElement.src = file;
     // finally insert the element to the body element in order to load the script
     document.body.appendChild(jsElement);
   }
 </script>

   <button onclick="loadJS('jsFile1.js');">Load jsFile1.js</button>
   <button onclick="loadJS('jsFile2.js');">Load jsFile2.js</button>

答案 5 :(得分:0)

选项2(动态加载脚本)是一种很好的方法 - 一旦加载,您可能只需要bootstrap angularjs正确。快速演示:

&#13;
&#13;
(function() {
  "use strict";

  var angularLoaded = false;

  window.lazyLoadAngular = function() {
    if (angularLoaded) {
      return;
    }

    angularLoaded = true;

    var angularScript = document.createElement("script");
    angularScript.src = "//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js";
    document.body.appendChild(angularScript);
    angularScript.onload = function() {
      var angular = window.angular,
      angularContent = document.querySelector('.angularContent');

      // reveal angular content
      angularContent.style.display = "block";

      // in practice, you're probably dynamically loading your angular app scripts as well... but here we'll just create it once angular is available
      createAngularApp();
      
      // bootstrap angular on the content
      angular.bootstrap(angularContent, ["myApp"]);
    };
  };


  function createAngularApp() {
    var angular = window.angular;
    angular.module("myApp", [])
    .controller("MyCtrl", ["$scope", MyCtrl]);
    
    function MyCtrl($scope) {
      $scope.isAngularWorking = "Yes it is!";
    }
  }

})();
&#13;
.angularContent {
  display: none;
}
&#13;
<button onclick="lazyLoadAngular()">Lazy load Angular</button>

<div class="angularContent">
  <div ng-controller="MyCtrl">
    Angular is working: {{isAngularWorking}}
  </div>
</div>
&#13;
&#13;
&#13;

答案 6 :(得分:0)

你可以使用SystemJs通用动态模块加载器 - 在浏览器和NodeJS中加载ES6模块,AMD,CommonJS和全局脚本,我认为是非常强大的引擎。