Search code examples
javascriptintersection-observerjs-scrollintoview

Scroll element into view - top nav


I've this code in the snippet. It's an intersection Observer that tracks visible headers and adds an "active" class to the corresponding anchor tag in the top nav.

I would like to know if it's possible for the 'li' element with class "active" to also be scrolled into view.

I have tried a mutationObserver but I can't seem to make it work by any means.

Thanks!

  window.addEventListener('DOMContentLoaded', () => {

    const observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        const id = entry.target.getAttribute('id');
        if (entry.intersectionRatio > 0) {
          document.querySelector(`ul li a[href="#${id}"]`).parentElement.classList.add('active');
        } else {
          document.querySelector(`ul li a[href="#${id}"]`).parentElement.classList.remove('active');
        }
      });
    });
  
    // Track all sections that have an `id` applied
    document.querySelectorAll('h2[id]').forEach((h2) => {
      observer.observe(h2);
    });
    
  });
.table_of_content li{
    display:inline-flex;    
    margin-right: 20px;
    border-right: 2px solid black;
    padding-right:15px;
}
.table_of_content {
    border-left:none;
    z-index:1000;
    position: sticky;
    background-color:white;
    top: -1px;
    overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;

}
.table_of_content ul {
    margin: 0 auto;
    padding: 15px 0;
}

