Hoe te scrollen naar een element?

Ik heb een chat-widget die elke keer dat ik omhoog een reeks berichten weergeeft. Het probleem waarmee ik nu ga zijn, is de schuifregelaar die aan de bovenkant is bevestigd wanneer berichten worden geladen. Ik wil dat het zich richt op het laatste indexelement van de vorige array. Ik dacht dat ik dynamische ref-gegevens kan maken door index te passeren, maar ik zou ook moeten weten wat voor soort scroll-functie om dat te bereiken

handleScrollToElement(event) {
    const tesNode = ReactDOM.findDOMNode(this.refs.test)
    if (some_logic){
      //scroll to testNode      
    }
  }
  render() {
    return (
      <div>
        <div ref="test"></div>
      </div>)
  }

Antwoord 1, Autoriteit 100%

React 16.8 +, functionele component

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> 
      </>
   )
}

Klik hier voor een volledige demo op stapblits

reageren 16.3 +, klassencomponent

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. 
}

Klasse component – Ref callback

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. 
}

Gebruik geen tekenreeksreferenties.

Stringrefs schaden de prestaties, kunnen niet worden samengesteld en zijn op weg naar buiten (augustus 2018).

stringrefs hebben een aantal problemen, worden als verouderd beschouwd en zullen dat waarschijnlijk ook doen
worden verwijderd in een van de toekomstige releases. [Officiële React-documentatie]

bron1resource2

Optioneel: vloeiende scrollanimatie

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

Verwijzing doorgeven aan een kind

We willen dat de ref aan een dom-element wordt gekoppeld, niet aan een react-component. Dus als we het doorgeven aan een onderliggende component, kunnen we de propreferentie niet noemen.

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

Bevestig vervolgens de ref-prop aan een dom-element.

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

Antwoord 2, autoriteit 18%

dit werkte voor mij

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

EDIT:ik wilde dit uitbreiden op basis van de opmerkingen.

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

Antwoord 3, autoriteit 8%

Zoek gewoon de toppositie van het element dat je al hebt bepaald https://www.w3schools .com/Jsref/prop_element_offsettop.aspscrol vervolgens naar deze positie via de scrollTo-methode https://www.w3schools.com/Jsref/met_win_scrollto.asp

Zoiets zou moeten werken:

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:

sinds React v16.3heeft de React.createRef()de voorkeur

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>)
}

Antwoord 4, autoriteit 3%

U kunt nu useRefvan react hook API gebruiken

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

verklaring

let myRef = useRef()

component

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

Gebruik

window.scrollTo({ behavior: 'smooth', top: myRef.current.offsetTop })

Antwoord 5, autoriteit 3%

Het gebruik van findDOMNode wordt uiteindelijk afgeschaft.

De voorkeursmethode is het gebruik van terugbelreferen.

github eslint


Antwoord 6, autoriteit 2%

Jul 2019 – Speciale haak/functie

Een speciale hook/functie kan implementatiedetails verbergen en biedt een eenvoudige API voor uw componenten.

Reageren 16.8 + functionele component

const useScroll = () => {
  const elRef = useRef(null);
  const executeScroll = () => elRef.current.scrollIntoView();
  return [executeScroll, elRef];
};

Gebruik het in elk functioneel onderdeel.

const ScrollDemo = () => {
    const [executeScroll, elRef] = useScroll()
    useEffect(executeScroll, []) // Runs after component mounts
    return <div ref={elRef}>Element to scroll to</div> 
}

volledige demo

Reageren 16.3 + klasse Component

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

Gebruik het in elk klasonderdeel.

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> 
  }
} 

Volledige demo


Antwoord 7, autoriteit 2%

Je kunt ook de scrollIntoViewmethode gebruiken om naar een bepaald element te scrollen.

handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
 if (some_logic){
  tesNode.scrollIntoView();
  }
 }
 render() {
  return (
   <div>
     <div ref="test"></div>
   </div>)
}

Antwoord 8, autoriteit 2%

Misschien ben ik te laat op het feest, maar ik probeerde dynamische refs op de juiste manier in mijn project te implementeren en alle antwoorden die ik tot nu toe heb gevonden, zijn niet bevredigend naar mijn smaak, dus kwam ik met een oplossing die Ik denk dat het eenvoudig is en de oorspronkelijke en aanbevolen manier van reageren gebruikt om de ref te maken.

soms merk je dat de manier waarop documentatie wordt geschreven veronderstelt dat je een bekend aantal views hebt en in de meeste gevallen is dit aantal onbekend, dus je hebt in dit geval een manier nodig om het probleem op te lossen, maak dynamische verwijzingen naar het onbekende aantal van weergaven die je in de klas moet laten zien

dus de meest eenvoudige oplossing die ik kon bedenken en die perfect werkte, was om het als volgt te doen

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

op die manier gaat de scroll naar de rij die u zoekt..

proost en ik hoop dat het anderen helpt


Antwoord 9, autoriteit 2%

Ik had een eenvoudig scenario, wanneer de gebruiker klikt op het menu-item in mijn materiaal UI NAVBAR Ik wil ze naar het gedeelte op de pagina scrollen. Ik zou Refs kunnen gebruiken en ze door alle componenten doorschakelen, maar ik haat met draadroepen die meerdere componenten rekten, omdat dat code fragiel maakt.

Ik heb net vanille JS in mijn reactcomponent gebruikt, blijkt dat het prima werkt. Geplaatst een ID op het element dat ik wilde scrollen naar en in mijn header-component heb ik dit gewoon gedaan.

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

Antwoord 10, Autoriteit 2%

De leukste manier is om element.scrollIntoView({ behavior: 'smooth' }). Dit scrolt het element in het zicht met een mooie animatie.

Wanneer u het combineert met de useRef(), kan het de volgende manier worden gedaan.

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>
    )
}

Wanneer u naar een reactcomponent wilt bladeren, moet u de REF naar het gerenderde element doorsturen. Dit artikel zal dieper in het probleem duiken .


Antwoord 11

je zou op deze manier kunnen proberen:

handleScrollToElement = e => {
    const elementTop = this.gate.offsetTop;
    window.scrollTo(0, elementTop);
 };
 render(){
  return(
      <h2 ref={elem => (this.gate = elem)}>Payment gate</h2>
 )}

Antwoord 12

U kunt iets als componentDidUpdate

gebruiken

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

Antwoord 13

Hier is de Class Component Code Snippet die u kunt gebruiken om dit probleem op te lossen:

Deze aanpak gebruikte de REF en scrolt soepel naar het doel 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>
    )
  }
}

Antwoord 14

Ik heb dit in een onclick-functie gebruikt om soepel naar een div te scrollen waarvan de id “step2Div” is.

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

Antwoord 15

Volg deze stappen:

1)Installeren:

npm install react-scroll-to --save

2)Importeer het pakket:

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

3)Gebruik:

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

Antwoord 16

Na het lezen van vele forums een heel gemakkelijke oplossing gevonden.

Ik gebruik redux-form. Urgo heeft redux-from fieldToClass in kaart gebracht. Bij een fout navigeer ik naar de eerste fout op de lijst met syncErrors.

Geen referenties en geen modules van derden. Gewoon simpele 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" })
}

Antwoord 17

Als iemand Typescript gebruikt, is hier het antwoord van 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];
};

Antwoord 18

Wat voor mij werkte:

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>
        )
    }
}

Antwoord 19

Als je het wilt doen bij het laden van de pagina, kun je useLayoutEffectgebruiken , en useRef.

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>
      </>
   )
}

Antwoord 20

Om automatisch naar het specifieke element te scrollen, moeten we eerst het element selecteren met document.getElementByIden dan moeten we scrollen met scrollIntoView(). Raadpleeg de onderstaande code.

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

De bovenstaande aanpak werkte voor mij.


Antwoord 21

Even een waarschuwing, ik kon deze oplossingen niet laten werken op Material UI-componenten. Het lijkt erop dat ze de eigenschap currentniet hebben.

Ik heb zojuist een lege divtoegevoegd aan mijn componenten en daarop de ref-prop ingesteld.


Antwoord 22

Hier is mijn oplossing:

Ik heb een onzichtbare div in de hoofd-div geplaatst en de positie ervan absoluut gemaakt. Stel vervolgens de topwaarde in op -(header height) en stel de ref in op deze div. Of je kunt gewoon reageren op die div met kinderen-methode.

Het werkt tot nu toe prima!

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

Antwoord 23

Deze oplossing werkt voor mij in ReactJS

In header.js

function scrollToTestDiv(){
      const divElement = document.getElementById('test');
      divElement.scrollIntoView({ behavior: 'smooth' });
    }
<a class="nav-link" onClick={scrollToTestDiv}> Click here! </a>

In index.html

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

Antwoord 24

<div onScrollCapture={() => this._onScrollEvent()}></div>
 _onScrollEvent = (e)=>{
     const top = e.nativeEvent.target.scrollTop;
     console.log(top); 
}

Antwoord 25

Voor iedereen die dit leest en die niet veel geluk heeft gehad met de bovenstaande oplossingen of die gewoon een eenvoudige drop-in-oplossing wil, dit pakket werkte voor mij: https://www.npmjs.com/package/react-anchor-link-smooth-scroll. Veel plezier met hacken!

Other episodes