Fixed secondary Nav bar after scrolling - javascript

I was looking through some of the posts and I found most my answer however it's still not working properly for me.
http://jsfiddle.net/5n5MA/619/
The bar you see on the jsfiddle should be catching lower than the top because there is a fixed header that will be there on my main site this secondary bar is supposed to go below it. I can get it to be fixed on jsfiddle but not on my site. And as you can see it is shrinking when it changes to fixed.
HTML:
<header>
<img class="logo" src="images/headerLogo.png">
<p class="about lighter">ABOUT US</p>
<p class="contact lighter">CONTACT US</p>
<img class="getStarted" src="images/getStarted.png">
</header>
<div class="mainSection1">
<h1>SAVE TIME & MONEY</h1>
<h2 class="lighter">CONCIERGE HAS ALL THE ANSWERS</h2>
<p>$79.99 VALUE<br>FREE FOR YOUR CLIENTS</p>
<img class="getStarted" src="images/getStarted.png">
</div>
<div class="subBar">
<p class="first">VALUE</p> <p class="second">SERVICES</p> <p class="third">BRANDS</p> <p class="fourth">HOW IT WORKS</p>
</div>
JS:
var nav = $('.subBar');
if (nav.length) {
var fixmeTop = nav.offset().top -100;
$(window).scroll(function () {
var currentScroll = $(window).scrollTop();
if (currentScroll >= fixmeTop) {
$('.subBar').css({
position: 'fixed',
width: '100%',
top: '73px',
left: '0'
});
$('header').css(
'box-shadow', 'inherit'
);
} else {
$('.subBar').css({
position: 'static'
});
$('header').css(
'box-shadow', '0px 5px 9px #515151'
);
}
});
}
css:
.subBar {
background: #F1F1F2;
height: 65px;
}
.subBar p:first-child {
margin-left: 15%;
border-left: 1px solid #bbbdc0;
}
.subBar p {
float: left;
border-right: 1px solid #bbbdc0;
width: 17%;
text-align: center;
height: 44px;
margin-top: 0px;
padding-top: 21px;
font-weight: lighter;
}

This is because the div .subBar is not given any width.
Because of this it's width get shrinked when it's position becomes fixed, taking it to be auto by default.
So specify a fixed width. It will take that width in any position.
Also, you need to have some margin on left and right so that it stays the same as you want.
You can make the following changes:
.subBar {
background: #F1F1F2;
height: 65px;
width:100%;
}
Another more accurate solution:
Change in the jquery
if (currentScroll >= fixmeTop) {
$('.subBar').css({
position: 'fixed',
top: '72px'
});
} else {
$('.subBar').css({
position: 'static',
width:'auto';
});
}
Check the FIDDLE.

Issue has been solved! I decided to make a second navbar that starts hidden than is shown when I scroll down enough. It seems to be way less jumpy and isn't taking the original bar out of the dom (which messes with other elements below it).

Related

how to change position from fixed to absolute and not have the div jump