.table_of_content li.active > a {
    color:#ff9900;
    border-radius:5px;
    text-decoration:underline;
}
.section {
    max-width: 400px;
}
<div class="section">

    <div id="navigation12" class="table_of_content">
        <ul>
          <li><span>In this article</span></li>
          <li><a href="#header1">Heading 1</a></li>
          <li><a href="#header2">Heading 2</a></li>
          <li><a href="#header3">Heading 3</a></li>
          <li><a href="#header4">Heading 4</a></li>
          <li><a href="#header5">Heading 5</a></li>
          <li><a href="#header6">Heading 6</a></li>
          <li><a href="#header7">Heading 7</a></li>
          <li><a href="#header8">Heading 8</a></li>
        </ul>
      </div>

      <h2 id="header1">Header 1</h2>
      Lorem, ipsum dolor sit amet consectetur adipisicing elit. Culpa, ex. Eaque laboriosam fugiat debitis quisquam maiores ipsa aspernatur quam provident tenetur! Ipsa possimus illum provident. Quam, quaerat cum? Earum, reiciendis!
      <h2 id="header2">Header 2</h2>
      Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quia neque, repudiandae minus sit ratione expedita debitis hic sequi recusandae repellat? Eligendi, reiciendis voluptatem. Quidem tempore cupiditate obcaecati rem omnis quis commodi, rerum in delectus beatae eius nulla? Harum laborum, obcaecati ipsa officiis velit voluptatibus alias facilis at recusandae dolores molestias, autem quas. Repellendus ducimus soluta culpa dicta vel eveniet recusandae beatae odit id exercitationem ratione, nemo inventore, unde dolores eligendi quasi pariatur rem labore? Labore eum doloremque non illo, autem optio, excepturi ad quis reiciendis exercitationem necessitatibus fugit? Repellendus dolore ea magnam tempora in corporis sed totam et suscipit! Nihil?
      <h2 id="header3">Header 3</h2>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Architecto debitis, eligendi odit quam necessitatibus enim alias perferendis ut maxime quod quae ipsam minima voluptates voluptatibus at nobis, esse sequi beatae dolor quis. Quia officiis consequuntur, delectus dolore temporibus reprehenderit reiciendis sunt perspiciatis aspernatur, facere veniam. Ad corporis a voluptate provident soluta eveniet? Sunt est deserunt amet assumenda iste odit ad placeat! Vitae aliquam aliquid, molestiae cum aut unde velit laboriosam, perferendis rem asperiores pariatur quam optio quo nostrum saepe quia id dignissimos, consequatur molestias sed nulla ipsum? Molestias ab sapiente dolores ut. Dolor vero quod, distinctio laborum expedita incidunt repudiandae.
      <h2 id="header4">Header 4</h2>
      Lorem ipsum dolor sit amet consectetur, adipisicing elit. Illo consequatur, harum doloribus nisi vitae odit non deserunt et veritatis modi maxime repudiandae quasi cum eveniet inventore, fuga similique accusamus ad magnam alias qui optio delectus provident. Asperiores labore molestias quod laborum quasi sequi suscipit, optio tenetur esse soluta debitis eaque, doloribus reiciendis voluptatum iure dolorum quibusdam vel nihil quo ratione cupiditate necessitatibus aliquid obcaecati totam. Deserunt laudantium officiis et? Quas doloribus ipsum nam similique libero velit, tempora, delectus exercitationem cumque autem in iste, perspiciatis repudiandae a aliquid nobis ut voluptate corrupti unde recusandae voluptas rem aut nisi quam. Inventore, dolor.
      <h2 id="header5">Header 5</h2>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi explicabo, numquam aliquam minus eveniet vero neque ratione quidem voluptatem ipsa officiis soluta beatae dicta eligendi quo, nemo quaerat atque mollitia! Vitae mollitia voluptatum natus iusto eum quis debitis, similique illo, libero necessitatibus illum provident ad inventore sed consectetur molestias ipsa impedit obcaecati cumque et. Eveniet, molestiae deserunt rem earum dolor neque animi dignissimos dolore atque provident at numquam repellendus aliquam adipisci officia maxime fuga unde reiciendis saepe, sint culpa recusandae. At neque sapiente mollitia doloremque, architecto voluptatem delectus nulla laboriosam dicta quo animi magnam nisi in? Voluptatum harum et est!
      <h2 id="header6">Header 6</h2>
      Lorem, ipsum dolor sit amet consectetur adipisicing elit. Debitis distinctio nesciunt ut similique dicta cum est quis soluta harum quam, dolorem sequi repellat, atque provident eius. Atque ea quibusdam quo! Rem nihil pariatur ex magni odio modi sed unde quidem laboriosam doloremque repellat quo eum nemo eaque mollitia adipisci exercitationem ipsam blanditiis, consectetur atque libero totam quaerat officia soluta? Cum ipsam a incidunt cumque earum quod ea quibusdam vel ratione? Minima, id voluptate! Minima cumque quisquam, quod blanditiis quas et est laudantium placeat explicabo, dolorum velit, facilis cupiditate aspernatur nostrum dicta voluptatem adipisci suscipit debitis enim ullam commodi? Magni, consequatur.
      <h2 id="header7">Header 7</h2>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis alias soluta qui accusantium in repellendus, doloremque ullam quis esse optio veniam fugit doloribus mollitia ea, dolorum rem. Unde, adipisci. Totam vel harum maiores illo nobis culpa labore corrupti quasi atque consequuntur, minus odio deleniti iure, ab natus aliquam consectetur asperiores quia eveniet dolorem similique dolore eos quisquam. Quis, ipsam corrupti? Atque molestiae omnis asperiores dolores eos obcaecati aspernatur, recusandae eaque numquam consectetur aut corporis vitae dignissimos et ipsum eum odit id incidunt voluptate perferendis! Saepe tempora iste aspernatur enim quidem labore voluptatem id dolor quam esse! Quibusdam reiciendis inventore hic!
      <h2 id="header8">Header 8</h2>
      Lorem ipsum dolor, sit amet consectetur adipisicing elit. Est amet inventore quae eveniet sequi unde! Consequatur necessitatibus minima molestias quia vero recusandae unde veniam nobis qui saepe minus culpa ab rem aspernatur officiis earum et doloribus, provident eius asperiores. Harum consectetur odio blanditiis, sunt rerum necessitatibus exercitationem vero dolorem rem, cupiditate pariatur officiis repudiandae deserunt modi sequi aspernatur ratione libero perspiciatis illo cum saepe debitis tempora sapiente! Possimus modi nostrum ipsum placeat nam praesentium quos vero in, non dolor debitis dolorum nobis cum natus obcaecati, soluta reprehenderit sapiente. Eius ducimus placeat numquam incidunt magni repudiandae accusantium quasi alias vitae vero!

    </div>


