Make sticky/fixed element stop at footer - javascript

I'm trying to make the side bar stop following the user's scroll once it hits the footer. Right now I set the z-index to -2 so that it goes behind the footer, but it sticks out a tiny bit.
JavaScript
$(document).ready(function () {
var floatingDiv = $('#side_bar');
var floatingDivPosition = floatingDiv.position();
$(window).scroll(function (){
var scrollBarPosition = $(window).scrollTop();
if(scrollBarPosition >= floatingDivPosition.top) {
floatingDiv.css({
'position': 'fixed',
'top': 55,
'width': '18.6676%',
'z-index': -2
});
}
else{
floatingDiv.css({
'position': 'relative',
'top': 0,
'width': '79.4392%'
});
}
});
});
HTML
<div id="content">
<div id="col_1">
<div id="side_bar">
<h4 id="cater_to">We cater to</h4>
<button class="side_bar_btns">Contractor</button>
<button class="side_bar_btns">Wood/Sport Floors</button>
<button class="side_bar_btns">Grocery/Commercial</button>
<button class="side_bar_btns">Education</button>
<h4 id="simplicity">Simplicity</h4>
<div id="all_systems_side_bar">
<img src="images/all_systems_logo.png" alt="All Systems Maintenance logo. Links to more about All Systems Maintenance." width="100%">
</div><!-- all systems side bar -->
</div><!-- side_bar -->
</div><!-- col_1 -->
<div id="col_2">
//// bunch of stuff here
</div><!-- col_2 -->
<div class="clear"></div>
</div><!-- content -->
<footer>
/// bunch of stuff here
</footer>
CSS
#col_1 {
float:left;
margin-top:44px;
width:23.4994%;
margin-left:3.9531%;
}
#side_bar {
background:#003768;
min-height:665px;
width:79.4392%;
border-radius:20px;
box-shadow: 10px 10px 5px #888;
}
#col_2 {
float:right;
margin-top:44px;
width:68.5944%;
margin-right:3.9531%;
}
footer {
background-image:url(../images/foot_background.gif);
background-repeat:no-repeat;
background-size:cover;
}
The footer background is almost the same height as the screen (about 824px when I inspect it with Chrome).

Found this gem on Youtube at https://www.youtube.com/watch?v=5s0L6dCVevk and changed it slightly to come up with the following, which works.
$(function() {
if ($('#side_bar').length) {
var el = $('#side_bar');
var stickyTop = $('#side_bar').offset().top;
var stickyHeight = $('#side_bar').height();
$(window).scroll(function(){
var limit = $('footer').offset().top - stickyHeight - 20;
var windowTop = $(window).scrollTop();
if (stickyTop < windowTop) {
el.css({
position: 'fixed',
top: 55,
width: '18.6676%'
});
} else {
el.css({
position: 'static',
width: '79.4392%'
});
}
if (limit < windowTop) {
var diff = limit - windowTop;
el.css({
top: diff
});
}
});
}
});

Related

How to detect correct div data attribute when each hitting the top of the page