I am implementing a sticky behaviour for a div, that works like this
when user scrolls the page, the sidebar on the right scrolls up till it reaches close to the top then it stops while user is still scrolling down sidebar should again start to scroll up when user reaches close to the bottom of page.
What happens is when user reaches close to the bottom I change the position of the sidebar from fixed to absolute and that makes it jump.
Is there way to change a position from fixed to absolute and have it not jump while I do that but continue the scroll up from the same coordinates?
<div class="col-md-4" style="border: 0px dashed black; margin-left: 2.933%; height: 832px; osition: relative;">
<div class="sticky" style="border: 1px dashed red;">
<div id="map" style="min-height: 350px;"></div>
<div style="padding: 20px">interesting</div>
<div style="padding: 20px">interesting</div>
<div style="padding: 20px">interesting</div>
<div style="padding: 20px">interesting</div>
<div style="padding: 20px">interesting</div>
<div id="last-interesting">last-interesting</div>
</div>
var stickyHeaderTop = $('.sticky').offset().top;
if( $(window).scrollTop() > stickyHeaderTop-10 ) {
$('.sticky').css({position: 'fixed', zoom: '1', top: '10px', left:'925px'});
} else {
$('.sticky').css({position: 'relative', zoom: '1', top: '0px', left: '0px', width:'330px'});
}
if ($('#content-last').visible(true)) {
// alert('visible');
console.log($('.sticky').offset().top);
$('.sticky').css({position: 'absolute', zoom: 'auto', 'z-index': '1', left: '', height: ''});
}
I've tried this also
$('.sticky').css({position: 'absolute', top: '0' zoom: 'auto', 'z-index': '1', left: '', height: ''});
and this
$('.sticky').css({position: 'absolute', top: $(window).scrollTop()+'px', zoom: 'auto', 'z-index': '1', left: '', height: ''});
but the first one is like not setting top at al, just like in the video, and the second one jumps down to the middle of screen.
Got any ideas how I may solve this issue?
you can see the sticky effect I am after right here.
I can show you how to make from position: static to position:fixed, I think you can use it to what you want to do:
HTML:
<div class='container'>
<div class='body'>
</div>
<div class='right'>
<div class='box'>
</div>
</div>
</div>
Sorry for SCSS
SCSS:
.container{
div{
display:inline-block;
float:left;
}
}
.body{
background-color: #3fa142;
height: 250vh;
width: 65%;
}
.right{
padding-top: 70px;
height: 250vh;
width: 34%;
.box{
height: 34vh;
background-color: #f66a68;
width: 150px;
}
}
jQuery:
boxPosition = $(".box").offset().top;
$(window).scroll(function(){
var isFixed = $(".box").css("position") === "fixed";
if($(window).scrollTop() > boxPosition && !isFixed){
$(".box").css({position:"fixed", top: "0px"});
}else if($(window).scrollTop() < boxPosition){
$(".box").css({position:"static"});
}
})
Let me know if you have any questions regarding this solution.
JSFiddle Link
The best solution I found was to use sticky position that is only implemented in some browsers
position: -webkit-sticky; // required for Safari
position: sticky;
top: 0; // required as well.
On browsers that is not supported polyfill is used, there is plugin for it
https://github.com/wilddeer/stickyfill
To use it just do
$('.sticky').Stickyfill();
It works perfectly, check the demo here http://wd.dizaina.net/en/scripts/stickyfill/
You cannot get the same smooth effect changing absolute to fixed and vice versa. You can only get that by using position sticky.

Absolute CSS positioning with a top margin

I have a sidebar with some text and a footer inside it (which sticks to the bottom of the sidebar). When I resize (reduce) the window's height to e.g. half, the footer goes on top of the other texts in the sidebar. Is there a way to have a margin-top for example, so that when the window get resized, the footer keeps its position at the bottom until it is about to go on top of other elements (before it)?
.sidebar {
position: fixed;
width: 260px;
overflow-y: auto;
border-right: 1px solid #dadada;
display: inline-block;
background-color: #BDE6CA;
float: left;
z-index: 3;
}
.sidebar-content {
position: relative;
height: 100%;
width: 100%;
}
.sidebar-option {
color: #00aa4f;
font-size: 20px;
cursor: pointer;
padding: 20px 0px 20px 20px;
}
.sidebar-bottom {
bottom: 0px;
position: absolute;
width: 100%;
padding: 0px 40px 20px 0px;
text-align: right;
}
<div class="sidebar max-height">
<div class="sidebar-content">
<div class="sidebar-top">
<img class="sidebar-logo" src="http://lorempixel.com/50/50">
<div class="sidebar-option">
<img src="http://lorempixel.com/50/50">
<span>Section 1</span>
</div>
<div class="sidebar-option">
<img src="http://lorempixel.com/50/50">
<span>Section 2</span>
</div>
</div>
<div class="sidebar-bottom">
<div class="sidebar-text"><span>Sidebar footer</span>
</div>
</div>
</div>
</div>
You may add padding-bottom:40px; (example) to .sidebar-top or .sidebar-content, so there will be enough space for .sidebar-bottom
I realized this functionality cannot be done only in CSS, we need Javascript for detecting window resize and then applying CSS attributes conditionally. Since I am already using Angular.js, I prefer an Angular.js way, but the same can be done in pure Javascript or jQuery.
Using scope.$watch in a custom directive, I can detect window resize, conditionally apply CSS to the footer element (using the ng-style directive on the footer) and finally calling scope.$apply() (in my directive) to force a digest.
The "demo 3" fiddle in the first answer to this question helped a lot. Here is my fiddle. The most relevant part is applying the custom directive ("resize") and ng-style to the footer element:
<div class="sidebar-bottom" ng-style="changePosition()" resize>
<div class="sidebar-text"><span>Footer Text 1</span></div>
<div class="sidebar-text"><span>Footer Text 2</span></div>
</div>
and the directive itself and the function scope.changePosition():
app.directive('resize', function ($window) {
return function (scope, element, attr) {
var w = angular.element($window);
scope.$watch(function () {
return {
'h': window.innerHeight,
'w': window.innerWidth
};
}, function (newValue, oldValue) {
scope.changePosition = function () {
var pos ="";
if (newValue.h < 440) {
pos = "relative"
} else {
pos = "absolute"
}
return {
'position': pos
};
};
}, true);
w.bind('resize', function () {
scope.$apply();
});
}
});
And the default/initial style for the footer div:
.sidebar-bottom {
bottom: 0px;
position: absolute;
}