Solution

  • I modified your code just a bit to get this working. The important part is where you add the active class to your current active element: currentActiveElement.scrollIntoView()

    This ensures, that the current element with the active class is always scrolled into the view.

      window.addEventListener('DOMContentLoaded', () => {
    
        const observer = new IntersectionObserver(entries => {
          entries.forEach(entry => {
            const id = entry.target.getAttribute('id');
            if (entry.intersectionRatio > 0) {
              let currentActiveElement = document.querySelector(`ul li a[href="#${id}"]`);
              currentActiveElement.parentElement.classList.add('active');
              currentActiveElement.scrollIntoView();
            } else {
              document.querySelector(`ul li a[href="#${id}"]`).parentElement.classList.remove('active');
            }
          });
        });
      
        // Track all sections that have an `id` applied
        document.querySelectorAll('h2[id]').forEach((h2) => {
          observer.observe(h2);
        });
        
      });
    .table_of_content li{
        display:inline-flex;    
        margin-right: 20px;
        border-right: 2px solid black;
        padding-right:15px;
    }
    .table_of_content {
        border-left:none;
        z-index:1000;
        position: sticky;
        background-color:white;
        top: -1px;
        overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    
    }
    .table_of_content ul {
        margin: 0 auto;
        padding: 15px 0;
    }
    
    .table_of_content li.active > a {
        color:#ff9900;
        border-radius:5px;
        text-decoration:underline;
    }
    .section {
        max-width: 400px;
    }
    <div class="section">
    
        <div id="navigation12" class="table_of_content">
            <ul>
              <li><span>In this article</span></li>
              <li><a href="#header1">Heading 1</a></li>
              <li><a href="#header2">Heading 2</a></li>
              <li><a href="#header3">Heading 3</a></li>
              <li><a href="#header4">Heading 4</a></li>
              <li><a href="#header5">Heading 5</a></li>
              <li><a href="#header6">Heading 6</a></li>
              <li><a href="#header7">Heading 7</a></li>
              <li><a href="#header8">Heading 8</a></li>
            </ul>
          </div>
    
          <h2 id="header1">Header 1</h2>
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Culpa, ex. Eaque laboriosam fugiat debitis quisquam maiores ipsa aspernatur quam provident tenetur! Ipsa possimus illum provident. Quam, quaerat cum? Earum, reiciendis!
          <h2 id="header2">Header 2</h2>
          Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quia neque, repudiandae minus sit ratione expedita debitis hic sequi recusandae repellat? Eligendi, reiciendis voluptatem. Quidem tempore cupiditate obcaecati rem omnis quis commodi, rerum in delectus beatae eius nulla? Harum laborum, obcaecati ipsa officiis velit voluptatibus alias facilis at recusandae dolores molestias, autem quas. Repellendus ducimus soluta culpa dicta vel eveniet recusandae beatae odit id exercitationem ratione, nemo inventore, unde dolores eligendi quasi pariatur rem labore? Labore eum doloremque non illo, autem optio, excepturi ad quis reiciendis exercitationem necessitatibus fugit? Repellendus dolore ea magnam tempora in corporis sed totam et suscipit! Nihil?
          <h2 id="header3">Header 3</h2>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Architecto debitis, eligendi odit quam necessitatibus enim alias perferendis ut maxime quod quae ipsam minima voluptates voluptatibus at nobis, esse sequi beatae dolor quis. Quia officiis consequuntur, delectus dolore temporibus reprehenderit reiciendis sunt perspiciatis aspernatur, facere veniam. Ad corporis a voluptate provident soluta eveniet? Sunt est deserunt amet assumenda iste odit ad placeat! Vitae aliquam aliquid, molestiae cum aut unde velit laboriosam, perferendis rem asperiores pariatur quam optio quo nostrum saepe quia id dignissimos, consequatur molestias sed nulla ipsum? Molestias ab sapiente dolores ut. Dolor vero quod, distinctio laborum expedita incidunt repudiandae.
          <h2 id="header4">Header 4</h2>
          Lorem ipsum dolor sit amet consectetur, adipisicing elit. Illo consequatur, harum doloribus nisi vitae odit non deserunt et veritatis modi maxime repudiandae quasi cum eveniet inventore, fuga similique accusamus ad magnam alias qui optio delectus provident. Asperiores labore molestias quod laborum quasi sequi suscipit, optio tenetur esse soluta debitis eaque, doloribus reiciendis voluptatum iure dolorum quibusdam vel nihil quo ratione cupiditate necessitatibus aliquid obcaecati totam. Deserunt laudantium officiis et? Quas doloribus ipsum nam similique libero velit, tempora, delectus exercitationem cumque autem in iste, perspiciatis repudiandae a aliquid nobis ut voluptate corrupti unde recusandae voluptas rem aut nisi quam. Inventore, dolor.
          <h2 id="header5">Header 5</h2>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi explicabo, numquam aliquam minus eveniet vero neque ratione quidem voluptatem ipsa officiis soluta beatae dicta eligendi quo, nemo quaerat atque mollitia! Vitae mollitia voluptatum natus iusto eum quis debitis, similique illo, libero necessitatibus illum provident ad inventore sed consectetur molestias ipsa impedit obcaecati cumque et. Eveniet, molestiae deserunt rem earum dolor neque animi dignissimos dolore atque provident at numquam repellendus aliquam adipisci officia maxime fuga unde reiciendis saepe, sint culpa recusandae. At neque sapiente mollitia doloremque, architecto voluptatem delectus nulla laboriosam dicta quo animi magnam nisi in? Voluptatum harum et est!
          <h2 id="header6">Header 6</h2>
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Debitis distinctio nesciunt ut similique dicta cum est quis soluta harum quam, dolorem sequi repellat, atque provident eius. Atque ea quibusdam quo! Rem nihil pariatur ex magni odio modi sed unde quidem laboriosam doloremque repellat quo eum nemo eaque mollitia adipisci exercitationem ipsam blanditiis, consectetur atque libero totam quaerat officia soluta? Cum ipsam a incidunt cumque earum quod ea quibusdam vel ratione? Minima, id voluptate! Minima cumque quisquam, quod blanditiis quas et est laudantium placeat explicabo, dolorum velit, facilis cupiditate aspernatur nostrum dicta voluptatem adipisci suscipit debitis enim ullam commodi? Magni, consequatur.
          <h2 id="header7">Header 7</h2>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis alias soluta qui accusantium in repellendus, doloremque ullam quis esse optio veniam fugit doloribus mollitia ea, dolorum rem. Unde, adipisci. Totam vel harum maiores illo nobis culpa labore corrupti quasi atque consequuntur, minus odio deleniti iure, ab natus aliquam consectetur asperiores quia eveniet dolorem similique dolore eos quisquam. Quis, ipsam corrupti? Atque molestiae omnis asperiores dolores eos obcaecati aspernatur, recusandae eaque numquam consectetur aut corporis vitae dignissimos et ipsum eum odit id incidunt voluptate perferendis! Saepe tempora iste aspernatur enim quidem labore voluptatem id dolor quam esse! Quibusdam reiciendis inventore hic!
          <h2 id="header8">Header 8</h2>
          Lorem ipsum dolor, sit amet consectetur adipisicing elit. Est amet inventore quae eveniet sequi unde! Consequatur necessitatibus minima molestias quia vero recusandae unde veniam nobis qui saepe minus culpa ab rem aspernatur officiis earum et doloribus, provident eius asperiores. Harum consectetur odio blanditiis, sunt rerum necessitatibus exercitationem vero dolorem rem, cupiditate pariatur officiis repudiandae deserunt modi sequi aspernatur ratione libero perspiciatis illo cum saepe debitis tempora sapiente! Possimus modi nostrum ipsum placeat nam praesentium quos vero in, non dolor debitis dolorum nobis cum natus obcaecati, soluta reprehenderit sapiente. Eius ducimus placeat numquam incidunt magni repudiandae accusantium quasi alias vitae vero!
    
        </div>