Search code examples
javascripthtmlcssstickysticky-footer

How to change the properties of a sticky up arrow button based on its position?


I have a sticky up arrow image for my webpage as follows:

HTML:

<a href = "#navbar-scroll"><img src = "images/sticky-btn-light.png" id = "myBtn" alt = "sticky-up-button"></a>

And CSS:

#myBtn {
    visibility: hidden;
    position: fixed;
    bottom: 50px; 
    right: 30px; 
    z-index: 99; 
    cursor: pointer;
    padding: 15px; 
    border-radius: 10px;
    width: 5%;
    opacity: 0.5 ;
}

The button disappears when the user scrolls down and appears when the user scrolls up based on this JS code.

window.onscroll = function(e) {
    console.log(this.oldScroll > this.scrollY);
    if((this.scrollY == 0) || (this.oldScroll < this.scrollY)  ){
        document.getElementById('myBtn').style.visibility = 'hidden';
    }
    else if(this.oldScroll > this.scrollY){
        document.getElementById('myBtn').style.visibility = 'visible';
    }
    this.oldScroll = this.scrollY;
}

Now, I want to change the color of the button based on its changing position on the screen. As I scroll the page, the sticky button will be in different sections as below.Web page layout1 If the sticky button is in Section A, it should be red. And if it is in Section B, it should be blue.Web page layout2 Please note that it's the page that is moving, not the button. The button is in a fixed position.

For this, I need the id of the section in which the sticky button is overlapping at any given moment. Is there any way to get that information through JavaScript?

PS: I have adjusted the details to make things more clear. It's the page that is moving. So, if I use Element.getBoundingClientRect() for #myBtn, will I not get the same top/y values for that element wherever I scroll on the page?


Solution

  • You can use element.getBoundingClientRect() to get the x,y of the top left corner and the x,y of the bottom right corner of a element.

    var arrow     = document.getElementById('myBtn');
    var arrowRect = arrow.getBoundingClientRect();
    console.log(arrowRect.top, arrowRect.right, arrowRect.bottom, arrowRect.left);
    
    var section     = document.getElementById('section1');
    var sectionRect = section.getBoundingClientRect();
    console.log(sectionRect.top, sectionRect.right, sectionRect.bottom, sectionRect.left);
    

    Then you can check collisions with the arrow and the section. In your case the x-axis doesn't matter:

    // This checks if the arrow is touching the section
    ( arrowRect.bottom > sectionRect.top && arrowRect.top < sectionRect.bottom  )
    
    // This checks if the arrow isn't touching the section, then inverts it (faster)
    !( arrowRect.bottom < sectionRect.top || arrowRect.top > sectionRect.bottom )