Javascript 如何滚动到一个元素?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43441856/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to scroll to an element?
提问by edmamerto
I have a chat widget that pulls up an array of messages every time I scroll up. The problem I am facing now is the slider stays fixed at the top when messages load. I want it to focus on the last index element from the previous array. I figured out that I can make dynamic refs by passing index, but I would also need to know what kind of scroll function to use to achieve that
我有一个聊天小部件,每次向上滚动时都会拉出一系列消息。我现在面临的问题是当消息加载时滑块固定在顶部。我希望它关注上一个数组中的最后一个索引元素。我发现我可以通过传递索引来创建动态引用,但我还需要知道使用什么样的滚动函数来实现这一点
handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
if (some_logic){
//scroll to testNode
}
}
render() {
return (
<div>
<div ref="test"></div>
</div>)
}
回答by Ben Carp
React 16.8 +, Functional component
React 16.8+,函数式组件
import React, { useRef } from 'react'
const scrollToRef = (ref) => window.scrollTo(0, ref.current.offsetTop)
// General scroll to element function
const ScrollDemo = () => {
const myRef = useRef(null)
const executeScroll = () => scrollToRef(myRef)
return (
<>
<div ref={myRef}>I wanna be seen</div>
<button onClick={executeScroll}> Click to scroll </button>
</>
)
}
Click here for a full demo on StackBlits
React 16.3 +, Class component
React 16.3+,类组件
class ReadyToScroll extends Component {
constructor(props) {
super(props)
this.myRef = React.createRef()
}
render() {
return <div ref={this.myRef}></div>
}
scrollToMyRef = () => window.scrollTo(0, this.myRef.current.offsetTop)
// run this method to execute scrolling.
}
Class component - Ref callback
类组件 - Ref 回调
class ReadyToScroll extends Component {
myRef=null
// Optional
render() {
return <div ref={ (ref) => this.myRef=ref }></div>
}
scrollToMyRef = () => window.scrollTo(0, this.myRef.offsetTop)
// run this method to execute scrolling.
}
Don't use String refs.
不要使用字符串引用。
String refs harm performance, aren't composable, and are on their way out (Aug 2018).
字符串引用会损害性能,不可组合,并且即将消失(2018 年 8 月)。
string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases. [Official React documentation]
字符串引用有一些问题,被认为是遗留的,可能会在未来的版本之一中被删除。[官方 React 文档]
Optional: Smoothe scroll animation
可选:平滑滚动动画
/* css */
html {
scroll-behavior: smooth;
}
Passing ref to a child
将 ref 传递给孩子
We want the ref to be attached to a dom element, not to a react component. So when passing it to a child component we can't name the prop ref.
我们希望 ref 附加到一个 dom 元素,而不是一个 react 组件。因此,当将其传递给子组件时,我们无法命名 prop ref。
const MyComponent = () => {
const myRef = useRef(null)
return <ChildComp refProp={myRef}></ChildComp>
}
Then attach the ref prop to a dom element.
然后将 ref 属性附加到 dom 元素。
const ChildComp = (props) => {
return <div ref={props.refProp} />
}
回答by chii
this worked for me
这对我有用
this.anyRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })
EDIT:I wanted to expand on this based on the comments.
编辑:我想根据评论对此进行扩展。
const scrollTo = (ref) => {
if (ref /* + other conditions */) {
ref.scrollIntoView({ behavior: 'smooth', block: 'start' })
}
}
<div ref={scrollTo}>Item</div>
回答by Roman Maksimov
Just find the top position of the element you've already determined https://www.w3schools.com/Jsref/prop_element_offsettop.aspthen scroll to this position via scrollTomethod https://www.w3schools.com/Jsref/met_win_scrollto.asp
只需找到您已经确定的元素的顶部位置https://www.w3schools.com/Jsref/prop_element_offsettop.asp然后通过scrollTo方法https://www.w3schools.com/Jsref/met_win_scrollto.asp滚动到该位置
Something like this should work:
这样的事情应该工作:
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>)
}
UPDATE:
更新:
since React v16.3the React.createRef()is preferred
因为阵营v16.3的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>)
}
回答by sww314
Using findDOMNode is going to be deprecated eventually.
使用 findDOMNode 最终将被弃用。
The preferred method is to use callback refs.
首选方法是使用回调引用。
回答by Tanapruk Tangphianphan
You can now use useReffrom react hook API
您现在可以使用useReffrom react hook API
https://reactjs.org/docs/hooks-reference.html#useref
https://reactjs.org/docs/hooks-reference.html#useref
declaration
宣言
let myRef = useRef()
component
成分
<div ref={myRef}>My Component</div>
Use
用
window.scrollTo({ behavior: 'smooth', top: myRef.current.offsetTop })
回答by Farshad J
You can also use scrollIntoViewmethod to scroll to a given element.
您还可以使用scrollIntoView方法滚动到给定元素。
handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
if (some_logic){
tesNode.scrollIntoView();
}
}
render() {
return (
<div>
<div ref="test"></div>
</div>)
}
回答by Miguel Sedek
I might be late to the party but I was trying to implement dynamic refs to my project the proper way and all the answer I have found until know aren't quiet satisfying to my liking, so I came up with a solution that I think is simple and uses the native and recommended way of react to create the ref.
我可能会迟到,但我正在尝试以正确的方式对我的项目实施动态引用,并且我找到的所有答案都没有让我满意,所以我想出了一个我认为是的解决方案简单并使用本机和推荐的反应方式来创建参考。
sometimes you find that the way documentation is wrote assumes that you have a known amount of views and in most cases this number is unknown so you need a way to solve the problem in this case, create dynamic refs to the unknown number of views you need to show in the class
有时您会发现编写文档的方式假设您拥有已知数量的视图,而在大多数情况下,这个数字是未知的,因此在这种情况下您需要一种解决问题的方法,为您需要的未知数量的视图创建动态引用在课堂上展示
so the most simple solution i could think of and worked flawlessly was to do as follows
所以我能想到并完美工作的最简单的解决方案是执行以下操作
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 `
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
that way the scroll will go to whatever row you are looking for..
这样滚动将转到您要查找的任何行..
cheers and hope it helps others
欢呼并希望它可以帮助他人
回答by jirina Brezinova
You could try this way:
你可以试试这样:
handleScrollToElement = e => {
const elementTop = this.gate.offsetTop;
window.scrollTo(0, elementTop);
};
render(){
return(
<h2 ref={elem => (this.gate = elem)}>Payment gate</h2>
)}
回答by Ben Carp
Jul 2019 - Dedicated hook/function
2019 年 7 月 - 专用钩子/函数
A dedicated hook/function can hide implementation details, and provides a simple API to your components.
专用的钩子/函数可以隐藏实现细节,并为您的组件提供简单的 API。
React 16.8 + Functional Component
React 16.8 + 函数式组件
const useScroll = () => {
const htmlElRef = useRef(null)
const executeScroll = () => window.scrollTo(0, htmlElRef.current.offsetTop)
return [executeScroll, htmlElRef]
}
Use it in any functional component.
在任何功能组件中使用它。
const ScrollDemo = () => {
const [executeScroll, htmlElRef] = useScroll()
useEffect(executeScroll, []) // Runs after component mounts
return <div ref={htmlElRef}>Show me</div>
}
React 16.3 + class Component
React 16.3 + 类组件
const utilizeScroll = () => {
const htmlElRef = React.createRef()
const executeScroll = () => window.scrollTo(0, htmlElRef.current.offsetTop)
return {executeScroll, htmlElRef}
}
Use it in any class component.
在任何类组件中使用它。
class ScrollDemo extends Component {
constructor(){
this.elScroll = utilizeScroll()
}
componentDidMount(){
this.elScroll.executeScroll()
}
render(){
return <div ref={this.elScroll.htmlElRef}>Show me</div>
}
}
回答by Raviteja
You can use something like componentDidUpdate
你可以使用类似的东西 componentDidUpdate
componentDidUpdate() {
var elem = testNode //your ref to the element say testNode in your case;
elem.scrollTop = elem.scrollHeight;
};

