HTML 页的 querySelector....>

querySelector across HTML Pages....>

我有一个格式如下的网站: 主页(名为 index.html)包含:

header 包含一个汉堡包图标,当点击子菜单和 sub-sub 菜单时,它会打开一个导航栏,主要由从 Nodejs 构建导航栏的 JS 脚本填充 & MySQL 调用结果。

因为 NavBar 相当复杂而且我的站点有很多不同的页面,所以我决定将整个 header 提取到它自己的 html 文件中(称为 header.html)并将 header.html 作为 index.html 的 header 导入到 div 中,这样可以更轻松地只维护一个 html 页面,而不是对所有 html 页。

我导入 header(称为 header.html)的方式是使用此函数(在一个名为 headerJS.js 的单独文件中):

      const headerPage = '/public/html/header.html';
      const headerDiv = document.getElementById('header_container');

      function loadHeader() {
        const xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function() {
            if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
            {
                headerDiv.innerHTML = xmlHttp.responseText;
            }
        };
        xmlHttp.open("GET", headerPage, true); // true for asynchronous
        xmlHttp.send(null);
      }
      loadHeader();

这很好用,因为它将我的 header.html 导入了我的 index.html 文件。 但是,当我单击汉堡包图标时,没有任何反应,控制台告诉我 toggle 为 null - toggle 是 const 的名称,它包含对汉堡包图标上 class 名称的引用,如下所示:

  /* Hide - Show the Menu Items if click on the Hamburger Icon */
  const toggle = document.querySelector('.navBarToggle');
  const menu = document.querySelector('.menu');
  
  function toggleMenu() {
      if (menu.classList.contains("active")) {
          menu.classList.remove("active");
          document.querySelector(".navbar").style.setProperty("padding", "0");
          toggle.querySelector("a").innerHTML = "<i class='fas fa-bars'></i>";
      } else {
          menu.classList.add("active");
          toggle.querySelector("a").innerHTML = "<i class='fas fa-times'></i>";
          document.querySelector(".navbar").style.setProperty("padding", "15px");
      }
  }
  toggle.addEventListener('click', toggleMenu);

如果我打开 header.html 并单击该图标,它会正常打开并加载整个导航栏,但如果我从 index.html 单击它,则什么也不会发生。

我想这可能是因为在 index.html 中加载 header.html 时,querySelector 找不到 .navBatToggle 因为 document.querySelector 正在寻找 index.html 中的 navBarToggle insted共 header.html.

我显然做了一些谷歌搜索,发现了一些听起来很有趣的东西,但我并没有完全理解它,因为我是 WebDev 的新手,关于共享网络工作者。这能解决我的问题吗?如果能,是否有资源以简单的方式解释它们是如何工作的——不太理解 MDN 上的解释)。

如果有其他解决方案,你能指出正确的方向吗? 我试图指向 window.querySelector 而不是 document.querySelector,认为 window 将适用于整个站点,而不仅仅是 index.html 文档,但它没有任何区别。

有没有办法通过单击 index.hmtl 页面中的图标,使查询选择器在 header.html 页面内查找 .navBarToggle class 而不是 document.querySelector 显然指的是 index.html?

提前谢谢你。 M.

你是对的。

您的想法看起来像 React.js 和任何其他想法的组成部分。

但是,在静态 html 页面的绘图中, 如果您将任何其他 html 文件加载为 Ajax,这些文件不会按照您的方式应用,这就是加载时间 - window.document 对象将在不同时间读取的原因。

啊,你认为你的方法是——加载为文本。没错,就是文字加载

我不推荐这些方式。

然后,您可以使用 AngularJS 否则。

这是我的建议。

谢谢。

事件侦听器不能添加到页面加载后创建的任何标记。您需要将事件侦听器添加到 #header-container 如果这是导航栏所附加的标签(或者更合乎逻辑的是页脚,但我只能按照您实际发布的内容进行 - 因此相应地进行调整)。

    /*
   Add the listener to a parent tag that has existed
   before the page has loaded
   */
   document.getElementById('header_container').addEventListener('click', toggleMenu);

向事件处理程序添加条件 toggleMenu(e),仅当用户单击 .navBarToggle

时才会接受
    if (clicked.matches('.navBarToggle')) {...

详情见event delegation

// Pass the Event Object
function toggleMenu(e) {
  // This is the tag the user actually clicked
  const clicked = e.target;
  const menu = document.querySelector('.menu');
  /*
  if clicked has class .navBarToggle
  then do whatever...
  */
  if (clicked.matches('.navBarToggle')) {
    if (menu.classList.contains("active")) {
      menu.classList.remove("active");
      document.querySelector(".navbar").style.setProperty("padding", "0");
      toggle.querySelector("a").innerHTML = "<i class='fas fa-bars'></i>";
    } else {
      menu.classList.add("active");
      toggle.querySelector("a").innerHTML = "<i class='fas fa-times'></i>";
      document.querySelector(".navbar").style.setProperty("padding", "15px");
    }
    // Wrap the whole thing in this if statement
  }
}

/*
Add the listener to a parent tag that has existed
before the page has loaded
*/
document.getElementById('header_container').addEventListener('click', toggleMenu);
   <!--Before Page Loads BEGIN-->
<div id='header_container'>
  <!--After Page Loaded BEGIN-->
  <button class='navBarToggle'></button>
  <nav class='menu'>
    <a></a>
  </nav><!--After Page Loaded END-->
</div><!--Before Page Loads END-->