Javascript 更改 reactjs 中的 scrollTop
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33748967/
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
change scrollTop in reactjs
提问by edeity
I just learn react, and want to achieve a function : both A,B are components, if A scroll, then B scroll
我刚学react,想实现一个功能: A,B都是组件,如果A滚动,那么B滚动
The following is my code
以下是我的代码
<A onScroll="handleScroll"></A>
<A onScroll="handleScroll"></A>
//what i write now
handleScroll: function(event){
var target = event.nativeEvent.target;
//do something to change scrollTop value
target.scrollTop += 1;
// it looks the same as not use react
document.getElementById(B).scrollTop = target.scrollTop;
}
but actually I want my code like this
但实际上我想要这样的代码
//what i want
<A scrollTop={this.props.scrollSeed}></A>
<B scrollTop={this.props.scrollSeed}></B>
//...
handleScroll(){
this.setState({scrollSeed: ++this.state.scrollSeed})
}
it is similar to input
它类似于 input
<input value="this.props.value"/>
<input value="this.props.value"/>
<input ref='c' onChange={handleChange}>
//...
handleChange: function() {
// enter some code in c and then render in a and b automatically
}
In other words, I want some attribute, like scrollTop
(different
form <input value={}>
,because <A scrollTop={}>
doesn't work) ,is bind with some state, so that I can just use setState
, and they will update by themselves.
换句话说,我想要一些属性,比如scrollTop
(不同的形式<input value={}>
,因为<A scrollTop={}>
不起作用),与一些状态绑定,这样我就可以使用setState
,它们会自己更新。
I googled before but can't find the answser. I hope that my poor English won't confuse you.
我之前用谷歌搜索过,但找不到答案。我希望我糟糕的英语不会让你感到困惑。
回答by Season
There are a number of patterns to achieve this. This sampleis what I came up with to get you up and going.
有许多模式可以实现这一点。这个样本是我想出来的,目的是让你站起来。
First create a component class which has an oversize element for scroll effect. When dragging the scroll bar, this component calls its handleScroll
React property to notify its parent component, with the value of scrollTop
.
首先创建一个组件类,它具有用于滚动效果的超大元素。拖动滚动条时,该组件调用其handleScroll
React 属性通知其父组件,值为scrollTop
。
var Elem = React.createClass({
render() {
return (
<div ref="elem"
onScroll={ this.onScroll }
style={{ width: "100px", height: "100px", overflow: "scroll" }}>
<div style={{ width: "100%", height: "200%" }}>Hello!</div>
</div>
);
},
componentDidUpdate() {
this.refs.elem.scrollTop = this.props.scrollTop;
},
onScroll() {
this.props.handleScroll( this.refs.elem.scrollTop );
}
});
The parent component, aka wrapper, keeps the scroll top value in its state. Its handleScroll
is passed to the child components as callback. Any scroll on the child elements triggers the callback, sets the state, results in a redraw, and updates the child component.
父组件,又名包装器,将滚动顶部值保持在其状态。它handleScroll
作为回调传递给子组件。子元素上的任何滚动都会触发回调、设置状态、导致重绘并更新子组件。
var Wrapper = React.createClass({
getInitialState() {
return {
scrollTop: 0
}
},
render() {
return (
<div>
<Elem scrollTop={ this.state.scrollTop } handleScroll={ this.handleScroll } />
<Elem scrollTop={ this.state.scrollTop } handleScroll={ this.handleScroll } />
</div>
);
},
handleScroll( scrollTop ) {
this.setState({ scrollTop });
}
});
And render the wrapper, presuming an existing <div id="container"></div>
.
并渲染包装器,假设现有<div id="container"></div>
.
ReactDOM.render(
<Wrapper />,
document.getElementById('container')
);
回答by Jerry Green
2019's answer
2019年的答案
First, the fix:
首先,修复:
const resetScrollEffect = ({ element }) => {
element.current.getScrollableNode().children[0].scrollTop = 0
}
const Table = props => {
const tableRef = useRef(null)
useEffect(() => resetScrollEffect({ element: tableRef }), [])
return (
<Component>
<FlatList
ref={someRef}
/>
</Component>
)
}
Second, a little explanation:
二、稍微解释一下:
Idk what is your reason why you got here but I have used flex-direction: column-reverse
for my FlatList (it's a list of elements). And I need this property for z-index
purposes. However, browsers set their scroll position to the end for such elements (tables, chats, etc.) - this may be useful but I don't need that in my case.
不知道您来到这里的原因是什么,但我已将其用于flex-direction: column-reverse
我的 FlatList(它是一个元素列表)。我需要这个属性z-index
。但是,浏览器将它们的滚动位置设置为此类元素(表格、聊天等)的末尾 - 这可能很有用,但在我的情况下我不需要。
Also, example is shown using React Hooks, but you can use oldermore traditional way of defining refs
此外,示例使用React Hooks 显示,但您可以使用更旧的更传统的方式来定义 refs
回答by Lukas Liesis
this.refs is deprecated. use reactjs.org/docs/refs-and-the-dom.html#creating-refs
this.refs 已弃用。使用 reactjs.org/docs/refs-and-the-dom.html#creating-refs
import React from 'react';
class SomeComponent extends React.Component {
constructor(props) {
super(props);
this.resultsDiv = React.createRef();
}
someFunction(){
this.resultsDiv.current.scrollIntoView({behavior: 'smooth'});
// alternative:
// this.resultsDiv.current.scrollTop = 0;
}
render() {
return (
<div ref={this.resultsDiv} />
);
}
}
export default SomeComponent;
回答by Don Kirkby
Here's an updated version of Season's answer, including a runnable snippet. It uses the recommended method for creating refs.
这是Season's answer的更新版本,包括一个可运行的片段。它使用推荐的方法来创建 refs。
class Editor extends React.Component {
constructor(props) {
super(props);
this.content = React.createRef();
this.handleScroll = this.handleScroll.bind(this);
}
componentDidUpdate() {
this.content.current.scrollTop = this.props.scrollTop;
}
handleScroll() {
this.props.onScroll( this.content.current.scrollTop );
}
render() {
let text = 'a\n\nb\n\nc\n\nd\n\ne\n\nf\n\ng';
return <textarea
ref={this.content}
value={text}
rows="10"
cols="30"
onScroll={this.handleScroll}/>;
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {scrollTop: 0};
this.handleScroll = this.handleScroll.bind(this);
}
handleScroll(scrollTop) {
this.setState({scrollTop: scrollTop});
}
render() {
return <table><tbody>
<tr><th>Foo</th><th>Bar</th></tr>
<tr>
<td><Editor
scrollTop={this.state.scrollTop}
onScroll={this.handleScroll}/></td>
<td><Editor
scrollTop={this.state.scrollTop}
onScroll={this.handleScroll}/></td>
</tr>
</tbody></table>;
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>