jQuery page animation makes button jump

So I was busy on a site, and I made a menu button with a menu which is hidden on the right side of the page as shown below:
When I press the red button, which is used to open the menu, the button jumps like 15px to the left.
As you can see, the button jumps, I would recommend using the black header to measure.
The button stays in its new position until I refresh the page.
Here is my jQuery:
$("#zijmenu-knop").click(function()
{
if($("#zijmenu").css('right') == '0px')
{
controlZijmenu('dicht');
}else if($("#zijmenu").css('right') == '-300px')
{
controlZijmenu('open');
}
});
function controlZijmenu(controller)
{
if(controller == 'dicht')
{
$("#zijmenu").stop(true).animate(
{
right : '-300px'
}, 500);
$("#mainSite, #zijmenu-knop").stop(true).animate(
{
right : '0px'
}, 500);
}else if(controller == 'open')
{
$("#zijmenu").stop(true).animate(
{
right : '0px'
}, 500);
$("#mainSite, #zijmenu-knop").stop(true).animate(
{
right : '300px'
}, 500);
}
}
Does anybody see any mistakes? Also, if more code is needed, please comment.
EDIT:
My CSS:
#zijmenu-knop {
width: 40px;
height: 40px;
cursor: pointer;
background-image: url(../img/menuknopje.png);
background-repeat: no-repeat;
z-index: 101;
position: fixed;
margin-top: -45px;
margin-right:3%;
margin-left:97%;
}
#zijmenu {
background: #DD5C65;
height:100%;
width:305px;
position: fixed;
z-index: 100000;
overflow: hidden;
right: -300px;
}
#mainSite{
width:100%;
position: fixed;
z-index: 1000;
right: 0px;
overflow: auto;
}
My HTML:
<div id="zijmenu">
<p class="zijmenu-titel">GH 24Hourz</p>
<div id="zijmenu-nieuwtjes">
<div class="zijmenu-shouts">
Open de verzoeklijnen
</div>
<a><div class="zijmenu-twitter"></a>
Open de twitter feed
</div>
</div>
</div>
<div id='mainSite'>
<header></header>
<div class="shadow">
<div id='zijmenu-knop'></div>
</div>
The #zijmenu-knop already has a margin-right property.
When opening the menu, #zijmenu-knop has right value of 300px along with the margin-right of 3%.
So, the total distance from right increases making it move to the left a little more. All you have to do is replace the margin-right property of #zijmenu-knop to right and it becomes :
#zijmenu-knop{
right: 3%;
}
By doing this, when the menu opens, the above rule of right is replaced by 300px which makes the distance from right side correct.
To make the position from right better, I would suggest to increase the right value from 300px to 315px, because the width of #zijmenu is 305px.

JavaScript Wrap Around Carousel

