I have 2 full height divs. When you scroll down the page the one div scrolls up and the other scrolls in an opposite direction. This works great.
I'm trying to keep this effect but put normal full width content underneath it whilst trying to maintain natural scrolling. So I'd like to keep the alternate scrolling effect but when I get to the bottom of the last div that uses this effect I would like to continue scrolling normally to see normal content underneath it.
Here's my jsFiddle, currently its floating over the effect I refer to: http://jsfiddle.net/u9apC/116/ and the JS is pasted below for reference:
(function ($) {
var top = 0;
$(document).ready(function () {
var contentHeight = $('.right').height(),
contents = $('.right > .content').length;
top = (0 - (contentHeight * (contents - 1)));
$('.right').css('top', top + 'px');
});
$(window).resize(function () {
var contentHeight = $('.right').height(),
contents = $('.right > .content').length;
top = (0 - (contentHeight * (contents - 1)));
$('.right').css('top', (top + $(window).scrollTop()) + 'px');
});
$(window).scroll(function () {
$('.right').css('top', (top + $(window).scrollTop()) + 'px');
});
})(jQuery);
EDIT
Here's a illustration of what I want:
I hope this is what you're after - it's a little hard to visualise from the description.
There are a couple of tricks to get this working:
Reverse the scroll direction when the right col top goes positive
Ensure the .row div has a top margin sufficient to push it down to the bottom of the left col.
(function ($) {
var top = 0;
var contentHeight = 0;
$(document).ready(function () {
calcContentHeight();
});
$(window).resize(function () {
calcContentHeight();
});
$(window).scroll(function () {
setRightTop();
});
function calcContentHeight() {
var contents = $('.right > .content').length - 1;
contentHeight = $('.right').height() * contents;
top = 0 - contentHeight;
setRightTop();
}
function setRightTop() {
var rightTop = top + $(window).scrollTop();
//1. don't allow right col top to go positive
if(rightTop > 0) rightTop = 0 - rightTop;
$('.right').css('top', rightTop + 'px');
//2. Ensure .row has sufficient top margin
$('.row').css('margin-top', contentHeight + 'px');
}
})(jQuery);
See updated JSFiddle here: http://jsfiddle.net/u9apC/126/
I've also refactored your code a little to reduce duplication.
You just need to make height of the div.body equal to total height of elements within it. Either by js or css.
Related
I have a fixed div on the right side of my page. I have it set up to scroll with the page and not overlap the footer and it works great. The problem is that it overlaps the nav when scrolling up. Is there any way to have it work for both? I tried to create a new function
function checkOffset() {
var a = $(document).scrollTop() + window.innerHeight;
var b = $('#footer').offset().top;
if (a < b) {
$('#social-float').css('bottom', '10px');
} else {
$('#social-float').css('bottom', (10 + (a - b)) + 'px');
}
}
$(document).ready(checkOffset);
$(document).scroll(checkOffset);
<nav class="nav">Nav Sample</nav>
<div id="social-float">
<div class="sf-twitter">twitter</div>
<div class="sf-facebook">facebook</div>
</div>
<div id="footer">footer sample</div>
Here checkout this fiddle for the solution.
I have added debug text on the page and also considered the fact that nav-bar might be offset due to other divs at the top.
/**
* This function checks for both top and bottom edges to position itself
* on the page
*/
function checkOffset() {
var documentTop = $(document).scrollTop();
var currentScrollOffset = documentTop + window.innerHeight;
var footerOffset = $('#footer').offset().top;
var navbarEffectiveHeight = $('.nav').outerHeight() + $('.nav').offset().top;
var $fixedElem = $('#social-float');
var fixedElemHeight = $fixedElem.outerHeight();
// until page scroll crosses navbar bottom edge (offset)
if (currentScrollOffset < navbarEffectiveHeight) {
$fixedElem.css('top', (currentScrollOffset + 10) + 'px');
$fixedElem.css('bottom', 'unset');
// page scroll crossed navbar bottom edge but not to extend of the height of fixed div
// including the top and bottom spacing for it which is 20px
} else if (currentScrollOffset < navbarEffectiveHeight + fixedElemHeight + 20) {
$fixedElem.css('top', (window.innerHeight - (currentScrollOffset - navbarEffectiveHeight) + 10) + 'px');
$fixedElem.css('bottom', 'unset');
// page scroll hasn't crossed footer top edge (offset)
} else if (currentScrollOffset < footerOffset) {
$fixedElem.css('bottom', '10px');
$fixedElem.css('top', 'unset');
// page scroll crossed footer top edge (offset)
} else {
$fixedElem.css('bottom', (10 + (currentScrollOffset - footerOffset)) + 'px');
$fixedElem.css('top', 'unset');
}
}
$(document).ready(checkOffset);
$(document).scroll(checkOffset);
Please help me out here, if bottom of div or full div is visible then i want to scroll to down of next div. Here the code i have tried out,
Mathematically,
var top = $("#myDiv").offset().top;
//top = 1863
var divHeight = $("#myDiv").height();
//divHeight = 571
var total = top + divHeight;
//total = 2434
if($('#myDiv').css('height',total).visible(true))
{
alert('hi');
// I need to alert only if the full div is visible not some part of div
}
else
{
//if height of myDiv is larger window height (my screen height 640 pixels)
}
If all this part of html(from top to divHeight) or bottom of page(here total value) is visible then i need to scroll to next div.
Please note :- the code inside if conditional statement is not correct, i think you got some idea from that.
Given element the jQuery object you want to check, element is fully visible if it is shown and all of the 4 sides of its layout box fall within the window viewport.
Caution: the following solution assumes that there are no element with scrollable overflow between element and the document root, otherwise the calculation becomes way more complicated.
function isFullyVisible(element) {
var offset = element.offset();
var scrollTop = $(document).scrollTop();
var scrollLeft = $(document).scrollLeft();
return element.is(":visible") && // shown
offset.top >= scrollTop && // top
offset.left >= scrollLeft && // left
offset.top + element.outerHeight() <= scrollTop + $(window).height() && // bottom
offset.left + element.outerWidth() <= scrollLeft + $(window).width(); // right
}
If you don't care of sides, you can keep only the corresponding sub-expression.
I have a page with a simple div. If the div is at the top of the page, the background image (a very long vertical wallpaper) should also only be displaying the top section. If we scroll all the way down, then at the last area way at the bottom, the bottom of the background will show. The effect is that it's like a parallax where the scrolling of the content and background image occur in tandem and are scaled to each other.
How would I do this?
Update: My attempt is something like this:
function setupMainContent(){
$("#programming").delay(1000).fadeIn(1000, function(){
$(window).scroll(function(){
var current = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
var scale = 100*(current/bottom);
$('body').css({
'background-position':scale+'%'
});
});
}
I don't really know how to work with variables within quotes however.
Update: I got it to work using this:
function setupMainContent(){
$("#programming").delay(1000).fadeIn(1000, function(){
$(window).scroll(function(){
var current = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
var scale = 100*(current/bottom) + "%";
document.body.style.backgroundPosition = "center " + scale;
});
});
}
But there seems to be very bad impact on performance. Is there any way to make it more responsive and faster?
CSS:
background-attachment: fixed;
https://developer.mozilla.org/en-US/docs/Web/CSS/background-attachment
This worked for me:
function setupMainContent(){
$("#programming").delay(1000).fadeIn(1000, function(){
$(window).scroll(function(){
var current = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
var scale = 100*(current/bottom) + "%";
document.body.style.backgroundPosition = "center " + scale;
});
*/
});
}
So, I have a div which I'm trying to keep 100px from the top of the page between to points of the page whilst scrolling. At the moment, my code works-ish but the div is not kept at exactly 100px from the top, instead altering between 0px - 200px
here's what I'm using atm:
$(window).scroll(function(){
var tpxl = $(window).scrollTop();
if( tpxl<100) {
$('#div').css('top',-Math.abs(tpxl)+100 + 'px');
}
else if(tpxl>700) {
$('#div').css('top',-Math.abs(tpxl)+800 + 'px');
}
});
You don't need Math.abs() because tpxl will always be a positive number. To set the position of the div to be 100px from the current top of the window, use $(window).scrollTop() + 100 + 'px'.
I don't really understand why you have the if / else if structure. The following would keep the div fixed at 100px all the time:
$(window).scroll(function () {
$('#div').css('top', $(window).scrollTop() + 100 + 'px');
}).scroll();
Demo: http://jsfiddle.net/G5BVU/
To only set the position "fixed" when the scroll point is less than 100 or more than 700 like for your original code try this:
$(window).scroll(function () {
var tpxl = $(window).scrollTop();
if (tpxl < 100 || tpxl > 700) {
$('#div').css('top', tpxl + 100 + 'px');
}
}).scroll();
Demo: http://jsfiddle.net/G5BVU/1/
EDIT: To have the element scroll normally except when the window is scrolled between those two points just reverse the if condition from my previous example:
if (tpxl > 100 && tpxl < 700)
$('#div').css('top', tpxl + 100 + 'px');
http://jsfiddle.net/G5BVU/2/
In all cases provide an initial top setting as appropriate.
I have a sort of sidebar on my website, which has to scroll down together with the user so that it is always in the view.
The code I'm using now is actually working fine however there is one problem. On smaller screens the sidebar scrolls before your at the sidebar thus making it impossible to see it all even if you scroll.
So what I want is the sidebar to scroll with the bottom instead of it being pushed down with the top so that when you reach the end of the sidebar it starts to scroll.
This is the code that I'm currently using.
var documentHeight = 0;
var topPadding = 10;
$(function() {
var offset = $("#mainright").offset();
documentHeight = $(document).height();
$(window).scroll(function() {
var sideBarHeight = $("#mainright").height();
if ($(window).scrollTop() > offset.top) {
var newPosition = ($(window).scrollTop() - offset.top) + topPadding;
var maxPosition = documentHeight - (sideBarHeight);
if (newPosition > maxPosition) {
newPosition = maxPosition;
}
$("#mainright").stop().animate({
marginTop: newPosition
});
} else {
$("#mainright").stop().animate({
marginTop: 0
});
};
});
});
I guess the "best practice" for accomplishing a task like this is to use dynamically changing css position from absolute to fixed and vice versa. A basic example could look like:
$(function(){
var $box = $('.box'),
offset = $box.offset(),
doc_h = $(document).height();
$(window).scroll(function(){
if($(window).scrollTop() > offset.top) {
if(!$box.hasClass('fix'))
$box.toggleClass('normal fix');
}
else{
if(!$box.hasClass('normal'))
$box.toggleClass('normal fix');
}
});
});
Example in action: http://www.jsfiddle.net/YjC6y/14/
$(function() {
var top = 50;
$(window).scroll(function() {
$('#box').stop().animate({ top: $(window).scrollTop() + top}, 1000);
});
});
Try the example : http://jsbin.com/omiyi3
I think you can instead make the sidebar responsive by throwing your function into one of these:
if (responsive_viewport >= 768) {}
This makes it so that the function will only load if the viewport is bigger than or equal to 768px.