简体   繁体   中英

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. 网页布局1 If the sticky button is in Section A, it should be red. And if it is in Section B, it should be blue. 网页布局2 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?

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 )

Here, I did an example for you to test and implement.

this will also help understand getBoundingClientRect even with fixed position

 var arrow= document.getElementById('myBtn'); window.onscroll = function(e) { var arrowBound = arrow.getBoundingClientRect(); var divs = document.querySelectorAll(".container > div"); divs.forEach(function(item){ var divBound = item.getBoundingClientRect(); var color= item.getAttribute("arrowColor"); if ( arrowBound.bottom > divBound.top && arrowBound.top < divBound.bottom ) { arrow.style.borderTopColor = color } }) }
 #myBtn { position: fixed; top: 10px; left:270px; z-index: 99; cursor: pointer; width: 0; height: 0; border-left: 20px solid transparent; border-right: 20px solid transparent; border-top: 20px solid #f00; } .container{ width:300px; height:800px; z-index: 81; } .container > div { width:300px; height:100px; border:1px solid black; }
 <div class="container"> <a id = "myBtn" href = "#navbar-scroll"></a> <div arrowColor="red"> box red </div> <div arrowColor="blue"> box blue </div> <div arrowColor="green"> box green </div> </div>

You can get coords of a html element with getBoundingClientRect() method, call this function and you'll get the Y coords of element (pixels), then you can use an if conditional

 function getCoords(elem) { let box = elem.getBoundingClientRect(); let body = document.body; let docEl = document.documentElement; let scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop; let clientTop = docEl.clientTop || body.clientTop || 0; return Math.round(box.top + scrollTop - clientTop); } if(getCoords(elem) > 100){ elem.className = 'your_class_name' }

 .your_class_name{ color: red; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM