intersection observer 不读取页面加载后添加的新元素或条目

intersection observer does not read new elements or entries added after page load

intersection observer 仅在现有元素上工作,但是当我通过按添加部分按钮添加新部分时,intersection observer 似乎没有观察到我在按下时再次尝试 运行 观察者按钮但它不起作用,我想我需要在代码中的某处重新分配 section 变量,但我不知道我应该在哪一部分重新分配它

let sections = document.querySelectorAll("section");
let navList = document.getElementById("navbar__list");
const buildSecBtn = document.getElementById("newSection");
const main = document.querySelector("main");

let counter = 3;
const buildSection = () => {
    counter++
    const newSec =  ` <section id="section${counter}" data-nav="Section ${counter}">
        <div class="landing__container">
        <h2>Section ${counter}</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi fermentum metus faucibus lectus pharetra dapibus. Suspendisse potenti. Aenean aliquam elementum mi, ac euismod augue. Donec eget lacinia ex. Phasellus imperdiet porta orci eget mollis. Sed convallis sollicitudin mauris ac tincidunt. Donec bibendum, nulla eget bibendum consectetur, sem nisi aliquam leo, ut pulvinar quam nunc eu augue. Pellentesque maximus imperdiet elit a pharetra. Duis lectus mi, aliquam in mi quis, aliquam porttitor lacus. Morbi a tincidunt felis. Sed leo nunc, pharetra et elementum non, faucibus vitae elit. Integer nec libero venenatis libero ultricies molestie semper in tellus. Sed congue et odio sed euismod.</p>
        <p>Aliquam a convallis justo. Vivamus venenatis, erat eget pulvinar gravida, ipsum lacus aliquet velit, vel luctus diam ipsum a diam. Cras eu tincidunt arcu, vitae rhoncus purus. Vestibulum fermentum consectetur porttitor. Suspendisse imperdiet porttitor tortor, eget elementum tortor mollis non.</p>
        </div>
        </section>`
    main.insertAdjacentHTML("beforeend", newSec);

};

const buildNav = () => {
    navList.innerHTML ="";
    sections = document.querySelectorAll("section");
    sections.forEach(section => { 
        const navItem = `<li><a class="menu__link" data-nav="${section.id}" href="${section.id}">${section.dataset.nav}</a></li>`
        navList.insertAdjacentHTML("beforeend",navItem)
    });
};
buildNav();

let options = {
    threshold: .7
};



const sectionObserver = (entries, Observer) => {
    entries.forEach(entry => {
        const activeLink = navList.querySelector(`[data-nav=${entry.target.id}]`)
        if (entry.isIntersecting) {
            entry.target.classList.add("your-active-class")
            activeLink.classList.add("active__li")
        } else {
            entry.target.classList.remove("your-active-class")
            activeLink.classList.remove("active__li")
        };
    });
};

let Observer = new IntersectionObserver(sectionObserver, options);

sections.forEach(section => {
    Observer.observe(section)
});




buildSecBtn.addEventListener("click", () => {
    sections = document.querySelector("section")
    buildSection();
    buildNav();
    sectionObserver();
})
body {
    background: rgb(136,203,171);
    background: linear-gradient(0deg, rgba(136,203,171,1) 0%, rgba(0,13,60,1) 100%);
    margin: 0;
    font-family: 'Merriweather', serif;
    color: #fff;
}


h1 {
    font-family: 'Fira Sans', sans-serif;
    font-size: 3em;
    margin: 2em 1rem;
}

@media only screen and (min-width: 35em){
    h1 {
        font-size: 7em;
        margin: 2em 4rem 1em;
    }
}

h2 {
    border-bottom: 1px solid #cc1;
    font-family: 'Oxygen', Sans-Serif;
    font-size: 3em;
    color: #fff;
}

p {
    line-height: 1.6em;
    color: #eee;
}
main {
    margin: 10vh 1em 10vh;
}

.main-hero {
    min-height: 40vh;
    padding-top: 3em;
}

section {
    position: relative;
    min-height: 80vh;
}

.navbar__menu ul {
    padding-left: 0;
    margin: 0;
    text-align: right;
}

.navbar__menu li {
    display: inline-block;
}

