动态目录-For循环未完成

时间:2019-10-16 00:53:55

标签: javascript jquery tableofcontents

我正在研究一些代码,这些代码循环遍历<section><header>元素以创建目录。创建后,目录应突出显示用户滚动到的部分。

该代码似乎可以正常工作,但是在遍历创建的目录时在项目10上停止。我想知道循环中是否发生太多事情,从而导致超时?我对JS和jQuery还是很陌生,感谢任何帮助!

我在这里有工作示例:https://codepen.io/higginbg/pen/jONzrYG

目录代码:

function tableOfContents(tocList) {

    $(tocList).empty()

    let prevItem = null
    let prevList = null

    $( 'section' ).each(function() {

        const text = $(this).children( 'header' ).text()

        const id = text.replace(/ /g, '_')

        const li = `
          <li>
            <a class='nav-link'
               href='#${id}'
               onclick='menuToggle()'
            >${text}
            </a>
          </li>
        `

        $(this).attr('id', id)

        prevList = $("<ul></ul>")
        prevItem = $(li)
        prevItem.append(prevList)
                .appendTo(tocList)
    })
}       

滚动到以下位置时突出显示部分的代码:

function highlightToc() {

  const elements = $( 'section' )
  const scrollPosition = ($(window).height() * 0.25) + $(window).scrollTop()

  for (let i = 0; i < elements.length; i++) {

    const thisId = '#' + elements[i].id
    const nextId = (i <= elements.length) ? `#${elements[i+1].id}` : '#'

    const thisOffset = $(thisId).offset().top
    const nextOffset = (i <= elements.length) ? $(nextId).offset().top : 0

    const listItem = $( `a[href='${thisId}']` )

    const isSelected = ((scrollPosition > thisOffset) && (scrollPosition < nextOffset))

      isSelected ? listItem.addClass( 'selected' ) : listItem.removeClass( 'selected' )
  }
}

1 个答案:

答案 0 :(得分:1)

提出一种仅创建包含节ID和偏移值的压缩数组的解决方案。似乎是为了防止超时。还决定不使用jQuery。

创建节的代码:

const fullSections = document.querySelectorAll('section')
const sections = []

const createSections = () => {
  for (const sec of fullSections) {
    const header = sec.querySelector('header')
    const text = header.innerText
    const id = text.replace(/ /g, '_')

    // Set section id
    sec.id = id

    sections.push({
      id,
      text,
      href: `#${id}`,
      header,
      offsetTop: sec.offsetTop,
    })
  }
}

目录代码:

const createToc = () => {
  const toc = document.getElementById('toc')

  for (const sec of sections) {
    const { id, text, href } = sec

    // Create list item
    const li = document.createElement('li')
    const a = document.createElement('a')

    a.innerText = text
    a.href = href
    a.className = 'nav-link'

    li.append(a)
    toc.append(li)
  }
}

滚动亮点:

const highlightToc = () => {
  const scrollPosition = (window.innerHeight * 0.50) + window.pageYOffset
  const numSections = sections.length

  for (let i = 0; i < sections.length; i++) {
    const { id, offsetTop } = sections[i]
    const thisClasses = document.querySelector(`#toc a[href='#${id}']`).classList

    // Next item (only up to last section)
    const n = (i + 1 < numSections) ? (i + 1) : i
    const nextOffset = sections[n].offsetTop

    // Highlight toc item if within scroll window
    if ((scrollPosition > offsetTop) && (scrollPosition < nextOffset)) {
      thisClasses.add('selected')
    } else {
      thisClasses.remove('selected')
    }

    // Highlight last toc item if near bottom of page
    if (sections[numSections - 1].offsetTop < window.innerHeight + window.pageYOffset) {
      const p = (i - 1 < 0) ? 0 : (i - 1)
      const prevId = sections[p].id
      const prevClasses = document.querySelector(`#toc a[href='#${prevId}']`).classList

      thisClasses.add('selected')
      prevClasses.remove('selected')
    }
  }
}

在调整窗口大小时重新映射偏移量:

const newOffsets = () => {
  for (let i = 0; i < fullSections.length; i++) {
    sections[i].offsetTop = fullSections[i].offsetTop
  }
}