如何使React应用在新渲染的页面上滚动到特定元素?

huangapple go评论65阅读模式
英文:

How to make React app scroll to a specific element on a newly rendered page?

问题

我正在努力寻找关于在单击相应元素后,如何使React应用程序滚动到新呈现页面上的特定元素的信息。我有一个主页,其中包含6个服务卡片。我还有一个包括有关每个服务的更详细描述的服务页面。我希望在主页上单击卡片后,浏览器能够自动滚动到服务页面中相应的服务。

以下是主页中的卡片组件:

const navigate = useNavigate()

return (
    <div id={data.id} className="serviceCard slideUpContainer" onClick={() => navigate(data.link)}>
        <img src={require('../visuals/' + data.img + '.png')} alt={data.title} />
        <div className="slideUpContent">
            <h2 className="slideUpTitle">{data.title}</h2>
            <p className="slideUpText">{data.excerpt}</p>
            <div className="linkContainer">
                <a href={data.link}>{data.btn}<i className="glyphicon glyphicon-menu-right"></i></a>
            </div>
        </div>
    </div>
)

以下是服务页面中的服务组件:

return (
    <div id={data.id} className={data.className}>
        <div id="imgBox">
            <img src={require('../visuals/services/' + data.blockImg + '.png')} alt={data.alt} />
        </div>
        <div id="textBox">
            <h2>{data.title}</h2>
            <p>{data.description}</p>
            <div>
                <h3>{data.listName}</h3>
                <ul>
                    {data.listItems.map(item => 
                        <ServiceListItem key={nanoid()} data={item} />
                    )}
                </ul>
            </div>
        </div>
    </div>
)

目前,我正在使用 navigate(),我还尝试将 /#ElementID 添加到URL 中,但都没有得到期望的结果。我尝试在互联网上找更多信息,但我只能找到在同一页面上进行滚动的选项(这很容易实现)。

英文:

I am struggling to find information about how to make React app scroll to a specific element on a newly rendered page after clicking a corresponding element. I have a homepage with 6 service cards. I also have a services page that includes more detailed descriptions about each service. I want the browser to automatically scroll to a corresponding service in the services page after a card in homepage was clicked.

Here is the Card component in the homepage:


    const navigate = useNavigate()

    return (
        &lt;div id={data.id} className=&quot;serviceCard slideUpContainer&quot; onClick={() =&gt; navigate(data.link)}&gt;
            &lt;img src={require(&#39;../visuals/&#39; + data.img + &#39;.png&#39;)} alt={data.title} /&gt;
            &lt;div className=&quot;slideUpContent&quot;&gt;
                &lt;h2 className=&quot;slideUpTitle&quot;&gt;{data.title}&lt;/h2&gt;
                &lt;p className=&quot;slideUpText&quot;&gt;{data.excerpt}&lt;/p&gt;
                &lt;div className=&quot;linkContainer&quot;&gt;
                    &lt;a href={data.link}&gt;{data.btn}&lt;i className=&quot;glyphicon glyphicon-menu-right&quot;&gt;&lt;/i&gt;&lt;/a&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    )
}
export default ServiceCard

And here is the Service component in the services page:



    return (
        &lt;div id={data.id} className={data.className}&gt;
        &lt;div id=&quot;imgBox&quot;&gt;
            &lt;img src={require(&#39;../visuals/services/&#39; + data.blockImg + &#39;.png&#39;)}
            alt={data.alt} /&gt;
        &lt;/div&gt;
        &lt;div id=&quot;textBox&quot;&gt;
            &lt;h2&gt;{data.title}&lt;/h2&gt;
            &lt;p&gt;{data.description}&lt;/p&gt;
            &lt;div&gt;
                &lt;h3&gt;{data.listName}&lt;/h3&gt;
                &lt;ul&gt;
                    {data.listItems.map(item =&gt; 
                        &lt;ServiceListItem key={nanoid()} data={item} /&gt;
                        )}
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    )
}

For now I was using navigate(), I also tried adding /#ElementID to the url and neither of those gives me the desired result. I was trying to find more info on the internet, but all I get is the scrolling option on the same page (which is easy).

答案1

得分: 0

新渲染的页面意味着你可以使用一个空的依赖项 'useEffect' 作为回调,当你希望的组件渲染完成并在DOM中可用时:

useEffect(() => {
    document.getElementById("ElementID").scrollIntoView();
    // 或者,使用引用
    elementRef.current.scrollIntoView()
}, [])

你还可以在希望进入视图的组件的任何父组件上使用,因为父组件的 'onEffect' 总是在子组件完全渲染后调用的(并且它自己的 'onEffect' 已经运行过)。

为了补充这一点,你还可以在你的CSS中使用:

  • scroll-padding-top - 如果你有一个粘性标头或某种方式滚动不能正确居中元素
  • scroll-behavior - 用于平滑滚动,如果你想要这个特性。如果你希望你的页面立即滚动到这个组件,但对于其他所有内容都有平滑滚动,你还可以:禁用平滑滚动 -> scrollIntoView() -> 重新启用平滑滚动。
英文:

Newly rendered page means that you can use an empty dependencies 'useEffect' as a callback for when the component you want into view finishes rendering and is available in the DOM:

useEffect(() =&gt; {
    document.getElementById(&quot;ElementID&quot;).scrollIntoView();
    // or, use a ref and
    elementRef.current.scrollIntoView()
}, [])

You can also use on any parent component of the component you want into view, as parent's 'onEffect' is always called after a child has completely rendered (and its own 'onEffect' has already ran).

To complement this, you can also use in your CSS:

  • scroll-padding-top - if you have a sticky header or somehow the scroll doesn't center the element correctly
  • scroll-behavior - for smooth scrolling, if you want this feature. If you want your page to instant scroll to this component, but have smooth scroll for everything else, you can also: disable smooth scroll -> scrollIntoView() -> re-enable smooth scroll.

huangapple
  • 本文由 发表于 2023年3月7日 22:29:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75663276.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定