开发者问题收集

如何为多个页面设置一个主 JavaScript 文件?

2020-08-21
6511

我有一个小应用程序,有两个页面:登录页面和主页。我的问题是,当我对两个页面只使用一个主 JavaScript 文件(如建议的那样)时,我会收到很多 ReferenceError,因为一个页面上的某些变量未在另一个页面上定义...

例如:

登录页面的代码行

copyrightYear.textContent = new Date().getFullYear();

主页投诉

Uncaught TypeError: Cannot set property 'textContent' of null

我该如何解决这个问题?不要告诉我每次都必须说 if(copyrightYear) { do stuff > ,如果我必须对每个变量都这样做,那简直是一场噩梦

2个回答

给您两个答案:

建议不是命令

My problem is that when I use just one main JavaScript file for both pages (like it's recommanded)

这是 非常 普遍的建议。它并不适用于所有情况。在不会使用该代码的页面中加载代码是没有意义的。

如果您的代码在两个页面中都使用,并且还有页面特定代码,那么拥有两个页面共享的文件和页面特定文件 绝对没问题

<script src="main.js"></script>
<script src="page1.js"></script>

如果您真的担心额外的 HTTP 请求(现在的问题比以前少了很多),请使用模块和捆绑程序,例如 Webpack 或 Rollup,它将创建一个捆绑包,将主模块与页面 1 的模块结合起来用于页面 1,以及另一个捆绑包,将主模块与页面 2 的模块结合起来用于页面 2。

但即便如此,如果您希望用户在合理的时间范围内从页面 1 转到页面 2,额外的 HTTP 请求可能对您的用户 更好 。原因是,如果您有 main.jspage1.js / page2.js 并且您允许缓存它们,那么当用户转到页面 1 时,他们会获取 main.jspage1.js ,然后当他们转到页面 2 时, main.js 会从其本地缓存中取出,他们只需加载 page2.js 。相反,如果您为每个页面设置一个单独的包文件,那么当从页面 1 转到页面 2(或反之亦然)时,他们必须重新下载所有通用代码。但是,如果您希望访问者访问 页面 1 或页面 2,但不访问另一个,则可以使用特定于页面的包来节省 HTTP 请求。

实际上没有一刀切的解决方案。 :-) 有各种各样的考虑因素。

请注意,HTTP/1.1 使额外的 HTTP 请求更加高效,并且几乎得到普遍支持,而 HTTP/2 使它们 更加 高效,有效地消除了在页面启动时减少 HTTP 请求数量的情况。所有主流现代浏览器都支持 HTTP/2,最新的 Web 服务器也是如此。

将每个页面的代码放在一个函数中

如果您确实想保留单个页面,请将特定于每个页面的代码放在这些页面的函数中,然后让文件主要部分中的代码根据 location.pathname 调用适当的函数。

T.J. Crowder
2020-08-21

您已经搞清楚了,您必须检查每个变量。但通常使用函数并仅在需要时调用这些函数会更方便。

例如,假设您要设置一些 copyrightYear(尽管这不应该通过 JS 设置,但您应该在后端生成它以将其放在源代码中)

您有类似以下内容:

function updateYear() {
  // here you do your magic of selecting the element, setting the year, whatever.
}

// another function, totally unrealted to updateYear()
function toggleMenu() {
  // some function where you toggle the menu if you click somewhere
  // like: button.addEventListener('click', () => {} );
}

并且在 JS 文件中,您有一个块,您可以在其中调用所有这些函数:

if (document.querySelectorAll('.elementForYear') {
  updateYear(); // here we call it because we are sure this element exists... so everything inside function must work
}
if (document.querySelector('.myMenu') {
  toggleMenu(); // if the element myMenu exists, we know we can add these toggle Functionality.
}  

您还可以在函数内部添加这些 if 并调用该函数,无论是否需要它,这取决于您和编码指南。

通常,我发现让一个函数仅依赖于一个(或最多两到三个元素,如果它是其他元素的切换)是有意义的...然后您只需检查一个元素。如果这个元素存在,您可以继续调用该函数。

cloned
2020-09-11