多个页面的一个 JS 文件

IT技术 javascript filesystems
2021-03-01 17:24:52

我通常将所有 JavaScript 脚本放在一个文件中,例如scripts.js(HTTP 请求越少越好)。因此,正如预期的那样,有些页面需要一些脚本,有些则不需要。

要定位特定页面,我使用以下内容:

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

// The file / script continues...

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

澄清:不是在寻找将多个 JS 文件合并为一个大文件和保留多个单独的 JS 文件之间的利弊。答案肯定是“视情况而定”(我们知道)。我的问题是,假设我所有的 JS 逻辑都放在一个大文件中,我如何使特定(块)脚本在加载相应页面时运行我以前做的一种方法是使用if ($('#id-of-target-element')) { /* run the script */}; 有没有更好的办法?

6个回答

我喜欢Paul Irish 的方法……你不必完全遵循它,但总体思路是非常可靠的。

对于您的示例,它可能看起来像这样

html

<body id="share">

您的页面特定的 javascript

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

Paul Irish 的 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()

阅读他的博客文章以及从中链接的一些变体。

我将使用一个data-*属性,而不是使用正文 id,这将允许您在页面之间共享 JS 代码。例如,如果您有两个页面: page1 with:<body data-page="page1 category1">和 page2 with: <body data-page="page2 category1">,那么这些页面都共享 JS(category1),并具有特定于页面的 JS(page1 和 page2)。显然,您需要修改 JS 代码以按空间拆分数据页属性并循环遍历每个值,按顺序执行方法。
2021-04-28 17:24:52
这实际上非常好。我想添加与gist.github.com/bacloud14/826329ab11a3d4b00d95b9f0a97d6c6c非常相似的方法
2021-05-15 17:24:52

已经有人问过类似的问题,正确的答案是并且永远是

这取决于实际情况。

但是,如果您关心的是最小化往返时间(RTT),那么可以肯定的是

将外部脚本合并到尽可能少的文件中可以减少 RTT 和下载其他资源的延迟。

保持尽可能少是好的,但您不必严格将其保存在一个文件中。

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

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

这些图像更清楚地说明了为什么将多个 JavaScript 文件组合成更少的输出文件可以显着降低延迟:

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

将 13 个 js 文件折叠成 2 个文件后: 相同的 729 KB 现在只需 1.87 秒即可下载 同样的 729 KB 现在只需 1.87 秒即可下载

经 Siku-Siku.Com 澄清后编辑: 对不起!我完全误解了你的问题。我不知道有什么更好的方法可以使特定(块)脚本仅在加载相应页面时运行。我觉得你的方法已经够好了。

这有点过时了。大多数现代浏览器(包括 IE8+)都是并发下载 JS,而不是串行下载。
2021-04-20 17:24:52

你的建议看起来不错。然而,我会使用HTML 5 data- 属性来标记每个页面,如下所示:

<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...
}

这允许您以合理的方式系统地对某个页面的所有代码进行分组

这如何影响页面加载?
2021-04-23 17:24:52
甚至一个 ID 和 className: <body id="{{ controller }}" class="{{ action }}">
2021-05-13 17:24:52

另一种选择是您可以在 HTML 代码中

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

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

我不是 100% 确定这比您当前的解决方案更有效,但另一方面,它会告诉正在查看您的 HTML 页面的人在页面加载时将运行哪些 JavaScript。这可能对以后的维护有所帮助.... 页面加载时运行的脚本与其说是猜谜游戏,不如说是猜谜游戏。

希望这可以帮助!

+1 问题中(也很好)建议的方法的一个很好的替代方案。如果有像 jQuery 这样的框架在玩,那么你不必把代码放在页面底部,只需将它包装在一个$(document).ready()或类似的......
2021-05-06 17:24:52
@Stobor 两者不是一回事。$(document).ready() 必须执行 $(document),解析提供给 ready() 的函数,并在所有写入的地方调用 ready()。如果您将代码放在页面的末尾,那么在解析之前的所有内容之前它不会执行。此外, $(document).ready() 会等到整个页面加载完毕,包括图像等外部资源。将代码放在页面末尾的等价物(就功能而言,而不是处理顺序)只需设置 window.onload。
2021-05-08 17:24:52
@Skier88 :错误,document.ready(或 jQuery 的 $(function(){...}); )在加载 DOM 后立即运行传递的函数,它不会等待加载文件等外部内容!Window.onload 确实……见stackoverflow.com/questions/3698200/……
2021-05-12 17:24:52

行。让我们希望,代码示例比文字墙更能说明问题:


你的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>

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

+1 代码。我需要对此进行更多实验以消化。
2021-05-20 17:24:52