首页 > 解决方案 > 交叉点观察者不读取页面加载后添加的新元素或条目

问题描述

交叉点观察者仅在现有元素上工作,但是当我通过按添加部分按钮添加新部分时,交叉点观察者似乎没有观察到我按下按钮时尝试再次运行观察者但它不起作用,我想我需要在代码中的某处重新分配 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>

标签: javascripthtmlcssarraysintersection-observer

解决方案


您的代码有两个区域存在问题:

  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)

};


推荐阅读