如何使元素在调整大小时与另一个元素保持一致

问题描述 投票:0回答:1

在我的 React JS 网站中,我有一个 div,它充当导航栏中的下划线,显示用户所在的路线。

Here it is here

每当用户使用 css 过渡单击 div 下划线元素时,它就会移动到新路线。

问题是每当我调整窗口大小时,导航栏也会调整移动可点击路线的大小(我希望它这样做)。然而,div 下划线元素保持在同一位置,因此现在在导航栏的随机部分下划线。

Like this

我的问题是即使在调整大小时如何不断地将div保持在选定的路线下。下面是我的代码:

反应:

import { useEffect, useState, useRef } from "react"
import { useLocation } from "react-router-dom"

export default function Underline() {

  let pathname = useLocation().pathname
  
  const [underlineStyle, setUnderlineStyle] = useState()
  const width = useRef(window.innerWidth)

  useEffect(() => {

    function handleResize() {
      width.current = window.innerWidth
    }

    window.addEventListener("resize", handleResize())

    let underlinedLink = document.querySelector(`a[href="${pathname}"]`)

    //as there are 2 anchor tags for home in nav
    if (underlinedLink.getAttribute("id") !== null) { //both home anchor tags are only ones with id's in nav
      underlinedLink = document.querySelector("#home")
    }

    setUnderlineStyle({
      width: `${underlinedLink.offsetWidth}px`,
      left: `${underlinedLink.getBoundingClientRect().left}px`,
    })
  
    return () => {
      window.removeEventListener("resize", handleResize())
    }

  }, [pathname, width.current])

  return <div id="underline" style={underlineStyle}></div>
}

CSS:

#underline {
  margin: 0 0 5px 0;
  height: 4px;
  bottom: 0;
  border: 0;
  position: absolute;
  transition: left 0.3s ease-in-out, width 0.3s ease-in-out;
  background: linear-gradient(to bottom, #48a0e0 20%, #2b58a5);
  box-shadow: 0 -14px 14px #48a0e0;
}

我尝试添加调整大小事件侦听器,它调用一个函数来移动下划线,这在技术上是有效的,但它不会始终保持在路线上,并且仅在我完成调整大小时才移动到路线,这将是一种非常奇怪的用户体验.

我也知道我可以将下划线div放入具有下划线div和路线的祖先元素中但是似乎是一种过于复杂的方法并且我很好奇是否有人知道任何更简单的方法来做到这一点。任何建议或解决方案将不胜感激。

reactjs react-hooks resize react-router-dom navbar
1个回答
0
投票

updateUnderline
内创建一个
useEffect
函数。当
pathname
发生变化时立即调用该函数,并将其用作调整大小处理程序。

export default function Underline() {
  const pathname = useLocation().pathname
  const [underlineStyle, setUnderlineStyle] = useState()
  
  useEffect(() => {
    function updateUnderline() {
      let underlinedLink = document.querySelector(`a[href="${pathname}"]`)

      //as there are 2 anchor tags for home in nav
      if (underlinedLink.hasAttribute("id")) { //both home anchor tags are only ones with id's in nav
        underlinedLink = document.querySelector("#home")
      }

      setUnderlineStyle({
        width: `${underlinedLink.offsetWidth}px`,
        left: `${underlinedLink.getBoundingClientRect().left}px`,
      })
    }
    
    updateUnderline() // call whenever the useEffect is triggered
    
    window.addEventListener("resize", updateUnderline) // use as event handler
  
    return () => {
      window.removeEventListener("resize", updateUnderline)
    }

  }, [pathname])

  return <div id="underline" style={underlineStyle}></div>
}
© www.soinside.com 2019 - 2024. All rights reserved.