I am working on the below code. Why am I not able to detect which div is reaching at the top of page in both down or up scroll?
$(window).scroll(function() {
$(".container").each(function() {
var $that = $(this);
var po = $(this).offset().top;
if (po >= 0 && po <= 300) {
console.log($that.data('map'));
}
});
});
.container {
height: 690px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container" data-map="One">One</div>
<div class="container" data-map="Two">Tow</div>
<div class="container" data-map="Three">Three</div>
<div class="container" data-map="Four">Four</div>
<div class="container" data-map="Five">Five</div>
You'll need to use $(window).scrollTop(); as well as $that.outerHeight()
$(window).scroll(function() {
var windowScrollTop = $(this).scrollTop(); // window scroll top
$(".container").each(function() {
var $that = $(this);
var po = $that.offset().top;
var poHeight = $that.outerHeight(true); // the height of the element
var distanceTop = 100; // the distance from top to run the action .. it can be 0 if you want to run the action when the element hit the 0 top
if (windowScrollTop + distanceTop >= po && windowScrollTop + distanceTop <= po + poHeight) {
if(!$that.hasClass('red')){ // if element dosen't has class red
console.log($that.data('map'));
$(".container").not($that).removeClass('red'); // remove red class from all
$that.addClass('red'); // add red class to $that
}
}
});
}).scroll(); // run the scroll onload
.container {
height: 690px;
}
.container.red{
background : red;
color : #fff;
font-size: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container" data-map="One">One</div>
<div class="container" data-map="Two">Two</div>
<div class="container" data-map="Three">Three</div>
<div class="container" data-map="Four">Four</div>
<div class="container" data-map="Five">Five</div>

jQuery - element crossing another element

I have a fixed div on the page which contains a logo and as the user scrolls and this logo passes over other divs I wnat to the change the colour of the logo.
I have this working over a single div but need to it work across multiple so any help appreciated.
The WIP site can be seen here... dd.mintfresh.co.uk - if you scroll down you'll (hopefully) see the logo change from black to white as it crosses an illustrated egg. I need the same to happen when it crosses other divs further down the page.
The script so far...
jQuery(window).scroll(function(){
var fixed = jQuery("logo");
var fixed_position = jQuery("#logo").offset().top;
var fixed_height = jQuery("#logo").height();
var toCross_position = jQuery("#egg").offset().top;
var toCross_height = jQuery("#egg").height();
if (fixed_position + fixed_height < toCross_position) {
jQuery("#logo img").css({filter : "invert(100%)"});
} else if (fixed_position > toCross_position + toCross_height) {
jQuery("#logo img").css({filter : "invert(100%)"});
} else {
jQuery("#logo img").css({filter : "invert(0%)"});
}
}
);
Any help appreciated. Thanks!
you need to fire a div scroll event. you can assign
$("div1").scroll(function(){
//change the color of the div1
}
});
$("div2").scroll(function(){
//change the color of the div2
}
});
or you can assign a class to divs which you want to change the color
$(".div").scroll(function(){
//change the color of the div which you are scrolling now
}
});
You can use like this :-
$(window).scroll(function() {
var that = $(this);
$('.section').each(function() {
var s = $(this);
if (that.scrollTop() >= s.position().top) {
if(s.hasClass('active')) {
$('.logo').addClass('invert');
} else {
$('.logo').removeClass('invert');
}
}
});
});
body {
padding: 0;
margin: 0;
}
div {
background: #f00;
height: 400px;
}
.logo {
position: fixed;
top: 0;
left: 0;
width: 100px;
}
.logo.invert {
filter: invert(100%);
}
div:nth-child(even) {
background: #ff0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://dd.mintfresh.co.uk/wp-content/uploads/2018/06/DD_logo.svg" class="logo" />
<div id="page1" class="section"></div>
<div id="page2" class="section active"></div>
<div id="page3" class="section"></div>
<div id="page4" class="section active"></div>
<div id="page5" class="section"></div>
As your site code you can do like this :
$(window).scroll(function() {
var that = $(this);
$('#content > section').each(function() {
var s = $(this);
if (that.scrollTop() >= s.position().top) {
if(s.hasClass('black')) {
$('#logo img').css({filter: 'invert(0%)'});
} else {
$('#logo img').css({filter: 'invert(100%)'});
}
}
});
});

Flexslider fullscreen is not centered in mobile

I have this fullscreen background that I'm using and it works correctly on my laptop and big screens. The problem is when I enter the website from a mobile device. The background image (and the buttons above it) move to the side. I do not know why is this. I think it has to be with the bootstrap.min.
The HTML:
<!-- Intro Section -->
<section id="intro">
<!-- Hero Slider Section -->
<div class="flexslider fullscreen-carousel hero-slider-1 ">
<ul class="slides">
<!--Slide-->
<li data-slide="dark-slide">
<div class="slide-bg-image overlay-light dark-bg parallax" data-background-img="images/connexion_background.jpg">
<div class="js-Slide-fullscreen-height container">
<div class="intro-content">
<div class="intro-content-inner">
<br />
<div><a class="btn btn-md btn-white" href="contact.php">Request a Quote</a><span class="btn-space-10"></span><a class="btn btn-md btn-white " href="research-solutions.html">View Our Solutions</a></div>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
<!-- End Hero Slider Section -->
</section>
<div class="clearfix"></div>
<!-- End Intro Section -->
The JS:
var pageSection = $('.slide-bg-image, .bg-image');
pageSection.each(function (indx) {
if ($(this).attr("data-background-img")) {
$(this).css("background-image", "url(" + $(this).data("background-img") + ")");
}
});
function fullScreenSlider() {
if ($('.fullscreen-carousel').length > 0) {
$('.fullscreen-carousel').flexslider({
animation: "slide",
// startAt: 0,
animationSpeed: 700,
animationLoop: true,
slideshow: true,
easing: "swing",
controlNav: false,
before: function (slider) {
//Slide Caption Animate
$('.fullscreen-carousel .intro-content-inner').fadeOut().animate({ top: '80px' }, { queue: false, easing: 'easeOutQuad', duration: 700 });
slider.slides.eq(slider.currentSlide).delay(400);
slider.slides.eq(slider.animatingTo).delay(400);
},
after: function (slider) {
//Slide Caption Animate
$('.fullscreen-carousel .flex-active-slide').find('.intro-content-inner').fadeIn(2000).animate({ top: '0' }, { queue: false, easing: 'easeOutQuad', duration: 1200 });
// Header Dark Light
headerDarkLight_with_flexslider();
},
start: function (slider) {
$('body').removeClass('loading');
// Header Dark Light
headerDarkLight_with_flexslider();
},
useCSS: true,
});
};
// Header Dark Light
function headerDarkLight_with_flexslider() {
var color = $('.fullscreen-carousel').find('li.flex-active-slide').attr('data-slide');
if (color == 'dark-slide') {
$('#header').addClass('header').removeClass('header-light');
$('#header').removeClass('header-default');
}
if (color == 'light-slide') {
$('#header').addClass('header-light').removeClass('header-dark');
$('#header').removeClass('header-default');
}
if (color == 'default-slide') {
$('#header').removeClass('header-dark');
$('#header').removeClass('header-light');
$('#header').addClass('header');
}
};
// "fullscreen-carousel" height
fullScreenCarousel();
function fullScreenCarousel() {
var windowWidth = $(window).width();
var windowHeight = $(window).height();
if ($(window).width() > 767) {
$('.hero-slider-1 .slides .js-Slide-fullscreen-height').css("height", windowHeight);
}
else {
$('.hero-slider-1 .slides .js-Slide-fullscreen-height').css("height", '400px');
}
};
$(window).resize(function () {
fullScreenCarousel();
});
};
This is the result in mobile:
The buttons and the background image are moved to the right. They are not centered and the background picture repeat itself.
I can see this on the development tool of Mozilla:
Any help would be appreciated.
Thank you.
center the images in your slides add this in your css
.flexslider img { margin: 0 auto; }
OR
.flexslider .slides > li{
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
can you try to add following css at last of the css document
.flexslider ul.slides {
padding: 0 !important;
}
Your flex slider left position is not right , You can simply fix this with left property, try with the below code
.fullscreen-carousel .slides li {
height: 100%;
left: -40px; /* newly added */
overflow: hidden;
position: relative;
}
can you try this also , remove the left:-40px and add this jquery to the page
$(window).load(function() {
$('.flexslider').flexslider();
$(window).trigger('resize');
});

How to set js function scroll let it don't exceed parent‘s bottom?

The html, js, css example is https://jsfiddle.net/t9mfmaa3/5/.
/* Latest compiled and minified JavaScript included as External Resource */
$(function() {
var $sidebar = $("#e"),
$window = $(window),
$offset = $sidebar.offset(),
$topPadding = 15;
$window.scroll(function() {
if ($window.scrollTop() > $offset.top) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - $offset.top + $topPadding
});
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
});
/* Latest compiled and minified CSS included as External Resource*/
/* Optional theme */
#import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
body {
margin: 10px;
}
#c {
background-color: red;
height: 2400px
}
#e {
background-color: lightblue;
height: 600px
}
#b {
height: 2400px;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div class="a">
<div id="b" class="column col-xs-3 col-sm-3">
<div id="e" class="">
blue
</div>
</div>
<div id="c" class="center_column col-xs-9 col-sm-9">
red
</div>
</div>
</div>
</div>
I tried to make blue block not exceed yellow block which means the blue one always in yellow block. My idea is to set code to detect block yellow and block blue. But I didn't success. Anybody has any suggestion? Thanks
If you are already using bootstrap, you may as well use their affix javascript.
getbootstrap.com
Here is an example:
jsfiddle.net
$(function() {
var $sidebar = $("#e"),
$body = $('body'),
$parent = $('#b'),
topPadding = 15,
offset=$sidebar.offset();
$sidebar.affix({
offset: {
top: function() {
return $parent.offset().top - topPadding;
},
bottom: function() {
return $(document.body).height() - ($parent.offset().top + $parent.outerHeight());
}
}
});
});
You might notice it act a little weird and jumpy near the end, but that should go away when using it on a real site (instead of inside an iframe)

