I have floating div which content is dynamically populated using js function.
I'm using following code to make this div float
// Stick the #nav to the top of the window
var nav = $('#right-div');
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;
}
});
});
sometimes when enough content items is added this div height is larger than windows and part of div content is not visible at all, it stays bellow page margin.
So I'm thinking on js function where content is generated before adding to floating div to calculate windows height and floating div and simply apply bottom margin to floating div
if ($(window).height() < $("#right-div").height()) {
alert("float div is larger than window");
$("#right-div").css({bottom:100});
}
on firebug I see this applied bottom margin (100px) but part of div content is still hidden.
Related
I am using the following code to make a fixed div ("two") to only remain fixed when scrolling between two absolute positioned divs ("one" and "footer").
But I am having one problem, when the browser window is made smaller or larger the distance between the footer and where the fixed div ("two") becomes unfixed increases or decreases, so that the fixed div becomes unfixed before the footer gets to it or after the footer has passed it.
How can I solve this? Can anyone help?
The DEMO here.
UPDATE (21 JULY 2016):
It seems that what is happening is:
Because div "leftside" has its width set as a percentage, when the browser window gets dragged smaller the div "leftside" gets higher to fit its content. This leaves div "two" hanging higher above div "footer" because div "two" lowest possible vertical position is set on page load.
I need to maintain the responsive design, and I can't have the page reloading when scaling the browser window because of other functionality in my website. Scaling the page and then refreshing it in the browser actually does reset things properly, but reloading is not an option for me.
Perhaps options to solve this:
Is there a way to reset the lowest possible position of div "two"
when the window is scaled?
Or actually even better; perhaps resetting the lowest possible
position of div "two" very frequently and automatically, or
everytime the user does something on the webpage or scaling the
browser window. This because I have collapsible segments in the div
"leftside" that will make this div higher or less high without even
scaling the browser window.
I guess adaptation needs to be made in this section of the code(?):
$window.resize(function()
{
bumperPos = pos.offset().top;
thisHeight = $this.outerHeight();
setPosition();
});
$window.scroll(setPosition);
setPosition();
};
Here the full script:
var window = this;
$.fn.followTo = function (from, bumper) {
var $this = this,
$window = $(window),
$from = $(from),
$bumper = $(bumper),
$startPos = $from.offset().top + $from.height(),
bumperPos = $bumper.offset().top,
thisHeight = $this.outerHeight(),
setPosition = function(){
if ($window.scrollTop() < $startPos) {
$this.css({
position: 'absolute',
top: $startPos
});
} else if ($window.scrollTop() > (bumperPos - thisHeight)) {
$this.css({
position: 'absolute',
top: (bumperPos - thisHeight)
});
} else {
$this.css({
position: 'fixed',
top: 0
});
}
};
$window.resize(function()
{
bumperPos = pos.offset().top;
thisHeight = $this.outerHeight();
setPosition();
});
$window.scroll(setPosition);
setPosition();
};
$('#two').followTo('#one', '#footer');
I've made three modifications:
The pos variable was not defined, it should be bumper.
Reset $startPos on resize—this fixes the problem of element(s) above the sticky element changing their height/position on resize.
Moved the fixed element's top value to a parameter in the followTo function, and take it in consideration when switching the fixed/absolute positions for a smoother transition.
Here's the updated fiddle.
$.fn.followTo = function (from, bumper, fixedOffsetTop) {
var $this = this,
$window = $(window),
$from = $(from),
$bumper = $(bumper),
$startPos = $from.offset().top + $from.height(),
bumperPos = $bumper.offset().top,
thisHeight = $this.outerHeight(),
setPosition = function(){
if ($window.scrollTop() < $startPos - fixedOffsetTop) {
$this.css({
position: 'absolute',
top: $startPos
});
} else if ($window.scrollTop() > bumperPos - thisHeight - fixedOffsetTop) {
$this.css({
position: 'absolute',
top: (bumperPos - thisHeight)
});
} else {
$this.css({
position: 'fixed',
top: fixedOffsetTop
});
}
};
$window.resize(function()
{
$startPos = $from.offset().top + $from.height();
bumperPos = $bumper.offset().top;
thisHeight = $this.outerHeight();
setPosition();
});
$window.scroll(setPosition);
setPosition();
};
$('#two').followTo('#one', '#footer', 30);
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 a div that I want to keep position: fixed when scrolling between two points.
For example, it should remain fixed only between the height of it's container div
I've done the following:
$window.scroll(function(e) {
pos = $('.container-element').height();
if ($window.scrollTop() > pos) {
$(scroll-element).css({
position: 'relative',
});
} else {
$(scroll-element).css({
position: 'fixed',
});
}
});
However, this doesn't stop the scroll-element from becoming relative on reaching the end of the container-element. What should I do to achieve the intended behavior?
EDIT:
JSFiddle: http://jsfiddle.net/09760d60/
I think You should remove fixed position when $(window).scrollTop() > containerHeight-childHeight
$(document).ready(function(){
$(window).scroll(function(e) {
containerHeight = $('.container-element').height();
childHeight = $(".scroll-element").height();
if ($(window).scrollTop() > containerHeight-childHeight) {
$('.scroll-element').removeClass('fixed');
} else {
$('.scroll-element').addClass('fixed');
}
});
});
Please check updated fiddle
http://jsfiddle.net/PrashantShirke/1u991v1j/
You should check the top and bottom bounds of your container, and compare it with the top and bottom bounds of your scroll element :
$(document).ready(function(){
$(window).scroll(function(e) {
containerTop = $('.container-element').offset().top;
containerBottom = $('.container-element').height()+$('.container-element').offset().top;
scrollEl = $('.scroll-element').height();
if ($(window).scrollTop() >= containerTop && $(window).scrollTop()+scrollEl <= containerBottom) {
$('.scroll-element').css({
"top":$(window).scrollTop()+"px"
});
}
});
});
Exemple
$(window).scrollTop() < containerTop: scroll element is at top of content
$(window).scrollTop()+scrollEl > containerBottom: bottom of scroll element is at bottom of content
If scroll element has to move, adjust its top property while being absolutelly positioned by CSS.
I think it would be more robust to check the bottoms of the container and window, not the heights of the container and child.
$(document).ready(function(){
var $window = $(window);
var $container = $('.container-element');
var $scroll = $('.scroll-element');
var containerBox = $container[0].getBoundingClientRect();
$window.scroll(function(e) {
var scrollBottom = $window.scrollTop() + $window.height();
var canSeeContainerBottom = scrollBottom > containerBox.bottom;
$scroll.css('position', canSeeContainerBottom ? 'relative' : 'fixed');
});
});
http://jsfiddle.net/bryandowning/09760d60/14/
It's easy to keep a column in my layout fixed so it's always visible, even when the user scrolls down.
It's also easy to only move the column down the page when the page is scrolled down far enough for it to be out of the viewport so it's anchored before scrolling starts.
My problem is, I have left hand column that is taller than the average window so you need to be able to scroll down to see all the content (controls) in the left column but at the same time when you scroll up you want to see the top of the controls again.
Here's a visual of what I want to accomplish:
So the left column is always occupying 100% of the height of the window but as the user scrolls down they can see the bottom of the div, and when they start to scroll up the scrolls up until it reaches the top of the window again. So no matter how far they scroll the page, the top of the div is always nearby.
Is there some jQuery magic to make this happen?
Did you mean something like this? (Demo)
var sidebar = document.getElementById('sidebar');
var sidebarScroll = 0;
var lastScroll = 0;
var topMargin = sidebar.offsetTop;
sidebar.style.bottom = 'auto';
function update() {
var delta = window.scrollY - lastScroll;
sidebarScroll += delta;
lastScroll = window.scrollY;
if(sidebarScroll < 0) {
sidebarScroll = 0;
} else if(sidebarScroll > sidebar.scrollHeight - window.innerHeight + topMargin * 2) {
sidebarScroll = sidebar.scrollHeight - window.innerHeight + topMargin * 2;
}
sidebar.style.marginTop = -sidebarScroll + 'px';
}
document.addEventListener('scroll', update);
window.addEventListener('resize', update);
#sidebar {
background-color: #003;
bottom: 1em;
color: white;
left: 1%;
overflow: auto;
padding: 1em;
position: fixed;
right: 80%;
top: 1em;
}
body {
line-height: 1.6;
margin: 1em;
margin-left: 21%;
}
It almost degrades gracefully, too…
I made a fiddle for you, hope this helps you out abit.
I detect scroll up or scroll down, and set the fixed position accordion to the direction.
http://jsfiddle.net/8eruY/
CSS
aside {
position:fixed;
height:140%;
background-color:red;
width:100px;
top:20px;
left:20px;
}
Javascript
//Detect user scroll down or scroll up in jQuery
var mousewheelevt = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel" //FF doesn't recognize mousewheel as of FF3.x
$('html').bind(mousewheelevt, function(e){
var evt = window.event || e //equalize event object
evt = evt.originalEvent ? evt.originalEvent : evt; //convert to originalEvent if possible
var delta = evt.detail ? evt.detail*(-40) : evt.wheelDelta //check for detail first, because it is used by Opera and FF
if(delta > 0) {
$('aside').css('top', '20px');
$('aside').css('bottom', 'auto');
}
else{
$('aside').css('bottom', '20px');
$('aside').css('top', 'auto');
}
});
http://jsfiddle.net/KCrFe/
or this:
.top-aligned {
position: fixed;
top: 10px;
}
with
var scrollPos
$(window).scroll(function(event){
var pos = $(this).scrollTop();
if ( pos < scrollPos){
$('.sidebar').addClass('top-aligned');
} else {
$('.sidebar').removeClass('top-aligned');
}
scrollPos = pos;
});
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>.