7

I am trying to use addEventListener when the user scroll into view <div id="container">. I have done so by scroll height but my attempts to addEventListener when <div> is on the top of the window.

handleHeaderStuck = () => {
    if (this.innerContainer.scrollTop <= 500 && this.state.isStuck === true) {
        this.setState({isStuck: false});
    }
    else if (this.innerContainer.scrollTop >= 500 && this.state.isStuck !== true) {
        this.setState({isStuck: true});
    }
}

This will setState when scrolled 500px.

How can I replace the condition of 500px to be set when the user is with id="container" as the top of the window? Also replace isStuck state to isStuckBottom when the user reaches the bottom of the div.

The full code is

constructor(props) {
    super(props)
    this.state = {
      isStuck: false,
    }
    this.handleHeaderStuck = this.handleHeaderStuck.bind(this)
  }

  innerContainer = null

  componentDidMount () {
    this.innerContainer.addEventListener("scroll", this.handleHeaderStuck);
  }

  componentWillUnmount () {
    this.innerContainer.removeEventListener("scroll", this.handleHeaderStuck);    
  }

  handleHeaderStuck = () => {
     if (this.innerContainer.scrollTop <= 500 && this.state.isStuck === true) {
        this.setState({isStuck: false});
     }
     else if (this.innerContainer.scrollTop >= 500 && this.state.isStuck !== true) {
        this.setState({isStuck: true});
     }
  }
Darren
  • 2,176
  • 9
  • 42
  • 98
  • https://github.com/joshwnj/react-visibility-sensor – Max Baldwin Apr 24 '18 at 20:21
  • Thanks @MaxBaldwin. I'll check it out. – Darren Apr 24 '18 at 20:22
  • [javascript - Position of Div in relation to the Top of the Viewport](https://stackoverflow.com/questions/1960082/position-of-div-in-relation-to-the-top-of-the-viewport) – Andreas Apr 24 '18 at 20:24
  • @Andreas comment is valid. I was going to mention `getBoundingClientRect`, but someone has already solved this problem in React. Why solve it yourself? – Max Baldwin Apr 24 '18 at 20:25
  • @MaxBaldwin. The problem I have found with `react-visibility-sensor` is that there is no option to make the sensor react upon the div reaching `0px` in the window. Did you know a way this can be achieved using this solution? – Darren Apr 24 '18 at 22:20
  • Look at the example in the docs I sent. You wrap your component in the visibility sensor and then you pass the visibility sensor a function it its prop `onChange`. That function receives `isVisible` as a parameter. If by 0px you mean entering the viewport, then that would be when isVisible goes from false to true. If you need an example let me know and i will write an answer when I get home – Max Baldwin Apr 24 '18 at 22:25
  • Thank you for your reply @MaxBaldwin. Yes, got that part working without issue. Struggling to find a way to sense when the top of the div container is top 0px. – Darren Apr 24 '18 at 23:36
  • @Darren, see if this helps? https://jsfiddle.net/tarunlalwani/xmfxpmf5/ – Tarun Lalwani Apr 29 '18 at 06:30
  • @Darren "top of the div container is top 0px." What do you mean by that? At `scrollTop` 0? – Max Baldwin Apr 30 '18 at 15:27
  • As the top of the `div` reaches the top of the viewport. – Darren Apr 30 '18 at 15:41

2 Answers2

3

  var atTop = false;
    var atBotton = false;
    document.addEventListener("scroll", e => {

      var elemInfo = document.getElementById("container").getClientRects()[0];
      if (parseInt(elemInfo.bottom) >= window.innerHeight) 
      {
       if (!atBottom){
          console.log("I touche the bottom")
          document.getElementById("information").innerHTML = "mouse  reached the bottom";
          atBottom = true;
        }
        atTop = false;
      } else if (parseInt(elemInfo.top) <= 0) {
        if (!atTop) {
          console.log("Mouse at top")
          document.getElementById("information").innerHTML = "I touched the top";
          atTop = true;
        }
        atBottom = false;
      } else {
          console.log("I touched the nothing")
      }
    });
body {
      margin: 0px;
      padding: 0px;
      border: 0px;
    }

    .first, .bottom {
      width: 100%;
      height: 200px;
      background-color: Green;
    }

    #container {
      width: 100%;
      background-color: Yellow;
      margin: 0px;
      padding: 0px;
      border: 1 px solid black;
      height: 200px;
    }

    #infomation {
      font-size: 50px;
    }
    <div class="example">

    </div>
    <div id=container>
    <div id=information></div></div>
    <div class="bottom">

    </div>
LShapz
  • 1,738
  • 11
  • 19
MK Vimalan
  • 1,213
  • 14
  • 28
2

You add an "scroll" onto document and check if the div is currently at 0 relative to the current viewport. To get the position relative to the current view of the user you can use getBoundingClientRect(). You can implement it in this way:

document.addEventListener("scroll", () => {
  div = document.querySelector("#container")
  if(div.getBoundingClientRect().top == 0) {
    //Do what you need to do here, this executes whenever the
    //top of the container is at the top of the screen.
  }
})
Caveman
  • 2,527
  • 1
  • 17
  • 18