在单个 JavaScript 文件中处理多个页面上的事件的正确方法是什么?

What is the correct way to handle events on multiple pages in a single JavaScript file?

本文关键字:事件 是什么 方法 文件 JavaScript 单个 处理      更新时间:2023-09-26

(不使用JQuery)

为了正确地提出这个问题,我做了一个简单的例子,一个由三个页面A,B和C组成的网站。每个页面都链接到一个JavaScript文件。JavaScript 文件链接在 body 标签的底部。下面是其中一个 html 页面的示例:

<html>
    <head>
        <title>Page A</title>
        <link rel="stylesheet"
              type="text/css"
              href="temp.css">
        </link> 
    </head>
    <body>
        <h1 id = "headingA">Page A</h1>
        <button id="enterA">Enter</button>
        <script src = temp.js>
        </script>
    </body>
</html>

所有三个页面看起来都一样,除了"A"明显替换了"B"和"C"。

//this button is on page A
var btnA = document.getElementById("enterA");
btnA.onclick = function () {
    "use strict";
    window.console.log("Button A Pressed");
    window.open("/pageB.html", "_self");
};
//this button is on page B
var btnB = document.getElementById("enterB");
btnB.onclick = function () {
    "use strict";
    window.console.log("Button B Pressed");
    window.open("/pageC.html", "_self");
};
//this button is on page C
var btnC = document.getElementById("enterC");
btnC.onclick = function () {
    "use strict";
    window.console.log("Button C Pressed");
    window.alert("Button C Pressed");
};

显然,这是行不通的,因为一次只能加载一个页面,因此脚本尝试在未加载的页面上抓取的元素将导致脚本错误。

我可以想到几种方法来解决这个问题,但我觉得自己像个黑客,我在这里问的原因是最佳实践解决方案,因为相信这必须是实践开发人员的第二天性(与我不同)。

没有理由将特定于一个页面的 JavaScript 保存在一个跨所有页面加载的.js文件中。事实上,这是有潜在风险的,因为如果您引入具有相同名称的元素,您可能会有模棱两可和意外的行为。你可以(而且通常会,在非平凡的项目上)每页加载多个 JavaScript 文件,所以虽然有很多方法可以构建你的代码,但这里有一个想法,我想说是常见的做法:

将共享的、非特定于页面的 JavaScript 保存在一个文件中,例如

  • 常见.js

然后,为每个页面创建一个特定于页面的 JavaScript 文件:

  • 页A.js
  • 页B.js
  • 页面C.js

现在一样,在所有页面上加载 Common.js 文件,但在每个页面上,还要加载包含该页面特定功能的脚本文件。正如评论中提到的,你也可以编写你的JavaScript来检查有问题的元素是否存在并采取相应的行动,但我鼓励你开始围绕代码组织养成更好的习惯,并完全避免这个问题。

每个都包装在空检查中,如下所示。 如果页面上不存在该按钮,则不会尝试绑定 onClick 事件。

//this button is on page A
var btnA = document.getElementById("enterA");
if (btnA != null) {
    btnA.onclick = function () {
        "use strict";
        window.console.log("Button A Pressed");
        window.open("/pageB.html", "_self");
    };
}

我同意斯潘利的回答,因为这是一种可能性。

以下是需要考虑的其他一些选项:

  • 如果 onclick 处理程序中除了链接之外没有任何其他功能,则可以考虑在 HTML 页面中简单地包含链接,样式为按钮:

    <a href="/pageB.html" class="button">Enter</a>
    

    。然后在样式表中:

    a.button {
      /* styles to make links look like a button */
    }
    
  • 另一种选择是在按钮上有一个通用id,并在按钮的某个属性中包含链接,如下所示:

    最好在自定义属性名称前面加上 data- 1

    <button id="enter" data-href="/pageB.html">Enter</button>
    

    。或使用其他一些自定义属性来标识目标资源

    <button id="enter" data-target="enterA">Enter</button>
    

    。然后抽象脚本,读出相关属性,如下所示:

    var btn = document.getElementById( 'enter' );
    // I like to use addEventListener in stead of the direct .onclick handler
    btn.addEventListener( 'click', function( e ) {
      // when using data-href:
      window.open( this.dataset.href, "_self" );
      // when using data-target:
      switch( this.dataset.target ) {
        case 'enterA':
          window.open( "/pageB.html", "_self" );
        break;
        case 'enterB':
          window.open( "/pageC.html", "_self" );
        break;
        case 'enterC':
          // do something else?
        break;
      }
      // or, you could also use a map with targets, in stead of a switch statement, of course:
      var targets = {
        'enterA': '/pageB.html',
        'enterB': '/pageC.html',
        'enterC': 'some other page',
      }
      if( targets.hasOwnProperty( this.dataset.target ) ) {
        window.open( targets[ this.dataset.target ], "_self" );
      }
      // etc.
    } );
    

1.) 有关数据属性的更多信息