किसी तत्व में कैसे स्क्रॉल करें?


181

मेरे पास एक चैट विजेट है जो हर बार मेरे स्क्रॉल करते समय संदेशों की एक सरणी खींचता है। संदेश लोड होने पर अब मैं जिस समस्या का सामना कर रहा हूं, वह स्लाइडर शीर्ष पर स्थिर है। मैं चाहता हूं कि यह पिछले एरे से आखिरी इंडेक्स एलिमेंट पर फोकस करे। मुझे लगा कि मैं इंडेक्स पास करके डायनामिक रीफ बना सकता हूं, लेकिन मुझे यह भी जानना होगा कि इसे हासिल करने के लिए किस तरह के स्क्रॉल फंक्शन का उपयोग करना चाहिए

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

  render() {

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

1
एक बंडल समाधान के लिए: npmjs.com/package/react-scroll-to-component
tokland

जवाबों:


301

प्रतिक्रिया 16.8 +, कार्यात्मक घटक

import React, { useRef } from 'react'

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

    render() {
        return <div ref={this.myRef}></div> 
    }  

    scrollToMyRef = () => window.scrollTo(0, this.myRef.current.offsetTop)   
    // run this method to execute scrolling. 

}

क्लास कंपोनेंट - रिफबैक कॉलबैक

class ReadyToScroll extends Component {
    myRef=null
    // Optional

    render() {
        return <div ref={ (ref) => this.myRef=ref }></div>
    } 

    scrollToMyRef = () => window.scrollTo(0, this.myRef.offsetTop)
    // run this method to execute scrolling. 
}

स्ट्रिंग रेफरी का उपयोग न करें।

स्ट्रिंग refs नुकसान के प्रदर्शन, नहीं कर रहे हैं, और उनकी राह से बाहर (अगस्त 2018)।

स्ट्रिंग रिफ में कुछ मुद्दे होते हैं, जिन्हें विरासत माना जाता है, और भविष्य के रिलीज में से एक में हटाए जाने की संभावना है। [आधिकारिक प्रतिक्रिया दस्तावेज]

संसाधन 1 संसाधन 2

वैकल्पिक: Smoothe स्क्रॉल एनीमेशन

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

एक बच्चे को पासिंग रेफरी

हम चाहते हैं कि रेफ एक डोम तत्व से जुड़ा हो, न कि किसी रिएक्शन कंपोनेंट से। इसलिए इसे एक बच्चे के घटक के पास करते समय हम प्रोप रेफरी का नाम नहीं दे सकते।

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

फिर रेफ प्रोप को डोम तत्व से जोड़ दें।

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

5
window.scrollTo(0, offsetTop)मौजूदा ब्राउज़रों में बेहतर समर्थन के साथ एक बेहतर विकल्प है
MoMo

1
यह सुनिश्चित कर सकता है कि आप अपनी छूट के अनुरूप हैं। हम myRef से शुरू कर रहे हैं, domRef के साथ जा रहे हैं, और tesNode के साथ समाप्त हो रहे हैं। यह काफी भ्रामक है
लुइस लेकोक

4
तथ्य के बाद स्पष्ट है, लेकिन यह उल्लेख करना महत्वपूर्ण है कि यह केवल देशी डोम तत्वों के लिए काम करता है और न ही किसी भी रिएक्ट घटक।
jpunk11

1
@ jpunk11 मैंने अभी अपना उत्तर अपडेट किया है। अपडेट किया गया उत्तर बताता है कि डोम तत्व पर स्क्रॉल कैसे करें जो कि चाइल्ड क्लास घटक में है।
बेन कार्प ने

2
@SimonFranzen मेरे अद्यतन उत्तर - TLDR - वर्ग घटक मामले पर एक नज़र डालें। जब ScrollToMyRef कहा जाता है, तो यह उस बच्चे को स्क्रॉल कर देगा जिसे आपने रेफ को संलग्न किया था। आप एक अलग चाइल्ड कंपोनेंट के लिए विधि पास कर सकते हैं, और इसे वहां से ट्रिगर कर सकते हैं।
बेन कार्प ने

55

यह मेरे लिए काम किया

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

संपादित करें: मैं टिप्पणियों के आधार पर इस पर विस्तार करना चाहता था।

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

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

1
इसे कहां
रखें

जीवन चक्र विधि या निर्माता में
su_sundariya

1
एक जादू की तरह काम करता है। उपरोक्त में से कोई भी मेरे लिए काम नहीं करता है, इसे स्वीकार किया जाना चाहिए!
शिन

1
मेरे लिए काम किया, बस ध्यान दें कि 'प्रारंभ' 'ब्लॉक' पैरामीटर का डिफ़ॉल्ट मान है।
लिरोन लवी