.navbar__menu .menu__link {
    display: block;
    padding: 1em;
    font-weight: bold;
    text-decoration: none;
    color: #000;
    scroll-behavior: smooth;
}

.navbar__menu .menu__link:hover {
    background: #333;
    color: #fff;
    transition: ease 0.3s all;
}

.active__li {
    background-color: #333;
    color: #fff;
}

.page__header {
    background: #fff;
    position: fixed;
    top: 0;
    width: 100%;
    z-index: 5;
}

#newSection {
    background-color: black;
    position: sticky;
    width: 5rem;
    color: wheat;
}

.page__footer {
    background: #000;
    padding: 3em;
    color: #fff;
}

.page__footer p{
    color: #fff;
}


.landing__container {
    padding: 1em;
    text-align: left;
}

@media only screen and (min-width: 35em){
    .landing__container {
        max-width: 50em;
        padding: 4em;
    }
}

section:nth-of-type(even) .landing__container {
    margin-right: 0;
    margin-left: auto;
    text-align: right; 
}

section:nth-of-type(odd) .landing__container::before {
    content: '';
    background: rgba(255, 255, 255, 0.187);
    position: absolute;
    z-index: -5;
    width: 20vh;
    height: 20vh;
    border-radius: 50%;
    opacity: 0;
    transition: ease 0.5s all;
}

section:nth-of-type(even) .landing__container::before {
    content: '';
    background: rgb(255,255,255);
    background: linear-gradient(0deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.2) 100%);
    position: absolute;
    top: 3em;
    right: 3em;
    z-index: -5;
    width: 10vh;
    height: 10vh;
    border-radius: 50%;
    opacity: 0;
    transition: ease 0.5s all;
}

section:nth-of-type(3n) .landing__container::after {
    content: '';
    background: rgb(255,255,255);
    background: linear-gradient(0deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.2) 100%);
    position: absolute;
    right: 0;
    bottom: 0;
    z-index: -5;
    width: 10vh;
    height: 10vh;
    border-radius: 50%;
    opacity: 0;
    transition: ease 0.5s all;
}

section:nth-of-type(3n + 1) .landing__container::after {
    content: '';
    background: rgb(255,255,255);
    background: linear-gradient(0deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.2) 100%);
    position: absolute;
    right: 20vw;
    bottom: -5em;
    z-index: -5;
    width: 15vh;
    height: 15vh;
    border-radius: 50%;
    opacity: 0;
    transition: ease 0.5s all;
}


section.your-active-class {
    background: rgb(0, 0, 0);
    background: linear-gradient(0deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0) 100%);
}

section.your-active-class .landing__container::before {
    opacity: 1;
    animation: rotate 4s linear 0s infinite forwards;
}

section.your-active-class .landing__container::after {
    opacity: 1;
    animation: rotate 5s linear 0s infinite forwards reverse;
}

@keyframes rotate {
    from {
        transform: rotate(0deg)
                   translate(-1em)
                   rotate(0deg);
    }
    to {
        transform: rotate(360deg)
                   translate(-1em) 
                   rotate(-360deg);
    }
}
<!DOCTYPE >
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Manipulating the DOM</title>
  <!-- Load Google Fonts -->
  <link href="https://fonts.googleapis.com/css?family=Fira+Sans:900|Merriweather&display=swap" rel="stylesheet">  <!-- Load Styles -->
  <link href="css/styles.css" rel="stylesheet">
  <script src="/js/app.js" defer></script>
