I have a vertically oriented vertical navigation bar, that I would like to make stop at the end of #contact. It will need to resume scrolling again if the user scrolls back up.
What is the best way to achieve this?
javascript being used:
$(function() {
$.fn.scrollBottom = function() {
return $(document).height() - this.scrollTop() - this.height();
};
var $el = $('#nav>div');
var $window = $(window);
var top = $el.parent().position().top;
$window.bind("scroll resize", function() {
var gap = $window.height() - $el.height() - 10;
var visibleFoot = 340 - $window.scrollBottom();
var scrollTop = $window.scrollTop()
if (scrollTop < top + 10) {
$el.css({
top: (top - scrollTop) + "px",
bottom: "auto"
});
} else if (visibleFoot > gap) {
$el.css({
top: "auto",
bottom: visibleFoot + "px"
});
} else {
$el.css({
top: 0,
bottom: "auto"
});
}
}).scroll();
});
jsfiddle
I believe this is the code you are looking for:
$(function() {
var $Nav = $('#Nav');
var $window = $(window);
var $contact = $('#contact');
var maxTop = $contact.offset().top + $contact.height() - $Nav.height();
window.navFixed = 1;
$window.bind("scroll resize", function() {
var currentTop = $window.scrollTop();
if (currentTop <= maxTop && window.navFixed == 0) {
$Nav.css({
position: 'fixed',
top: '5%'
});
window.navFixed = 1;
} else if (currentTop > maxTop && window.navFixed == 1) {
$Nav.css({
position: 'absolute',
top: maxTop
});
window.navFixed = 0;
}
}).scroll();
});
The #Nav element contains the CSS you had originally specified: position: fixed; top: (...). When the document is ready, the variable maxTop is calculated based on the #contact element's top and height.
On the scroll and resize event, the variable currentTop is calculated as the current scroll position. If this value is lower than maxTop, then #Nav is set to the original CSS; if the value is higher, new CSS styles are applied: position: absolute; top: maxTop;
window.navFixed is used to prevent the CSS to be constantly updated while scrolling. I'm sure that bit can be improved, however, it demonstrates its purpose.
Check out the JSFiddle for the full HTML..
PS. There's a minor bug in your code, where #Nav refers to the <ul> element, rather than the <nav> element. However, the moving element is the <ul>, when it should be <nav>.
Related
I have ~33 divs that I am setting the position of randomly and animating this places. These divs are originally positioned with the help of flex and then the positions are randomized by setting their positions to relative and changing the left and top values. This happens every click.
On every alternate click, I want to return the divs to their normal position. So far the only solution to this I've found is the .removeAttr('style') method. However, I want to be able to animate their return to original position. Is this possible?
Here is the code:
var position_checker = false;
$(document).click(function() {
if(position_checker == false) {
$('.poster05-text').each(function() {
var position = $(this).offset();
$(this).css({
position: 'relative',
}, position);
var docHeight = $(document).height(),
docWidth = $(document).width(),
divWidth = 500,
divHeight = 500,
heightMax = docHeight - divHeight,
widthMax = docWidth - divWidth;
var posLeft = Math.floor(Math.random() * widthMax);
var posTop = Math.floor(Math.random() * heightMax);
// console.log(docHeight, docWidth);
$(this).animate({
position: 'fixed',
left: posLeft,
top: posTop
}, 1000 , 'easeInQuint');
});
position_checker=true;
}
else if(position_checker==true) {
$('.poster05-text').each(function() {
$(this).removeAttr('style');
});
position_checker=false;
}
});
I don't know this a right way to do that or not .. but anyway .. you need to save the previous left and top positions for each div on array
var position_checker = false , T_L_Positions = [];
$(document).click(function() {
if(position_checker == false) {
$('.poster05-text').each(function(i) {
var position = $(this).offset();
$(this).css({
position: 'relative',
}, position);
T_L_Positions[i] = new Array(position.top ,position.left);
var docHeight = $(document).height(),
docWidth = $(document).width(),
divWidth = 500,
divHeight = 500,
heightMax = docHeight - divHeight,
widthMax = docWidth - divWidth;
var posLeft = Math.floor(Math.random() * widthMax);
var posTop = Math.floor(Math.random() * heightMax);
// console.log(docHeight, docWidth);
$(this).animate({
position: 'fixed',
left: posLeft,
top: posTop
}, 1000 , 'easeInQuint');
});
position_checker=true;
}
else if(position_checker==true) {
$('.poster05-text').each(function(i) {
$(this).animate({
position: 'relative',
left: T_L_Positions[i][1],
top: T_L_Positions[i][0]
}, 1000 , 'easeInQuint');
});
position_checker=false;
}
});
Note: This Code Not Tested .. but you can try it
maybe you'll need to wrap your code in $(document).ready(function(){ //code here })
If you're looking for a non-JS solution. You should be able to use CSS Transitions to do this.
transition: top 500ms, left 300ms;
That way you can just set and remove the position and let CSS deal with the animation.
For more information check out these examples:
https://www.w3schools.com/css/css3_transitions.asp
https://css-tricks.com/almanac/properties/t/transition/
Here's the link to my code:
https://jsfiddle.net/81scw7eg/
MY JavaScript:
$(function() {
/* Stick the #bottomMenuBarContent to the top of the window */
var nav = $('#bottomMenuBarContent');
var navHomeY = nav.offset().top;
var isFixed = false;
var $w = $(window);
$w.scroll(function() {
var scrollTop = $w.scrollTop();
var shouldBeFixed = scrollTop > navHomeY;
if (shouldBeFixed && !isFixed) {
nav.css( {
position: 'fixed',
top: 0,
left: nav.offset().left,
width: nav.width()
});
isFixed = true;
} else if (!shouldBeFixed && isFixed) {
nav.css({
position: 'static'
});
isFixed = false;
}
});
});
/* Changes Navigation Bar Color on Scroll */
$(document).ready(function(){
var scroll_pos = 0;
$(document).scroll(function() {
scroll_pos = $(this).scrollTop();
if (scroll_pos > 50) {
$("#bottomMenuBarContent").css('background-color', '#2a2a2a');
} else {
$("#bottomMenuBarContent").css('background-color', 'grey');
}
});
});
I don't know why, but my navigation bar isn't resizing to my screen. Try opening up my site and resizing it to a smaller size. Now scroll down on the website so that the navigation bar changes colors, and then maximize the browser screen. For some reason it doesn't move along with it. Any ideas why?
Example Screenshot
in your example you set the width of the element to it's original width
(which is in this case made by it's content and which doesn't go 100% of the screen the moment you switch from position: static to position: fixed)
just replace the line
width: nav.width()
with
right: 0
I have this problem which is probable very simple to solve, but I'm a newbie with JS/JQuery.
I have this code (see fiddle here: https://jsfiddle.net/Tiph/6ep3hp4j/) where my div footer shows when the scroll gets at the bottom of the document, but I want it to show when the scroll gets at a certain height under my header and have a fixed position at the bottom of my window. I understand that I have to calculate something with window.height, and/of offsetTop, but nothing works.
Someone can help me with it?
Thank you so much! :-)
my code here:
var footer = $('#footer'),
extra = 10;
footer.css({ opacity: '0', display: 'block' });
$(window).scroll(function() {
var scrolledLength = ( $(window).height() + extra ) + $(window).scrollTop(),
documentHeight = $(document).height();
console.log( 'Scroll length: ' + scrolledLength + ' Document height: ' + documentHeight )
if( scrolledLength >= documentHeight ) {
footer
.addClass('bottom')
.stop().animate({ bottom: '0', opacity: '1' }, 300);
}
else if ( scrolledLength <= documentHeight && footer.hasClass('bottom') ) {
footer
.removeClass('bottom')
.stop().animate({ bottom: '-100', opacity: '0' }, 300);
}
});
I create new sample code for you to understand how its work
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(window).scroll(function() {
var count=700;
var menuHeight = $('#footer').height()+count;
var top = $(this).scrollTop();
var bottom = $(document).height() - $(this).height() - $(this).scrollTop();
if (bottom < menuHeight) {
$('#footer').removeClass( 'top' );
$('#footer').addClass( 'bottom' );
$('#footer').fadeIn( 'slow' );
}
else {
$('#footer').fadeOut( 'slow' );
}
});
});
</script>
<meta charset="utf-8">
</head>
<body>
<style>
#footer{
width: 100%;
height: 60px;
background-color: #cccccc;
vertical-align: middle;
text-align: center;
font-size:3em;
}
.bottom{
position: fixed;
bottom: 0;
left: 0;
z-index: 999;
display:block;
}
</style>
<div style="height:2000px;"></div>
<div id="footer" style="display:none" > This is your footer</div>
<div style="height:700px"></div>
Try to change the number 700 to set where you want to footer to be shown
Say you want the header to show when you have scrolled 100px from the top.
You can do something like:
$(window).on("scroll", function() {
if(document.body.scrollTop >= 100) {
$("#footer").fadeIn()
} else {
$("#footer").fadeOut()
}
});
Say, you want to only show the header if a button with id, callToAction is above the viewport, you can do:
$(window).on("scroll", function() {
if(document.getElementById('callToAction').getBoundingClientRect().top <= 0) {
$("#footer").fadeIn()
} else {
$("#footer").fadeOut()
}
});
This code var y = $(this).scrollTop(); get your scroll height from top.
$(window).scroll(function() {
var y = $(this).scrollTop();
if (y > 800) { // scroll gets at a certain height
$('.bottomDiv').fadeIn();
} else {
$('.bottomDiv').fadeOut();
}
});
If I correctly understand your question you need to change documentHeight with value what you want.
Example: documentHeight = 150; not documentHeight = $(document).height();
It is good idea to rename documentHeight variable.
I would like to create a panel who scroll to top with a fixed content under.
I would like to have this effect : Curtain JS
I don't want to use Curtain JS plugin because I only need the first effect. That the first panel be scrolled and when he disappeared be deleted. In fact that's it's effect be played once.
So I try this : my test
But the content under isn't fixed.
$(document).ready(function () {
var $vertical = $('#vertical');
$(window).scroll(function () {
var s = $(this).scrollTop(),
d = $(document).height(),
c = $(this).height();
scrollPercent = (s / (d - c));
var position = (scrollPercent * ($(document).height() - $vertical.height()));
$vertical.css({
'bottom': position
});
});
});
Can I have some help please ?
Here is a working version: http://jsfiddle.net/1wtaofr2/1/
Js:
$(document).ready(function () {
var $vertical = $('#vertical');
$('body').height($('.test').height() + $vertical.height());
$(window).scroll(function () {
var s = $(this).scrollTop(),
d = $(document).height(),
c = $(this).height();
scrollPercent = (s / (d - c));
var position = (scrollPercent * ($(document).height() - $vertical.height()));
$vertical.css({
"-webkit-transform":"translateY(-"+ position +"px)"
});
if (position > $vertical.height()) {
$('.test').css({
position: 'relative',
'padding-top': $vertical.height()
})
}
if (position < $vertical.height()) {
$('.test').css({
position: 'fixed',
'padding-top': 0
})
}
});
});
Css:
body {
margin-left: 0;
}
#vertical {
position: fixed;
width: 100%;
height: 100%;
background: red;
top: 0;
left: 0;
bottom: 0;
}
.test {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
In case you want to use an external library, maybe you will find scrollr useful.
I have been trying to figure this out; how do I get the .float-div not to margin from the top while scrolling down? I would like it to be fixed on the top of the window while scrolling. If you take away the .top-entry it will work fine. But how can I fix it without deleting the .top-entry?
http://jsfiddle.net/loktar/Kjc6k/2/
var $scrollingDiv = $(".float-div");
$(window).scroll(function(){
var y = $(this).scrollTop(),
$postEntry = $('.post-entry'),
maxY = $postEntry.offset().top + $postEntry.height(),
scrollHeight = $scrollingDiv.height();
if(y< maxY-scrollHeight ){
$scrollingDiv
.stop()
.animate({"marginTop": ($(window).scrollTop()) + "px"}, "slow" );
}
});
This is my new answer, this is a fiddle http://jsfiddle.net/Kjc6k/48/
hope this is what you are looking for :)
var $scrollingDiv = $(".float-div");
$(window).scroll(function(){
var y = $(this).scrollTop(),
$topEntry = $('.top-entry').height();
if( y > $topEntry){
$scrollingDiv
.stop()
.animate({"margin-top": y + "px"}, "slow" );
}
else
$scrollingDiv
.stop()
.animate({"margin-top": "80px"}, "slow" );
});
Adding top:0 to float-div class will easily fix this.
.float-div {
position: absolute;
background: red;
top: 0;
}
updated fiddle: http://jsfiddle.net/7KSTs/