यह मेरे लिए काम किया जब @Ben कार्प का जवाब नहीं होगा।
जेसन मास्टर्स

37

बस आपके द्वारा पहले से निर्धारित तत्व की शीर्ष स्थिति का पता लगाएं https://www.w3schools.com/Jsref/prop_element_offsettop.asp तब इस स्थिति पर स्क्रॉल करें scrollToविधि https://www.w3schools.com/Jsref/met_win_scrollto.asp

कुछ इस तरह काम करना चाहिए:

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

अपडेट करें:

के बाद से 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>)
}

2
यह बेहतर उत्तर है। उपयोग करना ReactDOM.findDomNode()बेहतर अभ्यास है - चूंकि रिएक्ट फिर से रेंडर करता है, एक डिव जो आपको बस इसकी आईडी से मिलता है, जब तक आप फ़ंक्शन को कॉल नहीं करते, तब तक मौजूद नहीं हो सकता
Good Idea

4
आधिकारिक दस्तावेज के अनुसार आपको उपयोग करने से बचने की कोशिश करनी चाहिए findDOMNode। ज्यादातर मामलों में, आप DOM नोड में एक रेफरी संलग्न कर सकते हैं और findDOMNodeसभी का उपयोग करने से बच सकते हैं।
Facyo Kouch

1
ध्यान दें कि स्ट्रिंग मानचित्रण द्वारा this.refs का उपयोग कर हटा दिया गया है, देखें: stackoverflow.com/questions/43873511/...
Himmet Avsar

1
नोट: मुझे this.myRef.current.scrollIntoView()इसके बजाय उपयोग करना था window.scrollTo(0, this.myRef)
Babbz77

14

FindDOMNode का उपयोग करके अंततः अपदस्थ किया जा रहा है।

पसंदीदा तरीका कॉलबैक रिफ का उपयोग करना है।

जीथब एस्लिंट


3
कृपया लिंक की गई सामग्री के संबंधित भाग को शामिल करें ताकि आपका उत्तर हटा दिया गया हो, बेकार नहीं जाए।
टेंटमेडली

12

अब आप useRefप्रतिक्रिया हुक एपीआई से उपयोग कर सकते हैं

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

मैं आपके कोड का उपयोग करने की कोशिश कर रहा हूं। मैं देख सकता हूं, इसके माध्यम से console.logयह आपके window.scrollToकथन (मेरे मामले के लिए समायोजित) को निष्पादित कर रहा है, लेकिन फिर भी यह स्क्रॉल नहीं करता है। यह इस तथ्य से संबंधित हो सकता है कि मैं एक प्रतिक्रिया बूटस्ट्रैप मोडल का उपयोग कर रहा हूं?
रोबर्टवर्नर_एसएफ

9

आप scrollIntoViewकिसी दिए गए तत्व को स्क्रॉल करने के लिए विधि का उपयोग भी कर सकते हैं ।

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

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

9

मुझे पार्टी में देर हो सकती है लेकिन मैं अपने प्रोजेक्ट के लिए डायनामिक रीफ्स को उचित तरीके से लागू करने की कोशिश कर रहा था और जब तक मुझे पता है कि मुझे अपनी पसंद के हिसाब से संतुष्ट नहीं किया जाता है, तब तक मुझे लगता है कि मुझे लगता है कि एक समाधान है सरल और रेफरी बनाने के लिए प्रतिक्रिया के मूल और अनुशंसित तरीके का उपयोग करता है।

कभी-कभी आप पाते हैं कि जिस तरह से दस्तावेज़ को लिखा गया है, वह मानता है कि आपके पास विचारों की एक ज्ञात राशि है और ज्यादातर मामलों में यह संख्या अज्ञात है, इसलिए आपको इस मामले में समस्या को हल करने के लिए एक तरीके की आवश्यकता है, अज्ञात नंबरों को आपके द्वारा आवश्यक विचारों की संख्या बनाने के लिए कक्षा में दिखाने के लिए

इसलिए सबसे सरल समाधान मैं सोच सकता था और निर्दोष रूप से काम करना था जो निम्नानुसार था

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

इस तरह से आप जिस भी पंक्ति को देख रहे हैं, उस तक स्क्रॉल जाएगा।

चीयर्स और आशा है कि यह दूसरों की मदद करता है


8

जुलाई 2019 - समर्पित हुक / कार्य

एक समर्पित हुक / फ़ंक्शन कार्यान्वयन विवरण छिपा सकता है, और आपके घटकों को एक साधारण एपीआई प्रदान करता है।

