0

I want the div element to get the class of "showtext" when you scroll 100 pixels or less above the element. When you're 100 pixels or more above it, it has the class of "hidden".

I am trying to use a ref to access the div element, and use a method called showText to check and see when we scroll to 100 pixels or less above that div element, i'm using scrollTop for this.

Then i use componentDidMount to add a window event listener of scroll, and call my showText method.

I am new to this, so I am sure there is mistakes here and probably bad code. But any help is appreciated!

import React, {Component} from 'react';

class SlideIn extends Component{

    state={
        showTexts: false,
    }

    showText=()=>{
        const node= this.showTextRef;
        if(node.scollTop<=100)
        this.setState({
            showTexts: true
        })
    }



    componentDidMount(){
        window.addEventListener('scroll', this.showText() )
    }



    render(){
        const intro= document.querySelector('.intro')
        return(
            <div classname={this.state.showTexts ? 'showText' : 'hidden'} ref={node =>this.showTextRef = node}>
             {window.addEventListener('scroll', this.showText)}


                <h1>You did it!</h1> 
            </div>
        )
    }
}

export default SlideIn

I have tried using this.showText in my window scroll event, and as you see above this.showText(), neither have worked. I tried to use the current property on my div ref in my showText method, and it threw a error saying the scrollTop could not define the property of null.

Again I am new to this and have never added a window event listener this way, nor have I ever used scrollTop.

Thanks for any help!

4 Answers 4

1

When you attach an event listener you have to pass a function as a parameter. You are calling the function directly when you add the event listener.

In essence, you need to change:

componentDidMount(){
    window.addEventListener('scroll', this.showText() )
}

to:

componentDidMount(){
    window.addEventListener('scroll', this.showText)
}

In your scroll listener you should check the scroll position of the window(which is the element where you are performing the scroll):

showText = () => {
    if (window.scrollY <= 100) {
        this.setState({
            showTexts: true
        });
    }    
}

Also, you are attaching the event listener in the render method. The render method should only contain logic to render the elements.

Sign up to request clarification or add additional context in comments.

3 Comments

Hey @mgarcia I did try that with no luck :/
I updated the response to correct other points in the original code.
This was correct, but I did const top = window.pageYOffset; in my showText method, and did if(top>100){ The main issue I had was I was using CSS on body and html for overflow-x:hidden and that caused a issue with my scroll event listener. So I wrapped my whole main App component in a div and use overflow-x:hidden on that, and left body and html untouched, and the scroll event worked. Prior to that it would not work.
0

Pass function as parameter like

window.addEventListener('scroll', this.showText)

and remove it from return.

Then you just need to do only this in function

if(window.scrollY<=100)
    this.setState({
        showTexts: true
    })

use your div position here

Comments

0

You need to use getBoundingCLientRect() to get scroll position. window.addEventListener("scroll", this.showText); you need to pass this.showText instead of calling it. classname has speeling mistake.

showText = () => {
    const node = this.showTextRef;
    const {
        y = 0
    } = (node && node.getBoundingClientRect()) || {};

    this.setState({
        showTexts: y <= 100
    });
};

componentDidMount() {
    window.addEventListener("scroll", this.showText);
}

render() {
    const intro = document.querySelector(".intro");
    return (
       <div
          className={this.state.showTexts ? "showText" : "hidden"}
          ref={node => (this.showTextRef = node)}
       >
          <h1>You did it!</h1>
       </div>
   );
}

condesandbox of working example: https://codesandbox.io/s/intelligent-shannon-1p6sp

Comments

0

I've put together a working sample for you to reference, here's the link: https://codesandbox.io/embed/summer-forest-cksfh

There are few things to point out here in your code:

componentDidMount(){
        window.addEventListener('scroll', this.showText() )
    }

Just like mgracia has mentioned, using this.showText() means you're directly calling the function. The right way is just to use this.showText.

In showText function, the idea is you have to get how far user has scrolled from the top position of document. As it was called using:

const top = window.pageYOffset || document.documentElement.scrollTop;

now it's safe to check for your logic and set state according to the value you want, here I have put it like this:

this.setState({
  showTexts: top <= 100
})

In your componentDidMount, you have to call showText once to trigger the first time page loading, otherwise when you reload the page it won't trigger the function.

Hope this help

Full code:

class SlideIn extends Component {
  state = {
    showTexts: false,
  }

  showText = () => {
    // get how many px we've scrolled
    const top = window.pageYOffset || document.documentElement.scrollTop;
    this.setState({
      showTexts: top <= 100
    })
  }

  componentDidMount() {
    window.addEventListener('scroll', this.showText)
    this.showText();
  }

  render() {
    return (
      <div className={`box ${this.state.showTexts ? 'visible' : 'hidden'}`}
        ref={node => this.showTextRef = node}>
      
        <h1>You did it!</h1>
      </div>
    )
  }
}
.App {
  font-family: sans-serif;
  text-align: center;
  height: 2500px;
}

.box {
  width: 100px;
  height: 100px;
  background: blue;
  position: fixed;
  left: 10px;
  top: 10px;
  z-index: 10;
}

.visible {
  display: block;
}

.hidden {
  display: none;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.