ReactJS как прокручивать элемент
У меня есть виджет чата, который вытягивает массив сообщений каждый раз, когда я прокручиваю вверх. Проблема, с которой я столкнулся сейчас, заключается в том, что слайдер остается зафиксированным вверху при загрузке сообщений, я хочу, чтобы он сосредоточился на последнем элементе индекса из предыдущего массива. Я понял, что могу делать динамические ссылки, передавая индекс, но мне также нужно знать, какую функцию прокрутки можно использовать для достижения этого
handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
if (some_logic){
//scroll to testNode
}
}
render() {
return (
<div>
<div ref="test"></div>
</div>)
}
Ответы
Ответ 1
Реакция 16.8+, функциональный компонент
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 (
<> {/* React.Fragment*/}
<div ref={myRef}>I wanna be seen</div>
<button onClick={executeScroll}> Click to scroll </button>
</>
)
}
Нажмите здесь, чтобы получить полную демонстрацию по StackBlits
Реакция 16.3+, компонент класса
class ReadyToScroll extends Component {
constructor(props) {
super(props)
this.myRef = React.createRef() // Create a ref object
}
render() {
return <div ref={this.myRef}></div>
} // attach the ref property to a dom element
scrollToMyRef = () => window.scrollTo(0, this.myRef.current.offsetTop)
// run this method to execute scrolling.
}
Компонент класса - ссылка обратного вызова
class ReadyToScroll extends Component {
constructor(props){ // Optional, declare a class field to improve readability
super(props)
this.myRef=null
}
render() {
return <div ref={ (ref) => this.myRef=ref }></div>
} // Attach the dom element to a class field
scrollToMyRef = () => window.scrollTo(0, this.myRef.offsetTop)
// run this method to execute scrolling.
}
Не используйте строковые ссылки.
Строковые ссылки вредят производительности, не поддаются компоновке и находятся на выходе (август 2018 г.).
Строковые ссылки имеют некоторые проблемы, считаются устаревшими и могут быть удаленным в одном из будущих выпусков. [Официальная документация React]
resource1resource2
Необязательно: сгладить анимацию прокрутки
/* css */
html {
scroll-behavior: smooth;
}
Передача ссылки ребенку
Мы хотим, чтобы ссылка была прикреплена к элементу dom, а не к компоненту реакции. Таким образом, передавая его дочернему компоненту, мы не можем назвать опорный реф.
const MyComponent = () => {
const myRef = useRef(null)
return <ChildComp refProp={myRef}></ChildComp>
}
Затем прикрепите опорный элемент к элементу dom.
const ChildComp = (props) => {
return <div ref={props.refProp} />
}
Ответ 2
Просто найдите верхнюю позицию элемента, который вы уже определили https://www.w3schools.com/Jsref/prop_element_offsettop.asp, затем scrollTo
к этой позиции с помощью метода scrollTo
https://www.w3schools.com/Jsref/met_win_scrollto. гадюка
Примерно так должно работать:
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>)
}
ОБНОВИТЬ:
поскольку React 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>)
}
Ответ 3
это сработало для меня
this.anyRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })
Ответ 4
Использование findDOMNode в конечном итоге будет устаревшим.
Предпочтительным методом является использование обратных ссылок.
Github Eslint
Ответ 5
Вы также можете использовать метод scrollIntoView
для прокрутки к определенному элементу.
handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
if (some_logic){
tesNode.scrollIntoView();
}
}
render() {
return (
<div>
<div ref="test"></div>
</div>)
}
Ответ 6
Возможно, я опоздал на вечеринку, но я пытался правильно реализовать динамические ссылки в своем проекте, и все ответы, которые я нашел до тех пор, пока не узнали, не удовлетворяют меня по вкусу, поэтому я нашел решение, которое, мне кажется, простой и использует родной и рекомендуемый способ реагирования для создания ссылки.
иногда вы обнаруживаете, что при написании документации предполагается, что у вас есть известное количество просмотров, и в большинстве случаев это число неизвестно, поэтому в этом случае вам нужен способ решения проблемы, создайте динамические ссылки на неизвестное количество просмотров, которое вам нужно показать в классе
поэтому самое простое решение, которое я мог придумать и работать безупречно, заключалось в следующем
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
Таким образом, свиток перейдет в любую строку, которую вы ищете..
ура и надеюсь, что это помогает другим
Ответ 7
Вы можете попробовать так:
handleScrollToElement = e => {
const elementTop = this.gate.offsetTop;
window.scrollTo(0, elementTop);
};
render(){
return(
<h2 ref={elem => (this.gate = elem)}>Payment gate</h2>
)}
Ответ 8
Теперь вы можете использовать useRef
из API реакционного хука
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 })
Ответ 9
Вы можете использовать что-то вроде componentDidUpdate
componentDidUpdate() {
var elem = testNode //your ref to the element say testNode in your case;
elem.scrollTop = elem.scrollHeight;
};
Ответ 10
Используйте композицию функций, чтобы скрыть детали реализации
Реакция 16.8 + функциональный компонент
крючок useScroll
Следующий хук useScroll скрывает детали реализации dom и предоставляет простой API.
const useScroll = () => {
const htmlElRef = useRef(null)
const executeScroll = () => {
window.scrollTo(0, htmlElRef.current.offsetTop)
}
return [executeScroll, htmlElRef]
}
Тогда вы можете легко прокрутить ваши функциональные компоненты.
const ScrollDemo = () => {
const [executeScroll, elementToScrollRef] = useScroll()
return (
<>
<div ref={elementToScrollRef}>I wanna be seen</div>
<button onClick={executeScroll}> Click to scroll </button>
</>
)
}
Нажмите здесь для полной демонстрации на StackBlitz
Реагировать 16,3 + класс Компонент
utilizeScroll
Функция compositioin может быть использована и в компонентах класса.
const utilizeScroll = () => {
const htmlElRef = React.createRef()
const executeScroll = () => {
window.scrollTo(0, htmlElRef.current.offsetTop)
}
return {executeScroll, htmlElRef}
}
Затем используйте его в любом компоненте класса
class ScrollDemo extends Component {
constructor(){
this.elScroll = utilizeScroll()
}
render(){
return (
<>
<div ref={this.elScroll.htmlElRef}>I wanna be seen</div>
<button onClick={this.elScroll.executeScroll} >Click to scroll </button>
</>
)
}
}
Нажмите здесь для полной демонстрации на StackBlitz
Ответ 11
Что сработало для меня:
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>
)
}
}
Ответ 12
После тестирования нескольких решений, прокрутите список компонентов.
Используя $ внутри класса Component, он по-прежнему позволяет применять прокрутку к любому элементу с помощью селектора xpath.
import React from 'react';
import $ from "jquery"
scrollToElem() {
var elem= $( ".selector" )[0];
$('html, body').animate({
scrollTop: $(elem).offset().top
}, 1800);
}
Ответ 13
<div onScrollCapture={() => this._onScrollEvent()}></div>
_onScrollEvent = (e)=>{
const top = e.nativeEvent.target.scrollTop;
console.log(top);
}