प्रतिक्रिया 16.8 + कार्यात्मक घटक

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

  return [executeScroll, htmlElRef]
}

किसी भी कार्यात्मक घटक में इसका उपयोग करें।

const ScrollDemo = () => {
    const [executeScroll, htmlElRef] = useScroll()
    useEffect(executeScroll, []) // Runs after component mounts

    return <div ref={htmlElRef}>Show me</div> 
}

पूर्ण डेमो

प्रतिक्रिया 16.3 + वर्ग घटक

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

  componentDidMount(){
    this.elScroll.executeScroll()
  }

  render(){
    return <div ref={this.elScroll.htmlElRef}>Show me</div> 
  }
} 

पूर्ण डेमो


7

आप इस तरह से कोशिश कर सकते हैं:

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

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

अच्छा समाधान, हालाँकि आप शायद इसके बजाय e.offsetTop चाहते हैं ।gate.offsetTop और फिर इस। G फ़ंक्शन को पास करें।
KingOfHypocrites

5

आप कुछ का उपयोग कर सकते हैं componentDidUpdate

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

3
मुझे लगता है कि प्रतिक्रिया में तत्व आईडी का उपयोग करना पसंद नहीं किया जाता है। यह आभासी डोम अवधारणा को तोड़ता है
iamsaksham

जीवन चक्र विधि का उपयोग कोड को चलाने के लिए WHEN / WHERE तक जाने का तरीका है। लेकिन संभवतः आप वास्तविक कोड
Dameo

3

मेरे पास एक सरल परिदृश्य था, जब उपयोगकर्ता मेरे मटेरियल यूआई नवबार में मेनू आइटम पर क्लिक करता है तो मैं उन्हें पृष्ठ पर अनुभाग में नीचे स्क्रॉल करना चाहता हूं। मैं सभी घटकों के माध्यम से रेफरी का उपयोग कर सकता हूं और उन्हें थ्रेड कर सकता हूं लेकिन मुझे थ्रेडिंग प्रॉपर प्रॉपर कई घटकों से नफरत है क्योंकि यह कोड को नाजुक बनाता है।

मैंने अपने रिएक्शन कंपोनेंट में सिर्फ वनीला जेएस का इस्तेमाल किया है, यह ठीक है। जिस तत्व को मैं अपने हेडर घटक में स्क्रॉल करना चाहता था, उस पर एक आईडी लगाया और मैंने बस यही किया।

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

2

इन कदमों का अनुसरण करें:

1) स्थापित करें:

npm install react-scroll-to --save

2) पैकेज आयात करें:

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

3) उपयोग:

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

2

यहाँ क्लास कंपोनेंट कोड स्निपेट है जिसका उपयोग आप इस समस्या को हल करने के लिए कर सकते हैं:

इस दृष्टिकोण ने रेफ का उपयोग किया और लक्ष्य रेफरी को भी आसानी से स्क्रॉल किया

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

1

मेरे लिए क्या काम किया:

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

बस एक सिर, मैं सामग्री यूआई घटकों पर काम करने के लिए इन समाधानों को प्राप्त नहीं कर सका। लगता है जैसे उनके पास नहीं हैcurrent संपत्ति ।

मैंने सिर्फ divअपने घटकों के बीच एक खाली जोड़ा और उस पर रेफ प्रोप सेट किया।


0
 <div onScrollCapture={() => this._onScrollEvent()}></div>

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

0

इसे पढ़ने वाले किसी अन्य व्यक्ति के लिए जो उपरोक्त समाधानों के साथ ज्यादा भाग्यशाली नहीं था या केवल एक सरल ड्रॉप-इन समाधान चाहता है, इस पैकेज ने मेरे लिए काम किया: https://www.npmjs.com/package/react-anchor-link- चिकनी-स्क्रॉल । हैप्पी हैकिंग!


0

मैंने इसे एक ऑनक्लिक फंक्शन के अंदर एक div पर आसानी से स्क्रॉल करने के लिए उपयोग किया, जहां इसकी आईडी "step2Div" है।

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

0

सबसे अच्छा तरीका उपयोग करना है element.scrollIntoView({ behavior: 'smooth' })। यह तत्व को एक अच्छे एनिमेशन के साथ स्क्रॉल करता है।

जब आप इसे रिएक्ट के साथ जोड़ते हैं useRef(), तो इसे निम्न तरीके से किया जा सकता है।

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

जब आप किसी रिएक्ट घटक पर स्क्रॉल करना चाहते हैं, तो आपको रेफरी को दिए गए तत्व को अग्रेषित करना होगा। यह लेख समस्या में गहरा गोता लगाएगा

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.