[英]Load JavaScript on demand after lightbox is displayed
There is a button on every page of my site. 我网站的每个页面都有一个按钮。 When the button is clicked, a lightbox appears.
单击该按钮时,会出现一个灯箱。 The content of the lightbox is a form that relies on several JavaScript files including Angular.
灯箱的内容是一种依赖于包括Angular在内的多个JavaScript文件的表单。 Those JavaScript files are used only for the form and nowhere else on the site.
这些JavaScript文件仅用于表单,而不是网站上的其他任何地方。
In order to reduce page load time, my goal is to load the JavaScript files only after the user clicks the button. 为了减少页面加载时间,我的目标是仅在用户单击按钮后加载JavaScript文件。
Is there a best practice way of doing this? 这样做有最佳实践方法吗? Some options I can think of are:
我能想到的一些选择是:
Is there a better way? 有没有更好的办法?
By understanding your question, You want to lazy-load your js/css/html . 通过了解你的问题,你想懒惰加载你的js / css / html。 You can achieve this using two plugins
您可以使用两个插件实现此目的
Pros : 优点:
Cons : 缺点:
Pros : 优点:
OcLazyLoad
is used to load the dependency files and also to inject the AngularJS modules on the fly. OcLazyLoad
用于加载依赖项文件,也可以动态注入AngularJS模块。 Cons : 缺点:
So you can use Require.js
to load dependencies between modules listed in code and OcLazyLoad
to inject Angular module on fly . 因此,您可以使用
Require.js
加载代码和OcLazyLoad
列出的模块之间的依赖关系, OcLazyLoad
在运行时注入Angular模块。 And for your question regarding angular
itself on fly, I don't think you can do that in this case. 对于你在飞行中
angular
本身的问题,我认为在这种情况下你不能这样做。
Create script tag and attach script src and append it to head using javascript as below. 创建脚本标记并附加脚本src并使用javascript将其附加到头部,如下所示。
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', 'test.js');
document.head.appendChild(script);
Another way is to load js file using jquery ajax call like below. 另一种方法是使用jquery ajax调用加载js文件,如下所示。
$.ajax({
url: "test.js",
dataType: "script",
cache: true,
success: function() {
//Execute the function which you want...
}
});
Depending on your project's architecture and whether you are using/want to use a library like require.js could help. 根据您项目的体系结构以及您是否正在使用/想要使用像require.js这样的库可能有所帮助。
You can use it to require in the necessary modules for the lightbox. 您可以使用它来要求灯箱的必要模块。
The benefit of it in contrast to just dynamically loading a bunch of scripts, is that you will be able to manage dependencies between dynamically loading scripts and ensure they execute in a specific order if you need to (now or in the future). 与仅动态加载一堆脚本相比,它的好处是,您将能够管理动态加载脚本之间的依赖关系,并确保它们(如果您需要)(现在或将来)按特定顺序执行。
Another idea could be to call an ajax function on the click of the button that would return an html partial, containing the lightbox scripts that you would then append to the document so the scripts would again load dynamically. 另一个想法可能是在点击按钮时调用ajax函数,该按钮将返回html部分,包含灯箱脚本,然后您将附加到文档,以便脚本再次动态加载。
here is an example of how you achieve, I have implemented something similar on my websites and external JS are loaded only when required 这里有一个如何实现的例子,我在我的网站上实现了类似的东西,外部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>
The code also checks if the script is already loaded so it doesn't try to load with every click, you can easily scale to load multiple scripts, just give each script a different id and copy paste the below section for as many scripts you require. 代码还检查脚本是否已经加载,因此它不会尝试加载每次单击,您可以轻松扩展以加载多个脚本,只需为每个脚本提供不同的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);
I hope this helps 我希望这有帮助
For the dynamic script loading of the browser,you can use load-script package. 对于浏览器的动态脚本加载,您可以使用load-script包。
load-script appends a script node to the <head>
element in the dom. 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 } })
Alternatively you can combine the elements with the DOM 或者,您可以将元素与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>
Option 2 (dynamically loading scripts) is a good way to go - you probably just need to bootstrap angularjs correctly once it's been loaded. 选项2(动态加载脚本)是一个很好的方法 - 你可能只需要在加载后正确引导angularjs 。 A quick demo:
快速演示:
(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!"; } } })();
.angularContent { display: none; }
<button onclick="lazyLoadAngular()">Lazy load Angular</button> <div class="angularContent"> <div ng-controller="MyCtrl"> Angular is working: {{isAngularWorking}} </div> </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.