I was wonder how one would make a sticky side nav stop scrolling or stop sticking and lock into place after a certain point. The project page in question is located here:
http://www.tcdiggity.com/new-diggity-menu-22/
As you can see, the little nav with the navs on the left of the menu 'sticks' to the actual page. But if you keep scrolling down, it continues to stick. I was wondering if there would be a way to have it only scroll with the main menu page? I think i have it setup in it most basic form right now using the Fixed CSS tag. Any suggestions would be great! Thanks!
This should do what you want. You will have to find a value where you want it hidden after.
$(window).scroll( function() {
var valueOfScroll = $(document).scrollTop().valueOf();
if(valueOfScroll <= ???)
$('#sticker').show();
else
$('#sticker').hide();
});
From testing values on your site, it seems this works good, so it disappears before the end of your main content:
$(window).scroll( function() {
var valueOfScroll = $(document).scrollTop().valueOf();
if(valueOfScroll <= 10500)
$('#sticker').show();
else
$('#sticker').hide();
});
This is better for a fade effect:
var top = true;
var bottom = false;
$(window).scroll( function() {
var valueOfScroll = $(document).scrollTop().valueOf();
if(valueOfScroll <= 10500)
{
if(!top)
{
bottom = false;
top = true;
$('#sticker').fadeToggle(1000);
}
}
else
{
if(!bottom)
{
top = false;
bottom = true;
$('#sticker').fadeToggle(1000);
}
}
});
Hope this helps!
Also just as a side note, in your CSS I recommend adding margin-top:50px so you side bar doesn't go above that paper background you have for the main content. :)
.side-tabs {
margin-left: -135px;
margin-top: 50px;
position: fixed;
z-index: 1 !important;
}
Per your question in the comments:
$(window).scroll( function() {
var valueOfScroll = $(document).scrollTop().valueOf();
if(valueOfScroll <= 10500)
$('#sticker').css({ 'margin-left': "-135px" });
else
$('#sticker').css({ 'margin-left': "20px" });
if(valueOfScroll <= 10800)
$('#sticker').show();
else
$('#sticker').hide();
})
I would say that is "cleaner" because you don't need the second if statement, but looks fine to me.
Related
I have a landing page with a full height and width div and a background image. I am floating a fixed div in front and fading it out as the user scrolls up. It's great unless someone refreshes the page when they're half way down, then the fixed div shows up again. How do I only show div if it's "above the fold"?
<script type="text/javascript">
jQuery(function( $ ){
$(window).on("scroll", function() {
var scrollPos = $(window).scrollTop();
if (scrollPos <= 0) {
$(".blue_bar").fadeIn();
} else {
$(".blue_bar").fadeOut();
}
});
});
</script>
.blue_bar {
width:75%;
max-width:900px;
padding: 40px 65px 40px 65px;
position:fixed;
bottom:95px;
right:55px;
background-color:rgba(0,105,170,0.8);
}
Thats because your code for fading out doesn't get executed if the page reloads.
So what you can do is enclose that logic inside a function and call it on page load as well as on scroll.
HTML
<div class="blue_bar" style="display:none;">
blah
</div>
JS
jQuery(function( $ ){
let processFade = function(){
var scrollPos = $(window).scrollTop();
if (scrollPos <= 0) {
$(".blue_bar").fadeIn();
} else {
$(".blue_bar").fadeOut();
}
};
$(window).on("scroll load", function () {
processFade();
});
$(document).ready(function () {
processFade();
});
});
Update: "The div shows up, then quickly disappears again."
The solution is pretty simple, Just start out with a hidden div :) Updated the code to reflect the same.
I am working on a bootstrap based website and I have the following case :
A main container and a floating left navigation menu.
The floating left navigation menu, is set to position fixed, because it is following the user scroll.
What I would like is when the end user resize the window, and when the main content meets the left menu (overlap), the left menu becomes hidden, and when there is enough space the left menu comes back.
Actually, it is not really working, it is blinking. I have written a little bit of jquery binded to the resize function.
Here is the jsfiddle :
https://jsfiddle.net/cuw46rsv/5/
function getDiffLeftMenu(div1, div2) {
var value = ($(div1).offset().left - $(div2).offset().left);
console.log(value - $(div2).width());
if(value - $(div2).width() < 0){
return true;
}
}
$(window).on('resize', function(event) {
var value = ($('.central-content').offset().left - $('#sectionsMenu').offset().left);
if(getDiffLeftMenu('.central-content','#sectionsMenu')){
$('#sectionsMenu').hide();
}
else {
$('#sectionsMenu').show();
}
}).resize();
Is this possible to not have this blinking effet ?
Thanks a lot for any help.
Regards.
Here's the solution with your logic, .hide() method causes it to have offset 0 and that's why it's blinking (it can get stuck as hidden all the time).
https://jsfiddle.net/cuw46rsv/7/
function getDiffLeftMenu(div1, div2) {
var value = ($(div1).offset().left - $(div2).offset().left);
console.log(value - $(div2).width());
if(value - $(div2).width() < 0){
return true;
}
}
By using opacity offset will stay there.
$(window).on('resize', function(event) {
var value = ($('.central-content').offset().left - $('#sectionsMenu').offset().left);
if(getDiffLeftMenu('.central-content','#sectionsMenu')){
$('#sectionsMenu').css('opacity', 0);
}
else {
$('#sectionsMenu').css('opacity', 1);
}
}).resize();
well you are doing it wrong, but you can solve it like this (as a workaround):
$(window).on('resize', function(event) {
var value = ($('.central-content').offset().left - $('#sectionsMenu').offset().left);
if(getDiffLeftMenu('.central-content','#sectionsMenu')){
setTimeout(function(){$('#sectionsMenu').hide();},20);
}
else {
$('#sectionsMenu').show();
}
}).resize();
https://jsfiddle.net/cuw46rsv/6/
Context
I am working on a one-page website where the fixed navigation's class changes as it scrolls through the different sections in order to match the section's background color. To achieve this effect, I used and modified the 2nd solution listed here.
Issue
While it works great most of the time, the navigation code breaks when I resize the browser (or leave the page and click back). More specifically, the navigation's background color changes too early or too late and no longer matches the section's background.
I'm guessing that this happens because the section's height are calculated on page load. Ideally, they would be recalculated on every scroll - but I am a novice and that's just a guess. Any help to solve this issue would be appreciated.
JavaScript
FYI: there are four sections in the websites (Hero, Work, About, Contact). Navigation's bg color should be transparent in Hero, white in Work and Contact, and teal in About.
var afterhero = $('#hero-section').offset().top + $('#hero-section').height();
var afterwork = afterhero + $('#work-section').height();
var afterabout = afterwebsites + $('#about-section').height();
$(window).on('scroll', function() {
stop = Math.round($(window).scrollTop());
if (stop > afterabout) {
$('header').removeClass('teal');
$('header').addClass('white');
} else if (stop > afterwork) {
$('header').addClass('teal');
} else if (stop > afterhero) {
$('header').removeClass('teal');
$('header').addClass('white');
} else {
$('header').removeClass('teal');
$('header').removeClass('white');
}
});
Just try adding all your size variables into your scroll event handler:
$(window).on('scroll', function() {
var afterhero = $('#hero-section').offset().top + $('#hero-section').height();
var afterwork = afterhero + $('#work-section').height();
var afterabout = afterwebsites + $('#about-section').height();
stop = Math.round($(window).scrollTop());
if (stop > afterabout) {
$('header').removeClass('teal');
$('header').addClass('white');
} else if (stop > afterwork) {
$('header').addClass('teal');
} else if (stop > afterhero) {
$('header').removeClass('teal');
$('header').addClass('white');
} else {
$('header').removeClass('teal');
$('header').removeClass('white');
}
});
Now afterhero, afterwork and afterabout should all be recalculated on a page scroll.
I am having trouble creating a dynamic sticky footer that only sticks to the bottom once it enters the page then reveals a hidden surprise when you continue to scroll.
I have created this method but it is not exactly as I had hoped: http://jsfiddle.net/R3n7s/
jQuery(window).load(function(){
jQuery(window).scroll(function() {
if(jQuery(window).scrollTop() + jQuery(window).height() > jQuery(document).height() - 200) {
jQuery('h2 a').fadeIn(400);
} else {
jQuery('h2 a').fadeOut(400);
}
});
});
This works okay but my goal is to have "This is the hidden footer that will be revealed at the end" to appear to scroll with the rest of the content and then stay put once it enters the page and then to have the surprise be revealed.
Would be grateful for any suggestions. Thank you.
EDIT: hope this helps to explain what I'm hoping to achieve. The above example is my fallback solution but hopefully this can be done:
EDIT 2: I have put together a new sample here but it's not quite right. When scrolling back down, it doesn't reverse the effect but it looks very close to what I'm hoping.
However, it's seems a bit of a hack... and it does not work on mobile. If anyone has any suggestions on how to do this better and make a conditional sticky footer, it would be great to hear your suggestions.
Here is a new sample where the text scrolls up with the page but then stops and the surprise fades in: http://jsfiddle.net/R3n7s/3/
jQuery(window).load(function(){
Query(window).scroll(function() {
if(jQuery(window).scrollTop() + jQuery(window).height() > jQuery(document).height() - 300) {
jQuery('#footer').css({"position":"fixed", "bottom":"0"});
} else {
jQuery('#footer').css({"position":"relative", "bottom":"auto"});
}
if(jQuery(window).scrollTop() + jQuery(window).height() > jQuery(document).height() - 70) {
jQuery('#surprise').fadeIn(600);
} else {
jQuery('#surprise').fadeOut(600);
}
});
});
You can try changing the height of '#footer' relative to the scrollTop value change when the scroll reached that jQuery(window).scrollTop() + jQuery(window).height() > jQuery(document).height() - 200 mark.
Also writing jQuery is tedious and hard to read for me :D. But if you're doing this because your using another library that uses the same dollar sign '$' alias, you can wrap your code in a jQuery function and alias '$' on it for brevity.
(function ($) {
$(window).load(function () {
$(window).scroll(function () {
var docViewTop = $(this).scrollTop(),
docViewBottom = docViewTop + $(this).height(),
docHeight = $(document).height(),
marginBottom = parseInt($('#wrapper').css('margin-bottom'));
if (docViewBottom >= docHeight - 200) {
$('#footer').height((docViewBottom + marginBottom) - docHeight)
}
if (docViewBottom >= docHeight - 50) {
$('h2 a').fadeIn(600);
} else {
$('h2 a').fadeOut(600);
}
})
});
})(jQuery);
See this jsfiddle.
Do you have something like this in mind? Inside of the if block:
{
$('h2 a').fadeIn(2000);
$('p').fadeIn(400);
} else { ... }
And with matching CSS:
#footer p {
display: none;
}
I did something very similar on this website. I set a data-attribute on each of the pages. As you scroll through them, I trigger various actions based on which slide is active and finally, on the 5th slide, I slide everything up slightly to make room for the footer, and the footer appears. If you scroll back up, the animation reverses and the footer retracts back down.
var activeslide = parseInt($(this).find('.active').prev().data('index'));
if (activeslide == 1) {}
if (activeslide == 2) {}
if (activeslide == 4) {}
if (activeslide == 5) { displayFooter(); }
var p = null;
function displayFooter() {
if(this===p) {
setTimeout(function(){
$('footer').css({'z-index':'0'});
},2000);
$('footer').stop().animate({'margin-top':0},2000);
$('.main').stop().animate({'top':0},2000);
$('#iphone').stop().animate({'top':'75px'},2000);
p = null;
return false;
} else {
$('footer').css({'z-index':'999'});
$('footer').stop().animate({'margin-top':'-255px'},2000);
$('.main').stop().animate({'top':'-65px'},2000);
$('#iphone').stop().animate({'top':'20px'},2000);
p = this;
return false;
}
}
I am using hammer.js to make a basic touch friendly mobile site. I have hidden the top menu with a negative top position and it will appear using css3 transitions upon a double tap. However I want it to then hide again upon a second double tap.
I have tried using if/else to call the top position then re-set it accordingly but I cant get it to work, anyone know where I am going wrong?
var t = $("#topbar");
var position = t.position();
$sw.on('doubletap', function(event) {
event.preventDefault();
if (position.top == '-55px') {
$('#topbar').css("top", "0");
}
else {
$('#topbar').css("top", "-55px")
}
});
The site address is http://www.bettondesignwork.co.uk/tim/mobile
Thanks
You can try this:
var t = $("#topbar");
var position = t.offset();
$sw.on('doubletap', function(event) {
event.preventDefault();
if (position.top == '-55px') {
$("#topbar").offset({ top: "0"});
}
else {
$('#topbar').offset({ top: "-55px"});
}
}
The problem could be this line
if (position.top == '-55px')
If i'm not mistaken, the .top property is numeric, so u could change the code to
if (position.top == -55)
Or become more defensive
if (position.top < 0)
Gets top position of one HTMLElement
function getHTMLElementTop(thisNode, Top)
{
if (Top == undefined)
{
var Top = 0;
}
if (thisNode.nodeType == 1)
{
Top += thisNode.offsetTop;
//if (thisNode.parentNode)
if (thisNode.offsetParent)
{
Top = getHTMLElementTop(thisNode.offsetParent, Top);
}
}
return Top;
}
May be it helps