我网站的每个页面都有一个按钮。单击该按钮时,会出现一个灯箱。灯箱的内容是一种依赖于包括Angular在内的多个JavaScript文件的表单。这些JavaScript文件仅用于表单,而不是网站上的任何其他地方。
为了减少页面加载时间,我的目标是仅在用户单击按钮后加载JavaScript文件。
有这样做的最佳做法吗?我能想到的一些选择是:
有更好的方法吗?
答案 0 :(得分:13)
通过了解你的问题,你想懒惰加载你的js / css / html。你可以使用两个插件来实现这个目的
优点:
缺点:
优点:
OcLazyLoad
用于加载依赖项文件以及注入
动态的AngularJS模块。缺点:
因此,您可以使用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包。
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正确。快速演示:
(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;
答案 6 :(得分:0)
你可以使用SystemJs,通用动态模块加载器 - 在浏览器和NodeJS中加载ES6模块,AMD,CommonJS和全局脚本,我认为是非常强大的引擎。