</head>
<body>
  <header class="page__header">
    <nav class="navbar__menu">
    
      <ul id="navbar__list"></ul>
    </nav>
  </header>
  <main>
    <header class="main__hero">
      <button id="newSection"> add section </button>
      <h1>Landing Page </h1>
    </header>
    <section id="section1" data-nav="Section 1" class="your-active-class">
      <div class="landing__container">
        <h2>Section 1</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi fermentum metus faucibus lectus pharetra dapibus. Suspendisse potenti. Aenean aliquam elementum mi, ac euismod augue. Donec eget lacinia ex. Phasellus imperdiet porta orci eget mollis. Sed convallis sollicitudin mauris ac tincidunt. Donec bibendum, nulla eget bibendum consectetur, sem nisi aliquam leo, ut pulvinar quam nunc eu augue. Pellentesque maximus imperdiet elit a pharetra. Duis lectus mi, aliquam in mi quis, aliquam porttitor lacus. Morbi a tincidunt felis. Sed leo nunc, pharetra et elementum non, faucibus vitae elit. Integer nec libero venenatis libero ultricies molestie semper in tellus. Sed congue et odio sed euismod.</p>

        <p>Aliquam a convallis justo. Vivamus venenatis, erat eget pulvinar gravida, ipsum lacus aliquet velit, vel luctus diam ipsum a diam. Cras eu tincidunt arcu, vitae rhoncus purus. Vestibulum fermentum consectetur porttitor. Suspendisse imperdiet porttitor tortor, eget elementum tortor mollis non.</p>
      </div>
    </section>
    <section id="section2" data-nav="Section 2">
      <div class="landing__container">
        <h2>Section 2</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi fermentum metus faucibus lectus pharetra dapibus. Suspendisse potenti. Aenean aliquam elementum mi, ac euismod augue. Donec eget lacinia ex. Phasellus imperdiet porta orci eget mollis. Sed convallis sollicitudin mauris ac tincidunt. Donec bibendum, nulla eget bibendum consectetur, sem nisi aliquam leo, ut pulvinar quam nunc eu augue. Pellentesque maximus imperdiet elit a pharetra. Duis lectus mi, aliquam in mi quis, aliquam porttitor lacus. Morbi a tincidunt felis. Sed leo nunc, pharetra et elementum non, faucibus vitae elit. Integer nec libero venenatis libero ultricies molestie semper in tellus. Sed congue et odio sed euismod.</p>

        <p>Aliquam a convallis justo. Vivamus venenatis, erat eget pulvinar gravida, ipsum lacus aliquet velit, vel luctus diam ipsum a diam. Cras eu tincidunt arcu, vitae rhoncus purus. Vestibulum fermentum consectetur porttitor. Suspendisse imperdiet porttitor tortor, eget elementum tortor mollis non.</p>
      </div>
    </section>
    <section id="section3" data-nav="Section 3">
      <div class="landing__container">
        <h2>Section 3</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi fermentum metus faucibus lectus pharetra dapibus. Suspendisse potenti. Aenean aliquam elementum mi, ac euismod augue. Donec eget lacinia ex. Phasellus imperdiet porta orci eget mollis. Sed convallis sollicitudin mauris ac tincidunt. Donec bibendum, nulla eget bibendum consectetur, sem nisi aliquam leo, ut pulvinar quam nunc eu augue. Pellentesque maximus imperdiet elit a pharetra. Duis lectus mi, aliquam in mi quis, aliquam porttitor lacus. Morbi a tincidunt felis. Sed leo nunc, pharetra et elementum non, faucibus vitae elit. Integer nec libero venenatis libero ultricies molestie semper in tellus. Sed congue et odio sed euismod.</p>

        <p>Aliquam a convallis justo. Vivamus venenatis, erat eget pulvinar gravida, ipsum lacus aliquet velit, vel luctus diam ipsum a diam. Cras eu tincidunt arcu, vitae rhoncus purus. Vestibulum fermentum consectetur porttitor. Suspendisse imperdiet porttitor tortor, eget elementum tortor mollis non.</p>
      </div>
    </section>
  </main>
  <footer class="page__footer">
    <p>&copy Udacity</p>
  </footer>

</body>
</html>

您的代码有两个方面存在问题:

  1. 您不需要在构建部分点击事件侦听器中调用 sectionObserver 函数。这是交集观察者对象内部使用的回调。

  2. 在您的 buildSection 函数中,传入对交集对象的引用,然后定位您需要观察的元素。

这些更改将解决您遇到的问题。

请参阅下面的相关片段。

buildSecBtn.addEventListener("click", () => {
    sections = document.querySelectorAll("section")
    buildSection(Observer);
    buildNav();
    //sectionObserver();
})

const buildSection = (_observer) => {
    ...
    main.insertAdjacentHTML("beforeend", newSec);
    const target = document.querySelector(`#section${counter}`);
    _observer.observe(target)

};