Reputation: 23
How to write the code (below) that unlimited (#stickyContainer) number of elements also to work the code? Now, one element working.
function $(id) {
return document.getElementById(id);
}
function sticky() {
var stickyBoxHeight = $('stickyBox').offsetHeight;
var stickyTop = $('stickyBox').getBoundingClientRect();
var stickyBoxTop = stickyTop.top;
var stickyBoxBottom = stickyBoxTop + stickyBoxHeight;
var stickyHeight = $('sticky').offsetHeight;
if (stickyBoxTop <= 0) {
$('sticky').className = 'fixed';
} else if (stickyBoxBottom >= stickyBoxHeight) {
$('sticky').className = '';
}
if (stickyBoxBottom <= stickyHeight) {
$('sticky').className = 'fixedBottom';
}
}
window.onscroll = function () {
sticky();
}
Upvotes: 2
Views: 9179
Reputation: 9055
So first thing before I get into the javascript and html code is If I were you I would look into css position:sticky and the sticky polyfill for broswers that don't support it. It will make your life a lot easier in this case because it will take care of the width of your containers and you just need to set the position to sticky and how far from the top of the window you want it to start sticking. In the future this will more than likely be a mainstay in web design. Another nice thing about this is that in mobile screens you can easily change your elements to stack instead of stick with just css and not lengthy javascript coding. You can read more about this here https://www.sitepoint.com/css-position-sticky-introduction-polyfills/. So with sticky you just need to set your css to the element like so.
.sticky-box{
position: -webkit-sticky;
position: sticky;
top: 0;
}
And then the polyfill for browsers that don't support css sticky can be downloaded here at https://github.com/wilddeer/stickyfill And you just include the path to the polyfill and initiate with javascript like so:
<script src="path/to/stickyfill.min.js"></script>
var stickyElements = document.getElementsByClassName('sticky-box');
for (var i = stickyElements.length - 1; i >= 0; i--) {
Stickyfill.add(stickyElements[i]);
}
I have made a demo of this in action. Note: I had to rewrite the html and css because I had trouble making sense of your code in the fiddle you have, also like stated in the comments you should only have one of a certain id on each page. Id's are supposed to be unique to one element per page. So you will want to use classes instead.
Here is the Css position sticky demo Fiddle Demo
Now all that being said we will get on to the javascript way and how to write the code for this. First like I said you will want to use class names instead of id's because you will have multiple of them. So for the markup you will want a sticky container and then inside of that a sticky box. Then container you will position as relative and then the sticky box we will position accordinly when classes are added. Now what we are going to do is run a for loop in javascript for each of the sticky containers and add the class to them because that will be the easiest. So everytime one of the sticky-containers reaches the top we will add the class fixed to the container and not the sticky-box itself. Then in your css you can use this parent to add positions to the sticky box like so:
<div class="sticky-container">
<div class="sticky-box">
Sticky Box
</div>
</div>
.fixed .sticky-box{
position:fixed;
top:0;
right:0;
}
.fixedBottom .sticky-box{
position:absolute;
top:auto;
bottom:0;
}
The only thing that should be in the sticky container is the sticky box so take the info div and place it outside of the sticky container. Then you need to create a javascript function to add a width to the box because when it is fixed it will need to have the same width as the container it was in. For the following example since you have stated heights to the sticky-box and the sticky-container I just used numbers instead of calculating container heights to add the fixedBottom class but if your boxes and containers are going to be dynamic heights you will have to write out a little bit of code calculating when the fixedBottom class should be added. Anyway I know this was a long answer but there was a lot to explain about the code so here is what I used for my example. Take a look at it and see how it works.
Here is a fiddle demo of this in action Fiddle Demo
And the new javascript code
var stickyContainers = document.getElementsByClassName("sticky-container");
function sticky(){
for(var i = 0; i < stickyContainers.length; i++){
var stickyContainer = stickyContainers[i];
if (window.pageYOffset >= stickyContainer.offsetTop){
stickyContainer.classList.add("fixed");
}else{
stickyContainer.classList.remove("fixed");
}
if (window.pageYOffset >= stickyContainer.offsetTop + 350){
stickyContainer.classList.add("fixedBottom");
}else{
stickyContainer.classList.remove("fixedBottom");
}
}
}
window.onscroll = function() {
sticky();
}
Upvotes: 5