it-swarm.com.de

Reagiert darauf, wie zu einem Element gescrollt wird

Ich habe ein Chat-Widget, das jedes Mal, wenn ich nach oben scrolle, eine Reihe von Nachrichten abruft. Das Problem, dem ich jetzt gegenüberstehe, ist, dass der Schieberegler beim Laden von Nachrichten am oberen Rand fixiert bleibt. Ich möchte, dass er sich auf das letzte Indexelement des vorherigen Arrays konzentriert. Ich habe herausgefunden, dass ich dynamische Refs erstellen kann, indem ich den Index übergebe, aber ich müsste auch wissen, welche Art von Bildlauffunktion verwendet werden muss, um dies zu erreichen

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

  render() {

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

Reaktion 16.8 +, funktionelle Komponente

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

Klicken Sie hier für eine vollständige Demo von StackBlits

Reagiere 16.3 +, Klassenkomponente

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. 

}

Klassenkomponente - Ref-Rückruf

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

Verwenden Sie keine String-Refs.

Saitenreflexionen beeinträchtigen die Leistung, sind nicht zusammensetzbar und befinden sich auf dem Weg nach draußen (August 2018).

string-Refs haben einige Probleme, gelten als Legacy und werden wahrscheinlich in einer der zukünftigen Versionen entfernt. [Offizielle React Dokumentation]

resource1resource2

Optional: Bildlaufanimation glätten

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

Ref an ein Kind übergeben

Wir möchten, dass der ref an ein dom-Element angehängt wird, nicht an eine reagierende Komponente. Wenn wir es also an eine untergeordnete Komponente übergeben, können wir die Stützenreferenz nicht benennen.

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

Befestigen Sie dann die ref-Stütze an einem dom-Element.

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

Suchen Sie einfach die oberste Position des Elements, das Sie bereits bestimmt haben https://www.w3schools.com/Jsref/prop_element_offsettop.asp und scrollen Sie dann mit der scrollTo -Methode zu dieser Position https://www.w3schools.com/Jsref/met_win_scrollto.asp

So etwas sollte funktionieren:

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:

da Reagiere v16.3 wird die Funktion React.createRef() bevorzugt

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>)
}
33
Roman Maksimov

das hat bei mir funktioniert

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

Die Verwendung von findDOMNode wird irgendwann veraltet sein.

Die bevorzugte Methode ist die Verwendung von Rückrufreferenzen.

Github Eslint

14
sww314

Sie können auch die Methode scrollIntoView verwenden, um zu einem bestimmten Element zu scrollen.

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

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

Ich könnte zu spät zur Party kommen, aber ich habe versucht, dynamische Refs auf die richtige Art und Weise in mein Projekt zu implementieren, und alle Antworten, die ich bis dahin gefunden habe, sind nicht ganz zufriedenstellend. Deshalb habe ich eine Lösung gefunden, die ich für richtig halte Einfach und verwendet die native und empfohlene Art zu reagieren, um die Referenz zu erstellen.

manchmal wird bei der Erstellung der Dokumentation davon ausgegangen, dass Sie über eine bekannte Anzahl von Ansichten verfügen. In den meisten Fällen ist diese Anzahl unbekannt. In diesem Fall müssen Sie eine Möglichkeit zur Behebung des Problems finden. Erstellen Sie dynamische Verweise auf die unbekannte Anzahl von Ansichten, die Sie benötigen in der Klasse zu zeigen

die einfachste Lösung, die mir einfiel und die einwandfrei funktionierte, war, wie folgt vorzugehen

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

auf diese Weise wird die Schriftrolle zu der Zeile verschoben, nach der Sie suchen.

prost und hoffe, es hilft anderen

7
Miguel Sedek

Sie könnten es so versuchen:

 handleScrollToElement = e => {
    const elementTop = this.gate.offsetTop;
    window.scrollTo(0, elementTop);
 };

 render(){
  return(
      <h2 ref={elem => (this.gate = elem)}>Payment gate</h2>
 )}
6

Sie können jetzt useRef über die API für Reaktions-Hooks verwenden

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

erklärung

let myRef = useRef()

komponente

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

Verwenden

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

Sie können so etwas wie componentDidUpdate verwenden.

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

Was hat bei mir funktioniert:

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

Verwenden Sie die Funktionszusammensetzung, um Implementierungsdetails auszublenden

Reagiere mit 16,8 + funktioneller Komponente

useScroll hook

Der folgende useScroll-Hook verbirgt Details zur Dom-Implementierung und stellt eine einfache API bereit.

const useScroll = () => {
  const htmlElRef = useRef(null)
  const executeScroll = () => {
    window.scrollTo(0, htmlElRef.current.offsetTop)
  }

  return [executeScroll, htmlElRef]
}

Dann können Sie ganz einfach in Ihren Funktionskomponenten scrollen.

const ScrollDemo = () => {
    const [executeScroll, elementToScrollRef] = useScroll()

    return (
        <>
            <div ref={elementToScrollRef}>I wanna be seen</div> 
            <button onClick={executeScroll}> Click to scroll </button> 
        </>
    )

}

Klicken Sie hier für eine vollständige Demo auf StackBlitz

Reagiere 16.3 + Klasse Komponente

utiliseScroll

Funktionszusammenstellung kann auch in Klassenkomponenten verwendet werden.

const utilizeScroll = () => {
  const htmlElRef = React.createRef()
  const executeScroll = () => {
    window.scrollTo(0, htmlElRef.current.offsetTop)
  }

  return {executeScroll, htmlElRef}
}

Verwenden Sie es dann in einer beliebigen Klassenkomponente

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

Klicken Sie hier für eine vollständige Demo auf StackBlitz

1
Ben Carp
 <div onScrollCapture={() => this._onScrollEvent()}></div>

 _onScrollEvent = (e)=>{
     const top = e.nativeEvent.target.scrollTop;
     console.log(top); 
}
0
ibamboo