Sticky footer after complete scroll - html

I am trying to create a "see-also" button that is located on the bottom of the page.
When the user reaches the bottom and decides to scroll back up, I want it to stick to the bottom of the viewport.
I have been trying with position:sticky but then it is already sticked to the bottom of the viewport when the page just loaded. I only want this after a complete scroll down.
Any clues?
Thanks in advance.

This is an example with javascript (see result sticky button on scroll top
const DIRECTION_BOTTOM = 1;
const DIRECTION_TOP = 0;
let previousScroll = 0;
let direction = scrollY === 0 ? DIRECTION_BOTTOM : DIRECTION_TOP;
window.addEventListener('scroll', function(){
const scrollY = window.scrollY;
if(direction === DIRECTION_TOP && previousScroll < scrollY){
direction = DIRECTION_BOTTOM;
// remove sticky
document.getElementById("sticky").classList.remove("show");
}
else if(direction === DIRECTION_BOTTOM && previousScroll > scrollY ){
direction = DIRECTION_TOP;
// Add sticky
document.getElementById("sticky").classList.add("show");
}
previousScroll = scrollY;
})

You can create this functionality with JQuery by creating a function which calculates when an element is in the viewport. If the button enters the viewport, add a class which makes the element position: sticky. There are different ways to approach this problem but one solution is something like this:
$.fn.isInViewport = function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
$(window).on("scroll", function() {
if($('#button').isInViewport()) {
$('#button').addClass('sticky');
}
});
body {
text-align: center;
}
.button {
padding: 6px 12px;
}
.div {
width: 100%;
height: 250px;
color: #fff;
}
.div1 {
background: blue;
}
.div2 {
background: red;
}
.div3 {
background: purple;
}
.sticky {
position: sticky;
position: -webkit-sticky;
position: -moz-sticky;
position: -ms-sticky;
position: -o-sticky;
height: 100%;
bottom: 5px;
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<div class="div div1">Filler div 1</div>
<div class="div div2">Filler div 2</div>
<div class="div div3">Filler div 3</div>
<button type="button" class="button" id="button">See Also</button>

Scrambled everything together and this is working now:
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
document.getElementById("see-also").classList.add("sticky");
}
};
Thanks you everyone

Related

Display a Search bar on header on scroll HTML/CSS

I have a search bar which would like to display onto the header on scroll, a great example is like the one on this site: https://www.indiamart.com/
Approach 1 - A simple way to do this would be to detect a scroll & add and remove a class that contains display: none;
You can have an event listener -
window.addEventListener('scroll', function() {
if( window.scrollY !== 0) {
document.getElementById('searchBar').classList.add('scrolled');
} else {
document.getElementById('searchBar').classList.remove('scrolled');
}
});
With the CSS -
.noScroll
{
background: yellow;
position:fixed;
height: 50px; /*Whatever you want*/
width: 100%; /*Whatever you want*/
top:0;
left:0;
display:none;
}
/*Use this class when you want your content to be shown after some scroll*/
.scrolled
{
display: block !important;
}
.parent {
/* something to ensure that the parent container is scrollable */
height: 200vh;
}
And the html would be -
<div class="parent">
<div class ='noScroll' id='searchBar'>Content you want to show on scroll</div>
</div>
Here's a JSFiddle of the same - https://jsfiddle.net/kecnrh3g/
Approach 2 -
Another simple approach would be
<script>
let prevScrollpos = window.pageYOffset;
window.onscroll = function() {
let currentScrollPos = window.pageYOffset;
if (prevScrollpos > currentScrollPos) {
document.getElementById('searchBar').style.top = '-50px';
} else {
document.getElementById('searchBar').style.top = '0';
}
prevScrollpos = currentScrollPos;
}
</script>
with the html -
<div class="parent">
<div id ='searchBar'>Content you want to show on scroll</div>
</div>
and css
#searchBar {
background: yellow;
position: fixed;
top: 0;
left: 0;
height: 50px;
width: 100%;
display: block;
transition: top 0.3s;
}
.parent {
height: 200vh;
}
Here's a JSFiddle of the same - https://jsfiddle.net/0tkedcns/1/
From the same example, the idea is only to show/hide once user scroll the page using inline css display property, you can do the same or at least provide a code sample so we can help you!
HTML
<div class="search-bar">
<div class="sticky-search">
Sticky Search: <input type="text" value="search" />
</div>
</div>
CSS
.sticky-search {
display:none;
position:fixed;
top:0px;
left:0px;
right:0px;
background:blue;
padding:10px;
}
JS
var searchHeight = $(".search-bar").outerHeight();
var offset = $(".search-bar").offset().top;
var totalHeight = searchHeight + offset;
console.log(totalHeight);
$(window).scroll(function(){
if($(document).scrollTop() >= totalHeight) {
$('.sticky-search').show();
} else {
$('.sticky-search').hide();
}
});

