如何滚动到一个元素?

我有一个聊天小部件,每当我向上滚动时,它就会弹出一个消息数组。我现在面临的问题是,当消息加载时,滑块固定在顶部。我想让它关注上一个数组的最后一个索引元素。我发现我可以通过传递索引来进行动态引用,但我也需要知道使用哪种滚动函数来实现这一点

 handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
if (some_logic){
//scroll to testNode
}
}


render() {


return (
<div>
<div ref="test"></div>
</div>)
}
699518 次浏览

只要找到你已经确定的元素的顶部位置https://www.w3schools.com/Jsref/prop_element_offsettop.asp,然后通过scrollTo方法https://www.w3schools.com/Jsref/met_win_scrollto.asp滚动到这个位置

像这样的东西应该工作:

handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
if (some_logic){
window.scrollTo(0, tesNode.offsetTop);
}
}


render() {


return (
<div>
<div ref="test"></div>
</div>)
}

更新:

因为< em >反应v16.3 < / em >首选React.createRef()

constructor(props) {
super(props);
this.myRef = React.createRef();
}


handleScrollToElement(event) {
if (<some_logic>){
window.scrollTo(0, this.myRef.current.offsetTop);
}
}


render() {


return (
<div>
<div ref={this.myRef}></div>
</div>)
}

你可以使用类似componentDidUpdate的东西

componentDidUpdate() {
var elem = testNode //your ref to the element say testNode in your case;
elem.scrollTop = elem.scrollHeight;
};

使用findDOMNode最终将被弃用。

首选的方法是使用回调引用。

github eslint

你可以这样尝试:

 handleScrollToElement = e => {
const elementTop = this.gate.offsetTop;
window.scrollTo(0, elementTop);
};


render(){
return(
<h2 ref={elem => (this.gate = elem)}>Payment gate</h2>
)}

也可以使用scrollIntoView方法滚动到给定元素。

handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
if (some_logic){
tesNode.scrollIntoView();
}
}


render() {
return (
<div>
<div ref="test"></div>
</div>)
}

React 16.8 +,功能组件

const ScrollDemo = () => {
const myRef = useRef(null)


const executeScroll = () => myRef.current.scrollIntoView()
// run this function from an event handler or an effect to execute scroll


return (
<>
<div ref={myRef}>Element to scroll to</div>
<button onClick={executeScroll}> Click to scroll </button>
</>
)
}


点击这里查看StackBlits的完整演示

React 16.3 +,类组件

class ReadyToScroll extends Component {
constructor(props) {
super(props)
this.myRef = React.createRef()
}


render() {
return <div ref={this.myRef}>Element to scroll to</div>
}


executeScroll = () => this.myRef.current.scrollIntoView()
// run this method to execute scrolling.
}

类组件-引用回调

class ReadyToScroll extends Component {
render() {
return <div ref={ (ref) => this.myRef=ref }>Element to scroll to</div>
}


executeScroll = () => this.myRef.scrollIntoView()
// run this method to execute scrolling.
}

不要使用字符串引用。

字符串裁判损害性能,不可组合,并且正在被淘汰(2018年8月)。

字符串引用有一些问题,被认为是遗留的,并且很可能是 在将来的版本中被删除。[React官方文档]

.

resource1resource2

可选:平滑滚动动画

/* css */
html {
scroll-behavior: smooth;
}

传递ref给一个子对象

我们希望ref附加到一个dom元素,而不是一个react组件。所以当把它传递给子组件时,我们不能给prop ref命名。

const MyComponent = () => {
const myRef = useRef(null)
return <ChildComp refProp={myRef}></ChildComp>
}

然后将ref prop附加到dom元素上。

const ChildComp = (props) => {
return <div ref={props.refProp} />
}

这对我很有效

this.anyRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })

我想在评论的基础上扩展这一点。

const scrollTo = (ref) => {
if (ref && ref.current /* + other conditions */) {
ref.current.scrollIntoView({ behavior: 'smooth', block: 'start' })
}
}


<div ref={scrollTo}>Item</div>

我可能迟到了,但我试图实现动态引用到我的项目的正确方式和所有的答案,我已经找到,直到知道不是安静的满足我的喜欢,所以我想出了一个解决方案,我认为是简单的,并使用本机和推荐的反应方式来创建引用。

