<div class="container">
  <div class="toc js-toc">
    <p>Table of Contents</p>
    
    <ul class="js-toc-list">
      <li>
        <a href="#setup">Setup</a>
      </li>
      <li>
        <a href="#javascript">JavaScript</a>
        
        <ul>
          <li>
            <a href="#npm">npm</a>
          </li>
          <li>
            <a href="#bower">bower</a>
          </li>
        </ul>
      </li>
      <li>
        <a href="#css">CSS</a>
        <ul>
          <li>
            <a href="#sass">Sass</a>
          </li>
        </ul>
      </li>
    </ul>
  </div>
  
  <div>
    <h1>Scroll Spy Table of Contents</h1>
    
    <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Labore hic omnis vitae error blanditiis amet corporis sit est mollitia inventore rem, temporibus, voluptate incidunt accusamus eius illum nulla, assumenda sint.
    Earum animi at magni amet aliquid tempora, iusto temporibus, provident odit tempore blanditiis modi voluptatem neque perferendis incidunt ad ipsa placeat laudantium nam sit officia. Quos aperiam aspernatur magni inventore.
    Natus, facere ex molestiae culpa, sunt officiis sit ipsam voluptatem, pariatur voluptas omnis et hic doloremque iste labore dolore? Labore, porro cum voluptas eum tenetur iure pariatur fugiat iusto quia?</p>
    
    <h2 id="setup">Setup</h2>
    
    <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Repellendus sapiente consequatur sequi ipsa! Minima asperiores labore suscipit culpa eveniet ducimus? Voluptatibus in numquam dolorem illum aperiam vero natus pariatur illo.</p>
    
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nostrum voluptatibus minus sunt excepturi ad officia obcaecati dignissimos? Ad, quo laboriosam, numquam temporibus vitae cumque non pariatur maxime reprehenderit dolorum accusamus.
    Rem, quod maiores fugit laboriosam voluptatum corrupti deserunt hic vel molestiae earum iusto doloribus impedit rerum consectetur dolore beatae repellendus eum, magnam quia, atque voluptas modi. Deleniti officia voluptate reiciendis.
    Nisi illum accusantium iusto voluptates odio, explicabo culpa dignissimos aut hic soluta amet, aperiam nesciunt laboriosam atque. Natus, beatae sed delectus impedit aut odit, eius nesciunt officiis omnis ipsam non.
    Ex, porro repellendus nesciunt aspernatur alias maxime voluptates doloremque fugiat. Molestias at veritatis, voluptatum eaque ab impedit quaerat numquam, aperiam necessitatibus fugit sed, consequuntur distinctio nobis libero ipsum iure excepturi.
    Nostrum, libero qui beatae illo perferendis enim blanditiis voluptatum quo veniam ex nam reprehenderit corrupti vitae harum id! Ipsa totam esse aliquam dolor magnam nihil praesentium cum libero dolorum sint.
    Architecto facilis iste repudiandae earum quidem quos aliquid aut omnis fugit esse doloremque laudantium repellat quasi voluptates in ut atque quod optio quae, iure fuga asperiores eius illo! Dicta, voluptatibus.
    Saepe tempore ad eveniet quae sed molestias dicta id velit, repellat animi. Officia labore commodi iusto libero nisi ut, totam pariatur! Aperiam facere magnam mollitia in inventore eveniet dolore enim?
    Ad maxime amet voluptate nobis magni sequi voluptatibus fugit, quos eligendi natus, unde dolores quaerat quod repellat voluptatum rem possimus ratione! Perferendis praesentium sint est debitis. Impedit doloribus nulla cumque?
    Officiis repudiandae commodi quasi reprehenderit ex dolorum blanditiis quia, nobis voluptates! Facilis cupiditate atque ullam, commodi laboriosam a cum nam omnis, maiores accusamus enim tempore impedit rerum amet, qui voluptatem.
    Laborum illum quis deleniti quia ipsam mollitia nam iste suscipit doloribus eum? Fugit nisi voluptatem eaque tenetur exercitationem quasi quis, enim animi dignissimos sint incidunt, placeat distinctio culpa eveniet facilis.
    Corrupti mollitia numquam totam velit cumque atque perferendis quasi inventore ut cupiditate fugit praesentium illum aperiam alias quaerat ipsum doloremque beatae accusantium nulla, odio non distinctio. Mollitia at ut ea.
    Nam, facilis corporis. Nisi minima modi fugiat vero tenetur, dolorem iste quia perferendis, molestiae esse ut totam doloribus nihil? Iusto maiores voluptate reprehenderit cum eveniet sapiente, cupiditate exercitationem et repellendus?
    Placeat quo nisi mollitia nemo temporibus impedit, labore corrupti nostrum aspernatur. Veniam consectetur id ipsum quae, ea iusto excepturi expedita ducimus tempora nulla eos laboriosam a magnam aliquam est mollitia?
    Perferendis, assumenda nemo magnam error sit ipsam deserunt cupiditate, reprehenderit vero modi rerum voluptatibus beatae dolores. Perspiciatis odit minima cum sunt impedit necessitatibus, eaque, doloremque, nihil voluptas quos dignissimos exercitationem.
    Harum ducimus quibusdam accusantium, rem laboriosam asperiores officiis obcaecati quia ut quis consequuntur adipisci alias suscipit unde iusto voluptatum pariatur. Cumque laborum quo nesciunt deleniti similique adipisci molestias voluptate voluptates!</p>
    
    <h2 id="javascript">JavaScript</h2>
    
    <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Perferendis quae eaque incidunt doloribus, odit veniam quos sed, cupiditate repellat et accusamus optio perspiciatis dolore? Maxime repudiandae quis reprehenderit itaque eligendi!
    Consequatur, nisi velit illum soluta quia deleniti ipsa incidunt qui, odio ea sed. Eligendi magnam natus, ea quae cupiditate omnis beatae corrupti at possimus pariatur recusandae? Modi consectetur totam delectus.
    Natus, ullam fugit enim cum possimus doloribus, corrupti, deserunt quam dolores pariatur deleniti laboriosam placeat voluptate facere saepe ab nam blanditiis ipsum vitae illum quasi nulla est hic explicabo? Error.
    Eligendi impedit ducimus velit debitis. Molestias repellat impedit illo voluptatem vero architecto, repellendus est incidunt facere laborum soluta ex expedita officiis vel aliquam laboriosam saepe fuga excepturi quis? Quasi, placeat.
    Adipisci, accusantium voluptates! Asperiores perferendis obcaecati reiciendis mollitia consequuntur enim? Commodi quae illo odio, dolorem aspernatur at error accusantium maiores molestiae iure recusandae nisi minima repudiandae, eos nulla perspiciatis laboriosam.</p>
    
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta quisquam enim optio cupiditate, tempore deleniti labore aut doloribus! At cumque saepe rerum earum repudiandae quos fugit tempore magnam! Cumque, dignissimos!
    Et eveniet, atque facere dignissimos laboriosam, odio, omnis optio laudantium delectus aperiam perferendis sed. Vero tenetur est id exercitationem sequi explicabo magni, adipisci quo ad! Esse consequatur eveniet sunt distinctio!
    Ex, temporibus consequatur quisquam nihil tenetur quasi corporis pariatur sapiente ad mollitia dolorum earum hic velit soluta similique dolore error aperiam fugit a itaque expedita. Consectetur nihil ad asperiores similique.</p>
    
    <h3 id="npm">npm</h3>
    
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias quos nesciunt esse ipsam repellendus laborum corrupti suscipit voluptatum officiis veniam, tenetur sit recusandae dolores qui accusamus cupiditate hic voluptatibus sapiente!
    Beatae laboriosam in fugiat eos impedit nostrum molestiae dicta optio quasi officia illum laudantium ad asperiores, molestias at exercitationem placeat? Enim veniam eum officia, in sed quasi. Amet, temporibus rerum.
    Ratione eum, qui illum dolorem maiores nam doloremque, soluta cupiditate dicta eaque impedit ea reiciendis labore enim ipsam nesciunt tempora culpa nemo quod cumque beatae laborum minima. Assumenda, temporibus sequi.
    Est temporibus perferendis porro. Reprehenderit quaerat alias a quidem corrupti sapiente tempora facere rerum numquam ipsum facilis eveniet ipsa sunt architecto ut dignissimos fugit, eos earum enim nostrum odit soluta.
    Quis consectetur beatae, dicta quae nam eos. Unde nesciunt inventore mollitia debitis repellendus. Corrupti, quo quia eius fuga, minus aliquam vero illum accusamus repellendus nulla sint itaque recusandae natus nesciunt.
    Animi aperiam nostrum delectus necessitatibus facere, nam fugit. Facere ex quasi nulla numquam repellendus pariatur perspiciatis architecto delectus quam, odit sit! Cumque nemo recusandae error enim, velit explicabo repudiandae culpa?
    Excepturi quaerat fugit est tenetur ex nobis blanditiis recusandae sunt voluptatum quasi deserunt, assumenda consectetur animi accusantium quas reprehenderit impedit laborum laboriosam! Enim reprehenderit error sint eaque magni obcaecati beatae.
    Recusandae quis aliquam iure illum magnam quas quam, quia officia ab. Ipsam, sed. Neque laudantium facilis nostrum at consequuntur molestiae odio! Blanditiis asperiores reprehenderit minima a doloribus saepe odio doloremque?
    Vitae saepe vel facere maxime distinctio modi id a aspernatur. Libero magni tempore nulla a molestiae similique ipsam beatae, accusantium laudantium, itaque, perferendis sed nesciunt soluta. Pariatur exercitationem hic blanditiis?
    Rem, perspiciatis possimus accusantium voluptatum earum, animi saepe aliquid voluptatibus officiis, dolore voluptas et voluptatem odit nihil molestias tempore. Quas omnis facilis harum eligendi et repellat. Qui consequatur reprehenderit omnis.
    Cupiditate officiis corporis ad odit error iste debitis, ducimus minus! Facere ducimus facilis incidunt iusto ab delectus praesentium non recusandae amet sint. Recusandae cupiditate ad voluptatum expedita mollitia, nisi sequi.
    Ea sapiente quam nesciunt modi consequuntur aperiam corporis eos repudiandae at cupiditate autem, asperiores quibusdam eveniet maiores? Veniam iste deserunt pariatur magni veritatis consectetur voluptate, cum delectus, quae ipsum non.
    Ab sapiente rerum quibusdam molestiae facere debitis obcaecati odit pariatur! Distinctio, praesentium earum voluptatibus ipsam ullam nihil! Quod dolorum quo ullam magni pariatur. Dicta temporibus impedit veniam sequi non corrupti?
    Quisquam repudiandae nisi nihil nulla, nesciunt sed commodi optio! Iure voluptate blanditiis aliquid incidunt, commodi odit nostrum provident quasi labore quia, officiis excepturi neque ex eius aperiam quam voluptatibus fugit?
    Laborum, architecto ullam! Voluptate atque qui doloribus blanditiis, in voluptatum reiciendis error. Ipsum, vero corporis quasi tenetur, nostrum alias dolores a debitis nemo libero labore eaque ratione pariatur id. Asperiores?</p>
    
    <h3 id="bower">Bower</h3>
    
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis saepe laudantium repellat tempore nobis veritatis dolor accusamus sunt aperiam voluptas incidunt voluptatem quis distinctio laborum ducimus exercitationem, vel dolore dolores.
    Tempora dolore iste tempore nostrum. Tenetur, nihil omnis. Voluptatibus vitae tenetur error maxime reiciendis ullam cupiditate officia deserunt ratione, consequatur repudiandae aspernatur, cumque temporibus quas alias labore, rem dolore nulla!
    Obcaecati doloremque deleniti esse at, aspernatur officiis ab, dignissimos mollitia minus, architecto porro inventore repellendus. Consequatur ullam omnis laboriosam cupiditate corporis delectus, illo alias accusantium suscipit, ea atque dolores temporibus.
    Obcaecati unde culpa esse maxime, odit voluptatem cumque! Corrupti aut libero facere, tenetur deserunt ratione nobis non iusto numquam culpa animi ex. Neque id consequatur dolores quaerat esse inventore suscipit?
    Perferendis voluptatum sunt doloremque sit nostrum dicta molestiae at quia. Dicta quo animi corrupti aut repudiandae quae nemo rerum perspiciatis expedita! Tenetur beatae dolorum officiis. Accusantium aliquam exercitationem blanditiis quod.
    Recusandae voluptates id voluptatibus. Accusamus omnis natus perspiciatis consequuntur, earum eligendi corporis, praesentium aliquam numquam adipisci distinctio harum aperiam nostrum quibusdam ipsum consectetur minima error neque facilis? Iusto, harum quam.
    Deleniti maxime quibusdam possimus veniam unde odit facere incidunt nostrum consectetur, obcaecati assumenda voluptatum, impedit atque placeat illo ab eos, itaque minima. Quia, adipisci nostrum cum quaerat blanditiis maxime consectetur?
    Tempora eius, eum rem, nisi, alias vitae odit eos omnis veritatis sit cumque beatae voluptatibus quam laboriosam nam. Dolores iusto dolorem porro explicabo architecto perspiciatis ad vitae praesentium quisquam quae!
    Illum necessitatibus excepturi dolore minus porro magnam ea blanditiis. Nesciunt expedita odio maxime veniam molestiae assumenda eum iste dignissimos eligendi nobis eaque, dolor consectetur hic non at possimus facilis cumque!
    Hic aliquam in ratione porro dolore corporis beatae. Voluptate accusamus voluptatibus, illum laboriosam doloremque placeat, magni libero cum praesentium, quis eveniet optio ab provident vel expedita voluptatum laudantium et est.
    Saepe error in ab eos veritatis doloremque est nam cumque? Deleniti expedita rerum, magni possimus aut ex tempore reiciendis consequuntur molestias veritatis quos, cumque magnam, officiis adipisci obcaecati vero doloremque.
    Sed unde, placeat rerum repellat veniam explicabo. Sapiente iure unde perferendis quibusdam itaque rerum eius fugit assumenda tenetur! Autem quasi officiis pariatur libero, architecto eaque debitis esse ea. Dolorum, fuga?
    Cupiditate magni id, recusandae doloremque eius libero in animi autem atque odit sunt tempore error dolorem repellat nobis magnam. Dolorem quas illum fugit, voluptatibus quisquam delectus totam praesentium corporis mollitia!
    Corporis, inventore ex accusantium rem nam neque iure mollitia, repellendus natus delectus perferendis ducimus exercitationem porro temporibus enim laudantium modi fugit minus sit numquam molestias. At eveniet ea quisquam quam!
    Aspernatur corrupti ipsum culpa nostrum! Magnam itaque temporibus laboriosam velit eos esse voluptatem expedita unde maxime eum aperiam dolorem, similique necessitatibus impedit incidunt eligendi facilis aliquid? Necessitatibus consequuntur impedit officiis!</p>
    
    <h2 id="css">CSS</h2>
    <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Fugiat beatae repudiandae aspernatur consectetur laborum voluptatum nihil ipsa neque voluptatibus ad cupiditate obcaecati sunt quo error possimus minus facilis, sed quia.
    Quis doloremque alias quos voluptas, perspiciatis repellendus dolorem inventore nemo officiis illo. Totam ea aliquid unde doloribus est harum vel a veritatis ipsam at fugiat nam, blanditiis ab quae incidunt?
    Porro, officia? Doloribus amet possimus architecto ipsum voluptatum voluptatem enim praesentium nihil odit? Hic tenetur, provident assumenda harum aliquid officia, ab recusandae pariatur dolorum aperiam et aspernatur commodi nostrum minima.
    Amet saepe, autem cumque consequatur nobis fugit. Explicabo, voluptatem eligendi aliquam aliquid quo odio ipsa similique cumque fugiat laudantium nihil iste, omnis expedita adipisci eius autem quas consequuntur dolore unde.
    Sed inventore est nihil qui blanditiis eius temporibus atque itaque. Neque amet laboriosam delectus necessitatibus dolores eius nobis saepe consequatur dolore alias quidem quibusdam similique, odit voluptates praesentium, quam hic!
    At velit, assumenda illum odit temporibus iusto! Qui, illum, asperiores nostrum sit modi expedita nulla culpa minima explicabo labore doloribus unde aliquam, perspiciatis cum adipisci iste veritatis voluptatum consequuntur totam.
    Quisquam laboriosam ipsum optio dolorem dolore, odit asperiores quos maiores! Rerum velit doloribus quisquam beatae delectus, dolor iste! Ducimus enim, dolor modi placeat eaque culpa ut exercitationem rerum voluptates omnis.
    Impedit minus, eaque quisquam quis quas quam in assumenda dolorem nobis repellat nesciunt modi. Ipsum aliquid, minus facilis fuga ab, iste reiciendis, dolorum inventore adipisci eius sint vero totam mollitia.
    Exercitationem excepturi quam repellat illo, praesentium blanditiis totam consequatur quos, sit nulla repudiandae facilis nobis nihil dolor enim. Voluptatem dolore facilis perspiciatis unde rerum eum doloribus dicta neque consectetur nam.
    Ut accusantium aliquam quo quos officiis voluptatem ex facilis reprehenderit quia, cumque saepe assumenda sequi nam libero itaque quidem. Ipsam quae numquam nobis recusandae molestiae blanditiis aut nemo eos commodi.
    Totam excepturi cumque, et maiores quis fuga, aspernatur sunt a eos voluptatem dolorem quod fugiat quaerat quos corporis! Reprehenderit quos dicta atque optio impedit eligendi ad aliquam repellendus voluptatibus! Voluptatem.
    Doloremque, optio possimus amet perferendis, labore similique voluptate maxime quos culpa repellat dolor, voluptatibus facere esse? Fuga similique magnam sapiente eveniet quod voluptatem expedita, quia doloribus labore neque suscipit laborum.
    Autem quos provident voluptatum, asperiores minima illo cumque non omnis, sint reprehenderit veritatis consectetur, officiis inventore. Quibusdam laborum, sunt quod nemo quia illo libero rem illum beatae blanditiis qui molestiae.
    Facilis error obcaecati blanditiis reiciendis iste vel libero praesentium eligendi necessitatibus labore, ratione consequatur molestiae magni incidunt! Enim exercitationem quae autem. Repudiandae porro commodi corporis, optio dignissimos explicabo ipsam dolores.
    Eos earum molestiae eaque exercitationem, natus consectetur qui dignissimos tempore culpa reiciendis, nesciunt dolorem minima officia repellat cumque voluptates eius esse. Exercitationem molestiae reiciendis sit iure consequatur illum facilis deserunt?</p>
    
    <h3 id="sass">Sass</h3>
    
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsum eveniet voluptatem itaque inventore, consequatur voluptates est iste in sapiente hic, quasi unde numquam repellat corrupti dolores? Exercitationem asperiores fugiat ratione?
    Esse quo unde aliquam quas quaerat obcaecati consequuntur quod accusamus accusantium! Earum, similique provident sed natus distinctio asperiores impedit possimus repellendus commodi non totam et! Iusto odit nisi consequuntur itaque?
    Beatae, reiciendis vel fugit perferendis dolores nesciunt, quod iste quia eum mollitia aliquam odio voluptatibus facilis sapiente obcaecati expedita adipisci. Sapiente dolore magni reiciendis pariatur quia rem nihil magnam inventore.
    Velit consequuntur minima, dolorum aliquid, dolores suscipit cumque libero obcaecati facere, laboriosam corporis minus sint. Quia architecto amet ratione nesciunt voluptatibus aut inventore, maiores dolore error porro pariatur officiis suscipit.
    Molestias autem reiciendis totam eum aut odio quos, expedita officia nostrum est, tenetur earum rerum magni itaque esse animi architecto. Pariatur, laborum laudantium! Delectus magni illum ullam earum quaerat adipisci?
    Nulla vel recusandae cum perspiciatis impedit magni ab enim sint eveniet alias possimus aperiam odio ipsa officia explicabo repellat voluptates aut, aspernatur, dicta numquam? Ipsum necessitatibus aut vel laboriosam possimus?
    Iure, ex expedita laborum vero numquam labore quidem facere est reiciendis aliquid incidunt tenetur alias ut molestiae. Animi saepe ab nam exercitationem aliquid suscipit labore iusto, nostrum deserunt? Minus, veniam!
    Voluptas quis facere mollitia? Omnis nemo expedita error rem culpa, officiis impedit odio, illum incidunt velit voluptatum molestiae aut quos nulla enim voluptates. Quia, asperiores eum. Recusandae ab odit impedit!
    Maxime nostrum corrupti neque assumenda exercitationem iure in quo suscipit minus dolorem voluptates tempora inventore dolorum necessitatibus consequatur quod hic magnam libero, ab perferendis quas! Nesciunt, molestiae reprehenderit. Eveniet, illum.
    Aliquid harum perspiciatis blanditiis hic ipsa quo nemo officia facere, vitae dolorum quam dicta laborum delectus voluptates suscipit! Iusto eum cupiditate assumenda praesentium porro tempore dolores autem dignissimos ipsum illum?
    Eligendi, maiores. Necessitatibus numquam temporibus corporis nostrum aliquid? Adipisci possimus deserunt dolor beatae repellat odit incidunt, consectetur totam obcaecati natus, vitae sit quod molestias minima quae neque laboriosam vel. Repellendus!
    Ducimus alias eligendi suscipit. Ipsam laboriosam libero dolorem similique aliquam, vero enim eos. Fuga illum esse accusantium vero quae laboriosam sequi nemo inventore, a reprehenderit mollitia quas illo vel eum?
    Suscipit iusto voluptatibus quis hic consectetur nostrum eligendi perspiciatis mollitia eius at, necessitatibus vitae qui ea, magni corporis quam fugit assumenda eos ipsum repellat reiciendis nobis est! Nostrum, fugiat temporibus!
    In minus cum deserunt sit distinctio. Quia pariatur fugit unde rerum distinctio, ut quod itaque sint nihil et corporis esse officiis fuga aperiam enim illum vero cum minima recusandae molestias.
    Similique ad explicabo delectus unde nostrum culpa animi, illo nesciunt rerum ullam quas, voluptates ipsam, possimus odio tenetur excepturi eos ducimus minima rem eius aspernatur laboriosam quaerat? Obcaecati, vitae numquam?</p>
  </div>