I am looking for some information from some front end experts on how to go about creating a custom wrap around js carousel gallery. The idea is simple really I have a carousel of images, text, or whatever and when I get to the end I want it to wrap around. I don't want the content to simply fadeIn and out to the next piece of content. This is a gallery of div's currently but suppose it's images or whatever have you.
HTML
<div id="outside-container">
<div id="inside-container" class="cf">
<div class="items" id="item1"></div>
<div class="items" id="item2"></div>
<div class="items" id="item3"></div>
<div class="items" id="item4"></div>
</div>
</div>
<div id="directions">
<h4 id="left-button">Left</h4>
<h4 id="right-button">Right</h4>
</div>
CSS
#outside-container{
display: block;
width: 400px;
height: 125px;
overflow: hidden;
border: 1px solid #000;
margin: 0px auto;
}
#inside-container{
display: block;
width: 800px;
overflow: hidden;
height: 100%;
}
.items{
float: left;
margin: 0px;
width: 200px;
height: 100%;
}
#item1{ background: green; }
#item2{ background: red; }
#item3{ background: blue; }
#item4{ background: yellow; }
#directions{
display: block;
width: 400px;
margin: 0px auto;
text-align: center;
}
#left-button, #right-button{
display: inline-block;
cursor: pointer;
margin: 10px;
}
JS
var move = 0;
$("#left-button").click(function(){
move += 200;
$("#inside-container").animate({
marginLeft: move+"px"
}, 500);
});
$("#right-button").click(function(){
move -= 200;
$("#inside-container").animate({
marginLeft: move+"px"
}, 500);
});
Here is the codepen. So to sum all this up. I am asking for a way to create an infite loop for a gallery. I have always programmed these sorts of things to come to an end and then the user has to go back the other way. If this sounds confusing follow check out the codepen. Thanks in advance.
Here you go
http://codepen.io/nickavi/pen/cpFCE
But for the love of god, please don't use jQuery animate... at least add velocity.js to it, or the GSAP plugin, you don't even have to alter your JS you just add it in and it replaces the animate function with a more efficient one.
Cheers JBSTEW
First set move to the default slider and margin reset amount:
var move = 200;
Then, set the container margin to slide left by the move amount:
var margin_reset = (move * -1) + 'px'
$("#inside-container").css('margin-left', margin_reset);
Then, adjust the animation margin slide using move variable again, and execute a function when the animation is complete that moves the last/first item to the beginning/end of the container using prepend/append.
$("#left-button").click(function(){
$("#inside-container").animate({
marginLeft: 0
}, 500, function() {
$(this).prepend( $(this).find('.items:last') )
.css('margin-left', margin_reset);
});
});
$("#right-button").click(function(){
$("#inside-container").animate({
marginLeft: (move * -2) +"px"
}, 500, function() {
$(this).append( $(this).find('.items:first') )
.css('margin-left', margin_reset);
});
});
To avoid an initial draw jump, you could change the default css #inside-container as:
#inside-container{
...
margin-left: -200px;
}
see: Codepen

Bar fixed on top, but only if the scroll tries to hide it

I have a menu on the highest zone of my web, but not on the top. I want that when the user scrolls the page it stays on the top, but only when it would disapear instead. If the title is visible i want the menu under it, on an apparent static position.
Is it possible without javascript, only with css? I see it on a website, but I don't remeber where.
Thank you in advance (and sorry for my ugly english!) ;)
I think this is what you are looking for: https://jsfiddle.net/QuVkV/2/
Here html structure:
<div id='wrapper'>
<div id='upper'>This is upper content</div>
<div id='position-saver'>
<div id='bar'>This is the menu bar</div>
</div>
<div id='lower'>This is some content lower than the menu bar</div>
</div>
This is the css :
#wrapper {
width: 100%;
height: 2000px;
}
#upper {
width: 100%;
height: 100px;
}
#position-saver {
height: 50px;
width: 100%;
}
#bar {
position: static;
height : 50px;
width: 100%;
}
And here is the javascript :
$(document).on('scroll', function(){
if ($('#bar')[0].offsetTop < $(document).scrollTop()){
$("#bar").css({position: "fixed", top:0});
}
if ($(document).scrollTop() < $("#position-saver")[0].offsetTop){
$("#bar").css({position: "static", top: 0});
}
});
I'm not sure but I've seen this type of thing on many site. One on 9gag.com
Anyway, you can use the position property of the css.
like this one: JSFiddle
#scroll-me{
width:100%;
height:100px;
background:#333;
position: fixed;
top:15px;
}
The position:fixed with top:15px of the scroll-me div makes it always 15px on top

Categories

Resources