javascript - 动态目录 - For 循环未完成

标签 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' )
  }
}

最佳答案

想出一个解决方案,创建一个仅包含部分 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
  }
}

关于javascript - 动态目录 - For 循环未完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58404328/

相关文章:

javascript - 使用 javascript 代替 Sphinx 的默认目录树

javascript - 通过 AJAX 检索 PHP JSON 数据 - 数据请求的正确结构

javascript - 在 Three.js 中使用 FBXLoader 将 BufferGeometry 转换为 Geometry

javascript - 在鼠标悬停时打开一个 div 并保持打开状态直到鼠标移出?

javascript - 用户评分后禁用jquery star插件

php - TCPDF 添加 "Return to Table of Contents"页脚链接

javascript - 带有 angularJS 的 ASP.NET 无法加载模板(没有错误的空白页)

javascript - CSS之谜,不知道如何修改一段代码

jquery - 选择一天时应用不同的样式 - jQuery multidatepicker

html - Python jupyter notebook 转换为 html 后,markdown 的编号消失了