</div>
body {
  font-family: 'Open Sans', sans-serif;
}

h1, h2, h3 {
  font-family: 'Playfair Display', serif;
  font-weight: 700;
}

.container {
  display: grid;
  padding: 10px;
  grid-template-columns: 150px auto;
  grid-gap: 30px
}

.toc {
  position: sticky;
  top: 0;
  align-self: start;
  
  > ul {
    padding: 0;
    list-style: none;
  }
  
  a {
    display: block;
    padding: 3px;
    transition: background ease 0.2s, color ease 0.2s;
  }
}

.is-active {
  background-color: #cf1259;
  color: white;
  text-decoration: none;
}
View Compiled
function ready(fn) {
  document.addEventListener('DOMContentLoaded', fn, false)
}

ready(() => {
  const motionQuery = window.matchMedia('(prefers-reduced-motion)')

  const TableOfContents = {
    container: document.querySelector('.js-toc'),
    links: null,
    headings: null,
    intersectionOptions: {
      rootMargin: '0px',
      threshold: 1
    },
    previousSection: null,
    observer: null,

    init() {
      this.handleObserver = this.handleObserver.bind(this)

      this.setUpObserver()
      this.findLinksAndHeadings()
      this.observeSections()


      this.links.forEach(link => {
        link.addEventListener('click', this.handleLinkClick.bind(this))
      })
    },
    

    handleLinkClick(evt) {
      evt.preventDefault()
      let id = evt.target.getAttribute('href').replace('#', '')

      let section = this.headings.find(heading => {
        return heading.getAttribute('id') === id
      })

      section.setAttribute('tabindex', -1)
      section.focus()

      window.scroll({
        behavior: motionQuery.matches ? 'instant' : 'smooth',
        top: section.offsetTop - 15,
        block: 'start'
      })

      if (this.container.classList.contains('is-active')) {
        this.container.classList.remove('is-active')
      }
    },

    handleObserver(entries, observer) {
      entries.forEach(entry => {
        let href = `#${entry.target.getAttribute('id')}`,
          link = this.links.find(l => l.getAttribute('href') === href)
        

        if (entry.isIntersecting && entry.intersectionRatio >= 1) {
          link.classList.add('is-visible')
          this.previousSection = entry.target.getAttribute('id')
        } else {
          link.classList.remove('is-visible')
        }

        this.highlightFirstActive()
      })
    },

    highlightFirstActive() {
      let firstVisibleLink = this.container.querySelector('.is-visible')

      this.links.forEach(link => {
        link.classList.remove('is-active')
      })

      if (firstVisibleLink) {
        firstVisibleLink.classList.add('is-active')
      }

      if (!firstVisibleLink && this.previousSection) {
        this.container.querySelector(
          `a[href="#${this.previousSection}"]`
        ).classList.add('is-active')
      }
    },

    observeSections() {
      this.headings.forEach(heading => {
        this.observer.observe(heading)
      })
    },

    setUpObserver() {
      this.observer = new IntersectionObserver(
        this.handleObserver,
        this.intersectionOptions
      )
    },

    findLinksAndHeadings() {
      this.links = [...this.container.querySelectorAll('a')]
      this.headings = this.links.map(link => {
        let id = link.getAttribute('href')
        return document.querySelector(id)
      })
    }
  }


  TableOfContents.init()
});
View Compiled
Run Pen

External CSS

  1. https://fonts.googleapis.com/css?family=Open+Sans|Playfair+Display:400,700

External JavaScript

This Pen doesn't use any external JavaScript resources.