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

Time:11-11

intersection observer is only working on already existing elements, but when I add a new section by pressing add section button the intersection observer does not seem to observe I tried to run the observer again when I press the button but it does not work, I think I need to reassign the section variable somewhere in the code but I don't know in what part should I reassign it

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 >
        <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  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>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

There are two areas of your code where there are issues:

  1. You do not need to call sectionObserver function within the build section click event listener. That is a callback to be used by the intersection observer object internally.

  2. In your buildSection function, pass in a reference to the intersection object and then target the element you need to observe.

Those changes would resolve the issue you are experiencing.

See relevant snippets below.

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)

};

  • Related