有时,您会发现文档的编写方式假设您有一个已知的视图数量,而在大多数情况下,这个数字是未知的,因此您需要一种方法来解决这个问题,在这种情况下,创建动态引用到您需要在类中显示的未知视图数量

所以我能想到的最简单且完美无缺的解决方案是这样做的

class YourClass extends component {


state={
foo:"bar",
dynamicViews:[],
myData:[] //get some data from the web
}


inputRef = React.createRef()


componentDidMount(){
this.createViews()
}




createViews = ()=>{
const trs=[]
for (let i = 1; i < this.state.myData.lenght; i++) {


let ref =`myrefRow ${i}`


this[ref]= React.createRef()


const row = (
<tr ref={this[ref]}>
<td>
`myRow ${i}`
</td>
</tr>
)
trs.push(row)


}
this.setState({dynamicViews:trs})
}


clickHandler = ()=>{


//const scrollToView = this.inputRef.current.value
//That to select the value of the inputbox bt for demostrate the //example


value=`myrefRow ${30}`


this[value].current.scrollIntoView({ behavior: "smooth", block: "start" });
}




render(){


return(
<div style=\{\{display:"flex", flexDirection:"column"}}>
<Button onClick={this.clickHandler}> Search</Button>
<input ref={this.inputRef}/>
<table>
<tbody>
{this.state.dynamicViews}
<tbody>
<table>
</div>




)


}


}


export default YourClass

这样,滚动就会转到你要找的任何一行。

干杯,希望它能帮助别人

对我有用的是:

class MyComponent extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef(); // Create a ref
}


// Scroll to ref function
scrollToMyRef = () => {
window.scrollTo({
top:this.myRef.offsetTop,
// behavior: "smooth" // optional
});
};


// On component mount, scroll to ref
componentDidMount() {
this.scrollToMyRef();
}


// Render method. Note, that `div` element got `ref`.
render() {
return (
<div ref={this.myRef}>My component</div>
)
}
}

你现在可以从react钩子API中使用useRef

https://reactjs.org/docs/hooks-reference.html#useref

宣言

let myRef = useRef()

组件

<div ref={myRef}>My Component</div>

使用

window.scrollTo({ behavior: 'smooth', top: myRef.current.offsetTop })
 <div onScrollCapture={() => this._onScrollEvent()}></div>


_onScrollEvent = (e)=>{
const top = e.nativeEvent.target.scrollTop;
console.log(top);
}

2019年7月-专用钩子/函数

专用的钩子/函数可以隐藏实现细节,并为组件提供简单的API。

React 16.8 +功能组件

const useScroll = () => {
const elRef = useRef(null);
const executeScroll = () => elRef.current.scrollIntoView();


return [executeScroll, elRef];
};

在任何功能组件中使用它。

const ScrollDemo = () => {
const [executeScroll, elRef] = useScroll()
useEffect(executeScroll, []) // Runs after component mounts
    

return <div ref={elRef}>Element to scroll to</div>
}

完整demo

React 16.3 +类组件

const utilizeScroll = () => {
const elRef = React.createRef();
const executeScroll = () => elRef.current.scrollIntoView();


return { executeScroll, elRef };
};

在任何类组件中使用它。

class ScrollDemo extends Component {
constructor(props) {
super(props);
this.elScroll = utilizeScroll();
}


componentDidMount() {
this.elScroll.executeScroll();
}


render(){
return <div ref={this.elScroll.elRef}>Element to scroll to</div>
}
}

完整demo

遵循以下步骤:

1)安装:

npm install react-scroll-to --save

2)导入包:

import { ScrollTo } from "react-scroll-to";

3)用法:

class doc extends Component {
render() {
return(
<ScrollTo>
{({ scroll }) => (
<a onClick={() => scroll({ x: 20, y: 500, , smooth: true })}>Scroll to Bottom</a>
)}
</ScrollTo>
)
}
}

只是提醒一下,我无法让这些解决方案在Material UI组件上工作。看起来它们没有current属性。

我只是在我的组件中添加了一个空的div,并在其上设置了ref prop。

下面是你可以用来解决这个问题的类组件代码片段:

