简体   繁体   English

在 JavaScript 中使用 *csi.min.js* 时如何访问元素?

[英]How can I access elements when I use *csi.min.js* in JavaScript?

I want to animate my navbar using JavaScript.我想使用 JavaScript 为我的导航栏设置动画。 I have created separate navbar.html and included it usingcsi.min.js .我创建了单独的 navbar.html 并使用csi.min.js包含它。 When I try to getElementById my navbar, show and hide button.当我尝试 getElementById 我的导航栏时,显示和隐藏按钮。 it returns null and when try it on dev console it works.它返回 null 并且在开发控制台上尝试它时它可以工作。

navbar.html:导航栏.html:

<nav>  
    <div class="site-mobile-menu collapse navbar-collapse show" id="main-navbar">
        navbar content
    </div>
<nav>

index.html:索引.html:

<div data-include="/src/navbar.html"></div>


<script src="/src/js/navbar.js"></script>

navbar.js:导航栏.js:

window.addEventListener("load", function() {
    // debugger;

    var mobNav = document.getElementById("main-navbar");
    var showNavBtn = document.querySelector("#show-nav");
    var hideNavBtn = document.getElementById("hide-nav");
    console.log(mobNav + " " + showNavBtn + " " + hideNavBtn);

    if (!mobNav == null || !showNavBtn == null || !hideNavBtn == null) {
        showNavBtn.onclick = function() {
            console.log("clicked");
            mobNav.classList.add("nav-shown");
        }
    } else {
        console.log("Error Opening Mobile Navbar");
    }
}, false);

When the window load , the elements such as #main-navbar are not in the DOM yet, csi adds them later.当 window load时, #main-navbar等元素还没有在 DOM 中, csi稍后添加它们。

Ideally, csi would give an option to notified when a [data-include] element is loaded but it doesn't.理想情况下,当加载[data-include]元素但没有加载时, csi会提供通知选项。 I can suggest 2 ways:我可以建议两种方法:

Re-implementing csi重新实现 csi

// this is csi re-implementation
function fetchTemplates() {
  return Promise.all(
      [...document.querySelectorAll('[data-include]')].map(async el => {
        const response = await fetch(el.getAttribute('data-include'));
        const html = await response.text();
        el.outerHTML = html;
    }));
}

// now you can call fetchTemplates and wait for it to done
(async () => {
  await fetchTemplates()
  console.log('templates are loaded. you can now find #main-navbar');
  console.log(document.querySelector('#main-navbar'));
})();

https://codesandbox.io/s/zealous-jepsen-12ihl?file=/re-implement-csi.html https://codesandbox.io/s/zealous-jepsen-12ihl?file=/re-implement-csi.html

Use MutationObserver to catch when csi replace the element with the fetched content.csi用获取的内容替换元素时,使用MutationObserver捕获。

const div = document.querySelector('[data-include="/src/navbar.html"]');
const observer = new MutationObserver(function (mutationsList, observer) {
  const templates = document.querySelectorAll('[data-include]');
  if (templates.length === 0) {
    console.log('all templates loaded, now you can find #main-navbar');
    console.log(document.querySelector('#main-navbar'));
  }
  // we no longer should observe the div
  observer.disconnect();
});
observer.observe(div.parentElement, {
  childList: true,
});

https://codesandbox.io/s/zealous-jepsen-12ihl?file=/index.html https://codesandbox.io/s/zealous-jepsen-12ihl?file=/index.html

Personally I recommend the first option because我个人推荐第一个选项,因为

  • It's a very old package implemented with very old API ( XMLHttpRequest ).这是一个非常古老的 package 实现了非常古老的 API ( XMLHttpRequest )。
  • If there are a lot of html elements in your site's DOM it might hurt performance.如果您站点的 DOM 中有很多 html 元素,则可能会损害性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM