397 votes

Comment faire défiler un élément ?

J'ai un widget de chat qui fait apparaître une série de messages chaque fois que je fais défiler la page. Le problème que je rencontre actuellement est que le curseur reste fixe en haut lorsque les messages sont chargés. Je veux qu'il se concentre sur le dernier élément de l'index du tableau précédent. J'ai compris que je pouvais créer des références dynamiques en passant l'index, mais j'aurais également besoin de savoir quel type de fonction de défilement utiliser pour y parvenir

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

  render() {

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

1 votes

Pour une solution groupée : npmjs.com/package/react-scroll-to-component

717voto

Ben Carp Points 1515

React 16.8 +, Composant fonctionnel

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

Cliquez ici pour une démo complète sur StackBlits

React 16.3 +, Composant de classe

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

Composant de classe - 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. 
}

N'utilisez pas d'arbitres de cordes.

Les références de chaîne nuisent aux performances, ne sont pas composables et sont en voie de disparition (août 2018).

Les références de chaîne ont quelques problèmes, sont considérées comme un héritage et sont susceptibles d'être supprimées dans l'un ou l'autre des cas. être supprimées dans l'une des futures versions. Documentation officielle de React]

ressource1 ressources2

Facultatif : Animation de défilement lisse

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

Passer la référence à un enfant

Nous voulons que la référence soit attachée à un élément dom, et non à un composant react. Ainsi, lorsque nous le passons à un composant enfant, nous ne pouvons pas nommer le prop ref.

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

Attachez ensuite la ref prop à un élément dom.

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

10 votes

window.scrollTo(0, offsetTop) est une meilleure option avec une meilleure prise en charge par les navigateurs actuels.

1 votes

Vous pourriez vous assurer que vous êtes cohérent dans votre exemple. Nous commençons par myRef, puis domRef, et nous terminons par tesNode ? C'est assez déroutant.

0 votes

Mes liens d'ancrage et les sections auxquelles je souhaite accéder ne se trouvent pas dans le même composant. Comment accéder à la référence de la section dans mon lien ?

133voto

chii Points 155

cela a fonctionné pour moi

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

EDIT : Je voulais développer ce point sur la base des commentaires.

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

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

1 votes

où mettre ceci

0 votes

dans une méthode ou un constructeur du cycle de vie

3 votes

Fonctionne comme un charme. Aucune des solutions ci-dessus ne fonctionne pour moi, ceci devrait être une réponse acceptée !

46voto

Roman Maksimov Points 1081

Trouvez simplement la position supérieure de l'élément que vous avez déjà déterminé. https://www.w3schools.com/Jsref/prop_element_offsettop.asp puis faire défiler jusqu'à cette position via scrollTo méthode https://www.w3schools.com/Jsref/met_win_scrollto.asp

Quelque chose comme ceci devrait fonctionner :

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 :

depuis React v16.3 le site React.createRef() est préféré

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

2 votes

C'est la meilleure réponse. Utilisation de ReactDOM.findDomNode() est une meilleure pratique - étant donné que React restitue les composants, un div que vous obtenez simplement par son ID peut ne plus exister au moment où vous appelez la fonction

5 votes

Selon la documentation officielle, vous devriez essayer d'éviter d'utiliser findDOMNode . Dans la plupart des cas, vous pouvez attacher une référence au nœud du DOM et éviter d'utiliser la fonction findDOMNode du tout.

1 votes

Notez que l'utilisation de this.refs par mappage de chaîne est dépréciée, voir : stackoverflow.com/questions/43873511/

14voto

sww314 Points 128

L'utilisation de findDOMNode va être dépréciée à terme.

La méthode préférée est d'utiliser des références de rappel.

github eslint

3 votes

Veuillez inclure la partie pertinente du matériel lié afin que votre réponse ne devienne pas inutile au cas où il serait supprimé.

10voto

Farshad J Points 91

Vous pouvez également utiliser scrollIntoView pour faire défiler un élément donné.

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

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X