该方法使用了ref,并且平滑地将 滚动到目标ref

import React, { Component } from 'react'


export default class Untitled extends Component {
constructor(props) {
super(props)
this.howItWorks = React.createRef()
}


scrollTohowItWorks = () =>  window.scroll({
top: this.howItWorks.current.offsetTop,
left: 0,
behavior: 'smooth'
});


render() {
return (
<div>
<button onClick={() => this.scrollTohowItWorks()}>How it works</button>
<hr/>
<div className="content" ref={this.howItWorks}>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Nesciunt placeat magnam accusantium aliquid tenetur aspernatur nobis molestias quam. Magnam libero expedita aspernatur commodi quam provident obcaecati ratione asperiores, exercitationem voluptatum!
</div>
</div>
)
}
}

我有一个简单的场景,当用户点击我的材质UI导航栏的菜单项时,我想要向下滚动到页面上的部分。我可以使用引用和线程他们通过所有的组件,但我讨厌线程道具通过多个组件,因为这使得代码脆弱。

我只是在我的react组件中使用了香草JS,结果证明它工作得很好。在我想要滚动的元素上放置一个ID,在我的头组件中,我只是这样做了。

const scroll = () => {
const section = document.querySelector( '#contact-us' );
section.scrollIntoView( { behavior: 'smooth', block: 'start' } );
};

对于读到这篇文章的人来说,他们没有太多的运气使用上面的解决方案,或者只是想要一个简单的解决方案,这个包对我有用:https://www.npmjs.com/package/react-anchor-link-smooth-scroll。黑客快乐!

我在一个onclick函数中使用它来平滑地滚动到一个div,其id是"step2Div"。

let offset = 100;
window.scrollTo({
behavior: "smooth",
top:
document.getElementById("step2Div").getBoundingClientRect().top -
document.body.getBoundingClientRect().top -
offset
});

最好的方法是使用element.scrollIntoView({ behavior: 'smooth' })。这将以漂亮的动画将元素滚动到视图中。

当你将它与React的useRef()结合在一起时,可以通过以下方式完成。

import React, { useRef } from 'react'


const Article = () => {
const titleRef = useRef()


function handleBackClick() {
titleRef.current.scrollIntoView({ behavior: 'smooth' })
}


return (
<article>
<h1 ref={titleRef}>
A React article for Latin readers
</h1>


// Rest of the article's content...


<button onClick={handleBackClick}>
Back to the top
</button>
</article>
)
}

当你想要滚动到React组件时,你需要将引用转发给渲染的元素。本文将深入探讨这个问题

如果你想在页面加载时做,你可以使用useLayoutEffectuseRef

import React, { useRef, useLayoutEffect } from 'react'


const ScrollDemo = () => {


const myRef = useRef(null)


useLayoutEffect(() => {
window.scrollTo({
behavior: "smooth",
top: myRef.current.offsetTop,
});
}, [myRef.current]);


return (
<>
<div ref={myRef}>I wanna be seen</div>
</>
)
}

以下是我的解决方案:

我在main div里面放了一个隐形的div,使它的位置是绝对的。然后将顶部值设置为-(头高),并在此div上设置ref。或者你可以用children方法反应该div。

到目前为止,它工作得很好!

<div className="position-relative">
<div style=\{\{position:"absolute", top:"-80px", opacity:0, pointerEvents:'none'}}  ref={ref}></div>

在阅读manny论坛后,我找到了一个非常简单的解决方案。

我用还原形式。Urgo映射redux-from fieldToClass。当出现错误时,我导航到syncErrors列表中的第一个错误。

没有裁判,没有第三方模块。只是简单的querySelector &scrollIntoView

handleToScroll = (field) => {


const fieldToClass = {
'vehicleIdentifier': 'VehicleIdentifier',
'locationTags': 'LocationTags',
'photos': 'dropzoneContainer',
'description': 'DescriptionInput',
'clientId': 'clientId',
'driverLanguage': 'driverLanguage',
'deliveryName': 'deliveryName',
'deliveryPhone': 'deliveryPhone',
"deliveryEmail": 'deliveryEmail',
"pickupAndReturn": "PickupAndReturn",
"payInCash": "payInCash",
}


document?.querySelector(`.${fieldToClasses[field]}`)
.scrollIntoView({ behavior: "smooth" })


}

为了自动滚动到特定的元素,首先需要使用. getelementbyid选择元素,然后我们需要使用scrollIntoView ()滚动。请参考以下代码。

   scrollToElement= async ()=>{
document.getElementById('id001').scrollIntoView();
}

上述方法对我来说很有效。

这个解决方案适用于我在ReactJS

在header.js

function scrollToTestDiv(){
const divElement = document.getElementById('test');
divElement.scrollIntoView({ behavior: 'smooth' });
}


<a class="nav-link" onClick={scrollToTestDiv}> Click here! </a>

在index . html

<div id="test"></div>

如果有人在使用Typescript,下面是Ben Carp的答案:

import { RefObject, useRef } from 'react';


export const useScroll = <T extends HTMLElement>(
options?: boolean | ScrollIntoViewOptions
): [() => void, RefObject<T>] => {
const elRef = useRef<T>(null);
const executeScroll = (): void => {
if (elRef.current) {
elRef.current.scrollIntoView(options);
}
};


return [executeScroll, elRef];
};
这是我发现对我来说最简单的工作方式。 只需使用正常的javascript语法,不需要太多的包

  const scrollTohowItWorks = () =>  window.scroll({
top: 2000,
left: 0,
behavior: 'smooth'
});
  

<NavLink onClick={scrollTohowItWorks} style={({ isActive }) => isActive? {color: '#e26702', fontWeight:'bold'}: { color: '#0651b3'}} to=''>Support</NavLink>

也许有人会遇到像我这样的情况

https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node

如何测量DOM节点? 测量DOM节点位置或大小的一种基本方法是使用回调ref。每当ref附加到不同的节点时,React就会调用该回调。下面是一个小演示:

function MeasureExample() {
const [height, setHeight] = useState(0);


const measuredRef = useCallback(node => {
if (node !== null) {
setHeight(node.getBoundingClientRect().height);// you can scroll in this line
}
}, []);


return (
<>
<h1 ref={measuredRef}>Hello, world</h1>
<h2>The above header is {Math.round(height)}px tall</h2>
</>
);
}

在本例中,我们没有选择useRef,因为对象引用不会通知我们当前引用值的更改。使用回调引用可以确保即使稍后子组件显示了被测量的节点(例如,在响应单击时),我们仍然会在父组件中得到关于它的通知,并可以更新测量值。

注意,我们将[]作为依赖数组传递给useCallback。这确保了我们的ref回调在重新渲染之间不会改变,所以React不会不必要地调用它。

在这个例子中,回调ref只会在组件挂载和卸载时被调用,因为呈现的组件在任何重新呈现器中都保持存在。如果你想在组件调整大小时收到通知,你可以使用ResizeObserver或在其上构建的第三方Hook。

<div id="componentToScrollTo"><div>


<a href='#componentToScrollTo'>click me to scroll to this</a>

这就是你所需要的。

你可以同时使用useRefscrollIntoView

  • 对于你想要滚动到的元素使用__abc0:这里我想滚动到PieceTabs元素,这就是为什么我用Box(div)包装它,这样我就可以访问dom元素

您可能对refs很熟悉,它主要是作为一种访问DOM的方式。如果你传递一个ref对象给React, React会在相应的DOM节点发生变化时将其.current属性设置为相应的DOM节点。参见医生

...
const tabsRef = useRef()
...
<Box ref={tabsRef}>
<PieceTabs piece={piece} value={value} handleChange={handleChange} />
</Box>
...
  • 创建一个处理滚动的函数:
  const handleSeeCompleteList = () => {
const tabs = tabsRef.current
if (tabs) {
tabs.scrollIntoView({
behavior: 'smooth',
block: 'start',
})
}
}
  • 当你点击滚动到目标时,在你想要的元素上调用这个函数:
 <Typography
variant="body2"
sx=\{\{
color: "#007BFF",
cursor: "pointer",
fontWeight: 500,
}}
onClick={(e) => {
handleChange(e, 2);
handleSeeCompleteList(); // here we go
}}
>
Voir toute la liste
</Typography>;

我们开始吧 React Js Scroll to using useRef and scrollIntoView < / p >