一个JS文件的多个页面

我通常把所有的JavaScript脚本放到一个文件中,例如scripts.js (HTTP请求越less越好)。 所以,正如所料,一些页面需要一些脚本,有些则不是。

要定位一个特定的页面,我使用类似于:

 if ($("body#share").length > 0) { // Place the logic pertaining to the page with ID 'share' here... } // The file / script continues... 

其他或更好的build议? 谢谢!

澄清:没有find合并多个JS文件到一个大文件和保留多个单独的JS文件之间的利弊。 答案肯定是“取决于情况”(我们知道)。 我的问题是,假设我所有的JS逻辑都放在一个大文件中,那么只有当相应的页面被加载时,我如何才能使一个特定的(块)脚本运行? 我曾经使用的一种方法是使用if ($('#id-of-target-element')) { /* run the script */} ; 有没有更好的办法?

我喜欢保罗·爱尔兰的方法 ……你不必完全按照它,但总的想法是非常稳固的。

这可能看起来像这样的例子

HTML

 <body id="share"> 

您的网页特定的JavaScript

 YourNamespace = { share : { init : function(){ // Place the logic pertaining to the page with ID 'share' here... } } } 

保罗·爱尔兰人的Javascript使魔术发生

 UTIL = { fire : function(func,funcname, args){ var namespace = YourNamespace; // indicate your obj literal namespace here funcname = (funcname === undefined) ? 'init' : funcname; if (func !== '' && namespace[func] && typeof namespace[func][funcname] == 'function'){ namespace[func][funcname](args); } }, loadEvents : function(){ var bodyId = document.body.id; // hit up common first. UTIL.fire('common'); // do all the classes too. $.each(document.body.className.split(/\s+/),function(i,classnm){ UTIL.fire(classnm); UTIL.fire(classnm,bodyId); }); UTIL.fire('common','finalize'); } }; // kick it all off here $(document).ready(UTIL.loadEvents); 

所以你直接在上面看到的行将启动以下

 YourNamespace.common.init() YourNamespace.share.init() YourNamespace.common.finalize() 

阅读他的博客文章和一些与之相关的变化。

类似的问题已经被问到,正确的答案是,而且总是会的

这取决于实际情况。

但是,如果您的担心是关于最小化往返时间 (RTT),那么肯定是这样

将外部脚本合并为尽可能less的文件可减lessRTT,并延迟下载其他资源。

保持尽可能less是件好事,但不一定要严格保存在一个文件中。

让我们来看看为什么是这样。

虽然将代码分区到模块化的软件组件是一个很好的工程实践,但是将模块一次一个地导入HTML页面可能会大大增加页面加载时间。 首先,对于空caching的客户端,浏览器必须为每个资源发出一个HTTP请求,并产生相关的往返时间。 其次,大多数浏览器会阻止在下载和parsingJavaScript文件时加载页面的其余部分。

这些图像更清楚地表明了为什么将大量JavaScript文件合并到更less的输出文件中可以显着减less延迟:

所有文件都是连续下载的,共需要4.46秒才能完成 所有文件都是连续下载的,共需要4.46秒才能完成。

将13个js文件合并成2个文件后: 同样的729千字节现在只需要1.87秒的下载 同样的729千字节现在只需要1.87秒的下载

在Siku-Siku.Com给出的澄清之后编辑:对不起! 我完全误解了你的问题。 我不知道有什么更好的方法来使一个特定的(块)脚本只有当相应的页面加载时运行。 我认为你的方式是够好的。

另一个select是你可以在HTML代码中

 <script> callYourJSFunctionHere(); /*Things you would want to happen on Page load*/ </script> 

这将遵循页面的正常stream程。 因此,如果您正在使用页面上的元素,则在浏览器加载所有元素之后,您需要将此<script>部分放置在页面的底部。

我不是100%确定这是比当前的解决scheme更有效,但另一方面,它会告诉某人看着你的HTML页面,当页面加载时将运行JavaScript。 这在维护方面可能会有所帮助….没有太多的猜测游戏是在页面加载时运行的脚本。

希望这可以帮助!

你的build议似乎没问题。 然而,我将使用HTML 5数据属性来标记每个页面,如下所示:

 <body data-title="my_page_title"> 

你可以通过检查这个属性(jQuery 1.4.3以上版本)来编写有条件的JavaScript代码:

 if ($("body").data("title") === "my_page_title") { // Place the logic pertaining to the page with title 'my_page_title' here... } 

这可以让您以合理的方式系统地将某个页面的所有代码分组

好。 让我们希望,代码示例会说得更好,而不是文本墙:


你的one-and-only.js文件:

 var MY_SITE = { // you have one namespace-object where you hold all your stuff main_page: { // inside you have smaller chunks, for specific pages or widgets // this one is for main page _init: function () { ... }, ... showSplashScreen: function () { ... } }, ... // but there are other pages contacts: { ... }, // or widgets cool_menu: { ... }, // and maybe you want to put common functions into dedicated block global_utilities: { ... }, // and of course - the loader _start: function () { // here we simply call one _init of the page module that was specified this[PAGE_TYPE]._init(); // and more tricky stuff - we can search the page for elements // that contain special data-attribute, collect them var widgets = $('[data-our-widget]').each().getAttributeValue( 'data-or-widget' ); // and then _init each of those widgets just like we did with main page widgets.forEach( function (v) { this[v]._init(); } } }; document.on('ready', MY_SITE.start); // here we assume some random js framework 

页面上的<script>标签:

 <script>var PAGE_TYPE = 'main_page';</script> <script src="one-and-only.js" /> 

您网页上的“魔术”元素:

 <div id="whatever" data-our-widget="cool_menu"> ... </div> 

免责声明: 这是高层次的概述! 实施细节可能也应该有所不同,具体取决于您的需求。

你的问题是问如何只加载基于特定页面的脚本块。 然而,既然你所说的目标是尽量减lessHTTP请求(和stream量,我假设),我认为我的独特(复杂)实现至less与这个问题有关,如果不是你的方法的一个很好的替代/补充。

我在一个embedded式应用程序中使用它,在这个应用程序中,我将所有的javascript文件合并为一个大的文件,以减lesshttp请求 我也必须弄清楚caching方法。 一个120kb的JavaScript文件,除了几张大小适中的图片需要一段时间才能加载,当使用一个准系统50kb的networking服务器。

首先,我使用YUI Compressor来压缩我的JavaScript文件,因为这是一个简单的方法来节省带宽。

我发现一个很酷的“function”是,如果你链接到任何东西(css,js,img),就像下面这样,你只需加载文件并忽略通过'?'的参数。 在'src'中:

 <script type="text/Javascript" src="js/all.js?2382a97f099f42cc43c1b616cd24f281"></script> 

现在,这个看似随机的数字和字母混杂,实际上就是javascript文件的md5校验和了! 然后,我修改了我的服务器的相关扩展(CSS,JS,IMG等)的响应头永不过期。 这个头文件不会被发送到html文件,因为我们总是想要这些文件的最新版本。

 Cache-Control:max-age=290304000 

这意味着客户端将只加载一次JavaScript文件,直到校验和发生变化。 caching通过查看整个请求,包括文件参数。

我实际上用C代码编译我的html / js / css /图像文件,所以我有一个perl脚本在编译之前自动将这些md5校验和插入到html文件中。 这显然不适用于你的情况,但只要你有一个服务器端的语言来帮助你,你可以用任何方式来处理它。 例如,你可以让php计算校验和,或者你可以让php将校验和存储在数据库或平面文件中,以便轻松查找它们。 为了标记php重新计算校验和,可以检查文件时间,或者删除数据库条目/平面文件。

我意识到这是很多前期工作,可能不是你所追求的,但对我来说却是奇妙的。 对我来说性能上的提升是不可思议的。 第一页加载非常慢(8.5秒),但在此之后,所有的脚本,CSS和图像都被caching了。 在相同的应用程序内加载的新页面下降到〜300ms。

如何testingwindow.location ? 这似乎是我明显的方式。

或者就像你已经做的那样,testing所需的元素在那里。 这是一个相当强大的方法,我没有看到任何错误的。

这将是一个高层次的概述,但我build议使用Backbone来组织每个“视图”(或页面)的逻辑。我使用根元素并更改该元素的类以在其他视图(或状态)的布局。 然后,您可以按类组织次要样式,并在ID下保留主要样式。

HTML

 <div id="layout" class="default"> <!-- PUT DEFAULT HTML IN HERE --> </div> <script id="shareTemplate" type="text/html"> <!-- PUT SHARE HTML IN HERE --> </script> 

CSS

 #layout { /* primary style */ } #layout.share { /* secondary style */ } 

JavaScript的

 window.LayoutView = Backbone.View.extend({ el: "#layout", shareTemplate: _.template($("#shareTemplate").html()), initialize: function() { this.render(shareTemplate, data); this.el.className = "share"; }, render: function(template, data) { $(this.el).html(template(data)); return this; } }); window.Layout = new LayoutView; 

正如你所说的那样,分割/合并文件的想法确实取决于情况。

我不认为可以有更好的解决scheme ,因为我已经看到许多大网站实施类似的战略,虽然比CSS更多的CSS。

例如(摘自facebook):

 <body class="hasLeftCol home fbx hasSlimHeader safari4 win Locale_en_US defaultScrollbar"> 

你可以从中获得更多的好处。 你可以有select地使用class属性将一些JS代码应用到页面组中。

即。

 if $('body.pagesThatHaveThisClass').length > 0) {.... code ...} if $('body#singlePageWithThisId').length > 0) {.... code ...} 

否则,有许多基于JS / jQ的菜单会自动为当前页面提供不同的样式。 您可以将window.location与特定的地址相匹配。

即。

 if (window.top.location.href == 'http://domain.com/mypage1.html') { .... code ....} 

甚至

 switch (window.top.location.href) { case 'http://domain.com/mypage1.html' : { .... code ....} case 'http://domain.com/mypage2.html' : { .... code ....} } 

我仍然会更喜欢你的技术,因为你可以将多个页面的代码组合在一起。 我能想到的使用第二种方法的唯一原因是当JS人无法访问页面的HTML来改变类/ ID等

希望这是你正在寻找的!

基于以下假设:您网站上的所有不同页面被分类或至less在逻辑上被分组到不同的“视图模型”中,以不同types的页面的不同视图模型(例如“search结果”,“博客post”,“首页“,”单一blogpost“等),你可以有一个单一的JavaScript文件,其中包含所有网站的共同脚本,并为每个视图模型(如果你认为是必要的)特定的脚本。

然后,您可以让服务器将视图模型的名称插入(例如)HTML数据标记,以供将来由JavaScript使用,并在主脚本库之后添加一个附加的脚本标记。

例如:

 <head> <!-- Two JavaScript files, one for the common functionality, and one for the view model specfic --> <script type="text/javascript" src="path/to/scriptslib.js"></script> <script type="text/javascript" src="path/to/viewmodel.front_page.js"></script> </head> <body data-view-model="front_page"> ... </body> 

scriptslib.js

 var GlobalSettings = {}, ViewModel = {}; $(function () { // Save the view model in a variable when the body's been loaded GlobalSettings.viewModel = $("body").attr("data-view-model"); // Assuming that the viewmodel JavaScript file has been loaded, call a method that it'll have by convention here ViewModel.initialize(); // Additionally, you can later test for specific view models and perform necessary actions, if needed if (viewModel === "front_page") { // ... } }); 

然后,在viewmodel.front_page.js (或任何其他视图模型文件)中:

 ViewModel.FrontPage = { // data and methods specific for this view model } ViewModel.initialize = function () { // do stuff specific for this view model this.FrontPage.someFunction(); }; 

请注意,我在这里描述的方法是依靠页面重新加载在网页之间切换的网站。 如果您使用Ajax在页面之间切换,则希望JavaScriptdynamic加载新视图模型并执行它们。

希望这可以为你工作;)

你可以按照你的方法,但是假设你的“鸡尾酒”JavaScript文件有20万行代码,并且把它包含在你的所有html文件中,甚至那些显示“404”或“500”带宽?

我select为每个HTML页面使用不同的js,以及跨多个页面使用的任何js将其转储到“utils.js”或任何你想调用它的地方,例如

 \www \pages \index.html \dashboard.html \account.html \ ... \scripts \index.js <- for index.html \dashboard.js <- for dashboard.html \account.js <- for account.html \ ... \utils.js|shared.js|sharedlib.js <- used by all pages 

所以基本上会导致:

  • 1请求的HTML
  • 1为页面脚本
  • 1为共享脚本,如果使用
  • n为CSS,但我认为是1

这只是我的两分钱..