JS counter when scroll to a div stop counting

I want to make a counter on javascript that when you go to certain div, start counting and when you reach the specified number it stops, and if I continue scrolling, the counter no longer keep counting
I have made a Pen with the idea, but when I continue scrolling the counter do not stop, and start to count down, and then stop when reach a low number.
Any idea to make this work?
Thanks in advance.
HTML
<!-- Counter section -->
<div id="counter" class="Wrapper-counter">
<!-- Counter_item -->
<div class="Counter_item">
<h3 class="Counter_h3 right">
<span class="count">
123
</span>
</h3>
<p class="Counter_paragraph right">
<strong>Lorem ipsum</strong>
</p>
</div>
<!-- /Counter_item -->
<!-- Counter_item -->
<div class="Counter_item">
<h3 class="Counter_h3 left">
<span class="count">
123
</span>
</h3>
<p class="Counter_paragraph left">
<strong>Lorem ipsum</strong>
</p>
</div>
<!-- /Counter_item -->
</div>
<!-- /Counter section -->
JS
$(window).on('scroll', function() {
var div_counter = window.pageYOffset;
var scroll_pos_test = $('#counter').offset().top - window.innerHeight; // set to whatever you want it to be
if(div_counter < scroll_pos_test) {
//do stuff
$('.count').each(function () {
$(this).prop('Counter',0).animate({
Counter: $(this).text()
}, {
duration: 3000,
easing: 'swing',
step: function (now) {
$(this).text(Math.ceil(now));
}
});
});
}
});
codepen here
I didn't understand your code, but I created an example of what you are looking for which might give you a new perspective of how to tackle this problem in an easier way. Check out the working example on CODEPEN.
HTML
<div class="container">
<p data-counter="100">100</p>
</div>
CSS
p {
font-size: 3em;
position: fixed;
color: blue;
}
.container {
position: relative;
height: 700px;
background: #ccc;
}
JS
$(document).ready(function() {
var topCount = 100;
var maxCount = 50;
var startCount = 200;
var endCount = 400;
var currCount = 0;
$(window).scroll(function() {
if (($(window).scrollTop() >= startCount) && ($(window).scrollTop() <= endCount)) {
currCount = Math.floor(maxCount + (maxCount - topCount) * ($(window).scrollTop() - endCount) / (endCount - startCount));
$("p").attr("data-counter",currCount).text(currCount);
}
});
});
It should be pretty straight-forward. I don't have a resetting mechanism since I don't know how you want to do it or if you want to have it at all. but it is easy to add any modification
thanks for the code but it is not what I was looking; I solved the problem by adding the plugin INVIEW JQUERY and the following script, thanks anyway
CODEPEN DEMO
$('#counter').bind('inview', function(event, visible, visiblePartX, visiblePartY) {
if (visible) {
$(this).find('.count').each(function () {
var $this = $(this);
$({ Counter: 0 }).animate({ Counter: $this.text() }, {
duration: 2000,
easing: 'swing',
step: function () {
$this.text(Math.ceil(this.Counter));
}
});
});
$(this).unbind('inview');
}
});

Categories

Resources