Remove class at top of page isn't always working

I've got a header that I want to disappear (move above the top of the browser screen) when the user scrolls down, then when the user scrolls back up I want the header to reappear (move back down) and also to gain a solid white background behind it.
All of this is working fine, but then I want the white background to be removed if the user scrolls back up to the very top of the page again (so it's just the header visible but with no white background).
I've cobbled together the code for this, and it's pretty much working - but, for some reason, in certain circumstances, the white background isn't being removed?!
It seems to be if you've scrolled back up enough to make the header reappear with the white background, but not all the way top the top, and then scroll the rest of the way then the white background doesn't disappear for some reason.
Sorry, I've probably not explained that very well, but here's my code. If someone is able to replicate the bug I'm getting and offer an explanation I'd be very grateful!
Thanks
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 30;
var navbarHeight = $('header').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 30);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('header').removeClass('header-down').addClass('header-up').removeClass('header-solid');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('header').removeClass('header-up').addClass('header-down').addClass('header-solid');
}
}
lastScrollTop = st;
};
$(function () {
$(window).scroll(function () {
var top_offset = $(window).scrollTop();
if (top_offset == 0) {
$('header').removeClass('header-solid');
}
})
});
body {
margin: 0;
background: url('https://images.unsplash.com/3/doctype-hi-res.jpg?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=2246&q=80');
background-size: cover;
}
.wrapper {
width: 100%;
height: 3000px;
}
header {
display: flex;
width: 100%;
padding: 20px 50px;
position: fixed;
box-sizing: border-box;
transition: 300ms all ease-in-out;
margin-top: 0px;
}
.header-logo {
width: 200px;
}
.header-nav {
flex-grow: 1;
text-align: center;
}
.header-socials {
width: 200px;
text-align: right;
}
.header-up {
margin-top: -60px;
}
.header-down {
margin-top: 0px;
}
.header-solid {
background-color: #FFFFFF;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<header class="header-down">
<div class="header-logo">
<img src="#" class="img-header-logo"/>
</div>
<div class="header-nav">
One Two Three Four Five
</div>
<div class="header-socials">
Social Links
</div>
</header>
</div>

How to change data visible range to % percent

I am using this for my header that changes in a one page scroll up and down page. I noticed that it's not responsive so i am asking you if you maybe know a way to make that responsive. Like changing the 0-690 into a percentage so that it will work on mobile and also on a tv screen.
HTML
<div class="header header-1" data-visible-range="0-690">Portfolio</div>
<div class="header header-2" data-visible-range="691-2100">Services</div>
<div class="header header-3" data-visible-range="2101-">Contact</div>
CSS
.header-1 {
background-color:dimgray;
display: block;
}
.header-2 {
background-color:dimgray;
}
.header-3 {
background-color:dimgray;
}
.header {
position: fixed;
top: 0;
left: 0;
height:8vmax;
width: 100%;
display: none;
visibility:hidden;
transition: visibility .4s, opacity .4s ease-in-out;opacity:0;
font-size:4vmax;padding:1.58vmax;color:white;
}
What if, instead of basing it off pixels, you just checked to see if an element hit the top of the page, and then changed the header?
We'll call these elements "triggers." See my code below for an example of how they work.
let updateHeader = () => {
let scrollTop = $(window).scrollTop(),
triggerTitle = "Hi";
$('.trigger').each((i, el) => {
let topPos = $(el).offset().top,
distance = topPos - scrollTop;
if (distance < 0)
triggerTitle = $(el).data('title');
});
$('header h2').text(triggerTitle);
}
$(window).scroll(updateHeader);
$(window).on('touchmove', updateHeader);
body {
margin: 0;
}
#container {
height: 1000px;
}
header {
width: 100%;
position: fixed;
top: 0;
background-color: red;
}
p {
margin: 200px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<header><h2>Hi</h2></header>
<p class="trigger" data-title="section1">
trigger1
</p>
<p class="trigger" data-title="section2">
trigger2
</p>
<p class="trigger" data-title="section3">
trigger3
</p>
</div>
As you scroll down the page, each trigger hits the top of the page, and the text in the header will change to the the value of the latest trigger's data-title. You could position these triggers appropriately above each of your website's sections, so that, no matter what size the screen, the header should update at the right time. Here's a codepen.
EDIT
Try this JS instead for maximum compatibility (no es6 involved).
function updateHeader() {
var scrollTop = $(window).scrollTop(),
triggerTitle = "Hi";
$('.trigger').each(function(i, el) {
var topPos = $(el).offset().top,
distance = topPos - scrollTop;
if (distance < 0)
triggerTitle = $(el).data('title');
});
$('header h2').text(triggerTitle);
}
$(window).scroll(updateHeader);
$(window).on('touchmove', updateHeader);

stop scrolling inside fixed div

I have 2 divs (one is fixed, the other one is relative)
I was implementing a scrolling behavior inside the fixed one ... scrolling along with the page. What i want to do more is when the div inside fixed one is scrolled to the bottom this should stop scrolling, only the page should continue scroll.
I do not know if i was very clear so that's why i create a fiddle.
<style>
body {
background-color:#dddddd;
margin: 0;
}
#mainDiv{
top: 120px;
max-width: 1024px;
margin:0px auto;
background-color:#fff;
}
#leftDiv{
width: 30%;
float: left;
background-color: #DBEAED;
height: 300px;
top: 1em;
z-index: 999;
position: fixed;
overflow: hidden;
}
#rightDiv{
width: 68%;
padding-left: 2%;
float: right;
background-color: #FBE9DD;
}
#filters{
display: inline-block;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
window.onscroll = scrollFunction;
function scrollFunction() {
var doc = document.documentElement, body = document.body;
var top = (doc && doc.scrollTop || body && body.scrollTop || 0);;
$('#filters').css("margin-top", -top);
}
});
</script>
<div id="mainDiv">
<div id="leftDiv">
<div id="filters">
<p>XX 1</p><p>XX 2</p><p>XX 3</p><p>XX 4</p><p>XX 5</p><p>XX 6</p><p>XX 7</p><p>XX 8</p><p>XX 9</p><p>XX 10</p><p>XX 11</p><p>XX 12</p>
</div>
</div>
<div id="rightDiv">
Here is PLP page
<p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p>
<p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p>
<p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p>
</div>
</div>
Any help is more than welcome. Thanks !!!
ps. X12 should stick to the end of blue area.
If I undersand correctly, make it so that top has a maximum value of $('#filters').height()-$('#leftDiv').height(), which is as far as you want filters to scroll. Further, to make it be able to change directions gracefully, rather than set the margin of #filters equal to scroll top, we have to instead increment and decrement the value as we scroll
$(document).ready(function () {
window.onscroll = scrollFunction;
var filterMargin = 0;
maxTop = $('#filters').height() - $('#leftDiv').height();
lastTop = 0;
function scrollFunction() {
var doc = document.documentElement, body = document.body;
var top = (doc && doc.scrollTop || body && body.scrollTop || 0);
filterMargin = -parseInt($('#filters').css("margin-top"));
var diff = top - lastTop;
filterMargin += diff;
//make sure the margin value stops when the scrolling stops,
//otherwise the scrolling physically stops but the value keeps growing
filterMargin = filterMargin < 0 ? 0 : filterMargin;
filterMargin = filterMargin > maxTop ? maxTop : filterMargin;
console.log(top, maxTop, filterMargin, top - lastTop);
$('#filters').css("margin-top", -filterMargin + 'px');
lastTop = top;
}
});
Fiddle:
http://jsfiddle.net/nfp6fhg6/5/

HTML -- How can I make my navbar stick after scrolling to a certain point on page?

How can I make my navbar stick after scrolling to a certain point on page? I don't want it to stick immediately after scrolling past it, but rather once I reach another div on the page.
Try this:
window.onscroll = function() {
var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
if (scrollTop >= document.getElementById("d").offsetTop) {
document.getElementById("nav").style.position = "fixed";
document.getElementById("d").style.marginTop = "50px";
document.getElementById("nav").style.marginTop = "-50px";
} else {
document.getElementById("nav").style.position = "static";
document.getElementById("d").style.marginTop = "0px";
document.getElementById("nav").style.marginTop = "0px";
}
}
nav {
width: 100%;
height: 50px;
background: red;
z-index: 100;
}
body {
margin: 0;
min-height: 1000px
}
#d {
position: relative;
top: 100px;
width: 100%;
height: 50px;
background: yellow;
}
<body>
<nav id="nav"></nav>
<div id="d"></div>
</body>
When you scroll to the yellow div, the red navbar sticks to the top of the viewport and stays there until you scroll up