Reactjs 盖茨比将目录与页面滚动同步,并设置活动链接的样式

Reactjs 盖茨比将目录与页面滚动同步,并设置活动链接的样式,reactjs,gatsby,Reactjs,Gatsby,我使用了data.markdownRemark.tableOfContents来生成任何标记文件的目录,但是,它只是HTML,我的意思是它的行为与Gatsby文档页面上出现的TOC不同,我希望TOC中的链接根据用户滚动到当前显示的部分处于活动和非活动状态,就像盖茨比文档中TOC的行为一样 我做了大量的研究,什么也没发现 我是否在数据、markdownRemark.tableOfContents方面做错了什么?或者有没有一种我在文档中找不到的方法来实现这一点?或者我应该自己用vanilla JS实

我使用了
data.markdownRemark.tableOfContents
来生成任何标记文件的目录,但是,它只是HTML,我的意思是它的行为与Gatsby文档页面上出现的TOC不同,我希望TOC中的链接根据用户滚动到当前显示的部分处于活动和非活动状态,就像盖茨比文档中TOC的行为一样

我做了大量的研究,什么也没发现


我是否在
数据、markdownRemark.tableOfContents
方面做错了什么?或者有没有一种我在文档中找不到的方法来实现这一点?或者我应该自己用vanilla JS实现这个行为吗?

我在上发布了这个问题,团队告诉我这是我们必须自己实现的

下面是我如何实现它的:

import React, { useEffect, useMemo } from "react"
import { useActiveHash } from "../../reactHooks/use-active-hash"

export default function TableOfContents({ html }) {
  let targetedIds = useMemo(() => {
    var dummyDOM = document.createElement("html")
    dummyDOM.innerHTML = html
    const justAnchors = dummyDOM.querySelectorAll(`a`)

    let val = []
    justAnchors.forEach(a => {
      val.push(a.hash.replace("#", ""))
    })

    return val
  }, [])

  const activeHash = useActiveHash(targetedIds)

  useEffect(() => {
    const ToClinks = document.querySelectorAll(`.ToCs a`)

    ToClinks.forEach(a => {
      a.classList.remove("isActive")
    })

    const activeLink = document.querySelectorAll(
      `.ToCs a[href$="${"/#" + activeHash}"]`
    )

    if (activeLink.length) {
      activeLink[0].classList.add("isActive")
    }
  }, [activeHash])

  return (
    <div>
      <h2>Table Of Contents</h2>
      <div className="ToCs" dangerouslySetInnerHTML={{ __html: html }} />
    </div>
  )
}


这是我的实现,它只是将
isActive
类添加到目录的活动链接中,您可以看看盖茨比的团队是如何实现它的。

我将这个问题发布在上,团队告诉我,这是我们必须自己实现的

下面是我如何实现它的:

import React, { useEffect, useMemo } from "react"
import { useActiveHash } from "../../reactHooks/use-active-hash"

export default function TableOfContents({ html }) {
  let targetedIds = useMemo(() => {
    var dummyDOM = document.createElement("html")
    dummyDOM.innerHTML = html
    const justAnchors = dummyDOM.querySelectorAll(`a`)

    let val = []
    justAnchors.forEach(a => {
      val.push(a.hash.replace("#", ""))
    })

    return val
  }, [])

  const activeHash = useActiveHash(targetedIds)

  useEffect(() => {
    const ToClinks = document.querySelectorAll(`.ToCs a`)

    ToClinks.forEach(a => {
      a.classList.remove("isActive")
    })

    const activeLink = document.querySelectorAll(
      `.ToCs a[href$="${"/#" + activeHash}"]`
    )

    if (activeLink.length) {
      activeLink[0].classList.add("isActive")
    }
  }, [activeHash])

  return (
    <div>
      <h2>Table Of Contents</h2>
      <div className="ToCs" dangerouslySetInnerHTML={{ __html: html }} />
    </div>
  )
}

这是我的实现,它只是将
isActive
类添加到目录的活动链接中,您可以看看盖茨比团队是如何实现它的