Changing div postion depending on page scroll - javascript

I have the following code below that changes a div's position to fixed once an element scrollTop is greater than a number. I am trying to either amend this script or find a different solution so that the div will scroll between a range and STOP scrolling at some point ( so the div doesn't go off the page or overlap with footer elements.
I don't know if the right way is to say that IF scrollTop is greater than 150 then position=fixed, and if it's greater than 600 then position goes back to absolute, or if there's a better way, like distance from the bottom...
AND I use MooTools, not jQuery. I know there are a few jQuery options / plugins that do this. Thanks in advance!
window.onscroll = function()
{
if( window.XMLHttpRequest ) { // IE 6 doesnt implement position fixed nicely...
if (document.documentElement.scrollTop > 150) {
$('tabber').style.position = 'fixed';
$('tabber').style.top = '0';
} else {
$('tabber').style.position = 'absolute';
$('tabber').style.top = 'auto';
}
}
}

the script above is wrong on many levels.
don't use window.onscroll but window.addEvent("scroll", function() {});
cache selectors. using $("tabber") 3 times on each scroll when the element does not change is expensive.
just do var tabber = $("tabber") and reference that.
you don't need to do
$("tabber").style.position = ...
$("tabber").style.top = ...
do:
tabber.setStyles({
position: "fixed",
top: 12123,
right: 24
});
There are mootools plugins for this, eg scrollSpy by David Walsh: http://davidwalsh.name/mootools-scrollspy
it can allow you to set scripted events upon reaching various scrolling destinations or events, look at the examples.
or you could just write it yourself, eg, this took me 15 mins to do:
http://jsfiddle.net/dimitar/u9J2X/ (watch http://jsfiddle.net/dimitar/u9J2X/show/) - it stops being fixed when it reaches to 20 px of the footer. and then goes back to fixed if scrolling up again.

Related

Freeze element (position:fixed) for specific scroll range

I'm working on this site (http://styleguide.co/medhelp/) that has 5 sections. For one of the sections (Styles), I've got a sidenav I'm trying to get to stick in the visible frame only as long as users are scrolling in that section.
Here's what I've done thus far - I'm telling the section title & sidenav to stick after the top of the section has begun:
$(window).scroll(function(event) {
var sw = $('.fixed'),
pg = $('.styles'),
diff = pg[0].offsetTop - window.pageYOffset;
if (diff < 80 ) {
$('.fixed').css('position', 'fixed');
$('.fixed').css('top', '160px');
$('.styles').css('position', 'fixed');
$('.styles').css('top', '70px');
}
else {
$('.fixed').css('position', 'relative');
$('.fixed').css('top', '0px');
$('.styles').css('position', 'relative');
$('.styles').css('top', '0px');
}
});
I can't seem to figure out a good way to make the section title "Style" and the sidenav appear/disappear while I scroll to/from that section. Any advice? What could I do better? A simple solution demo in jsfiddle would really help!
Please click on this link & scroll down/up to know what I'm referring to: http://styleguide.co/medhelp/
I'm not going to give you a fiddle, but you need to determine when the next section would stick based on its offset from the top. At the moment what you are doing is:
// if difference top and element < 80 -> fix to top, else position is relative
First of all this means the condition will never be undone. What you need to do in order to continue is:
// once next contact section comes into screen
//(offset from the top of the screen <= screen height), give
var winHeight = $(window).height();
var calcTop = 80 - (winHeight - (winHeight - $('#nextSelector').offset().top);
$('.fixed').css('top', calcTop);
This will give the illusion of your text scrolling up as the new section comes up. I hope this helps. Also, when scrolling back up it doesn't re-stick, but you probably are aware of that.

Jquery change div based on another div's position

Let me start of by saying, I'm just now learning JS and Jquery, so my knowledge is very limited.
I've been looking around for 2 days now, and tried all sorts of combinations. But I just can't get this to work.
Below is an example of the layout
I'm looking for a way to trigger an event when div 1 is X px from the top of the screen. Or when div 1 collides with div 2.
What I'm trying to accomplish is to change the css of div 2 (the fixed menu) when div 1 is (in this case) 100px from the top of screen (browser window). Alternatively, when div1 passes div2 (I'm using responsive design, so the fixed height from top might become a problem on smaller screens right? Seeing as the header for example won't be there on a hand held.). So maybe collision detection is better here? Would really appreciate some thoughts and input on this matter.
Another issue is, div2 has to revert back to is previous css once div1 passes it (going back (beyond the 100px)).
This is what I have but it has no effect
$(document).ready(function() {
var content = $('#div1');
var top = $('#div2');
$(window).on('scroll', function() {
if(content.offset().top <= 100) {
top.css({'opacity': 0.8});
}else{
top.css({'opacity': 1});
}
});
});
I am not sure of the reason but $("#content").offset().top was giving a constant value on console. So I added window.scrollTOp() to check its distance from top, here is how it works,
$(document).ready(function() {
var top = $("#menu");
$(window).on('scroll', function(){
if(($('#content').offset().top - $(window).scrollTop()) <= 100){
top.css({'opacity': 0.4});
}else{
top.css({'opacity': 1});
}
});
});
And DEMO JSFIDDLE....

JQuery Offset and ScrollTop Problems

I'm trying to fix a elements position based on the scroll position within the window.
I thought it would be as easy as getting the offset of the element where the fixed element should become fixed and then when the window.scrollTop is equal to it add CSS but it is weird.
It seems as though the offset of the element is larger than the scrollTop largest numeral.
Is there any other way of getting this to work?
I want it to have the same functionality as this with regards to the footer on scroll;
http://be.blackberry.com/
But I don't want to clone the element, I want to detect when it gets to near the bottom of the page and then change the position on the bottom of the element.
Thanks in advance.
B
This should help get you in the right direction:
var footer = $("#footer");
// min amount to show when not scrolled to the bottom of the page.
var minVisable = 25;
$(parent.document).scroll(function() {
// check position
if (window.scrollY + window.innerHeight + minVisable > $("html").height()) {
// if at the bottom of the page, stick the footer to it
footer.css("position","absolute").css("top", $("html").height() - footer.height());
} else {
// else keep top part of footer on the screen
footer.css("position","fixed").css("top", window.innerHeight - minVisable );
}
});

Floating elements on scroll

I was wondering how sites like Facebook, with their timeline feature, float a certain element (usually a menu bar, or sometimes a social plugin, etc) when the user has scrolled past a point such that the top of the element is off the screen, etc.
This could be seen as a more general JavaScript (jQuery?) event firing when the user has scrolled to a certain element, or scrolled down a certain number of pixels.
Obviously it would require toggling the CSS property from:
#foo { position: relative; }
to
#foo { position: fixed; }
Or with jQuery, something like:
$('#foo').css('position', 'fixed');
Another way I have seen this implemented is with blogs, where a popup will be called when you reach the bottom, or near the bottom of a page. My question is, what is firing that code, and could you link or provide some syntax/ semantics/ examples?
Edit: I'm seeing some great JS variants coming up, but as I am using jQuery, I think the plugin mentioned will do just nicely.
Take a look at this jsfiddle: http://jsfiddle.net/remibreton/RWJhM/2/
In this example, I'm using document.onscroll = function(){ //Scroll event } to detect a scroll event on the document.
I'm then calculating the percentage of the page scrolled based on it's height. (document.body.scrollTop * 100 / (document.body.clientHeight - document.documentElement.clientHeight)).
document.body.scrollTop being the number of pixels scrolled from the top, document.body.clientHeight being the height of the entire document and document.documentElement.clientHeight being the visible portion of the document, a.k.a. the viewport.
Then you can compare this value to a target percentage, an execute JavaScript. if(currentPercentage > targetPercentage)...
Here's the whole thing:
document.onscroll = function(){
var targetPercentage = 80;
var currentPercentage = (document.body.scrollTop * 100 / (document.body.clientHeight - document.documentElement.clientHeight));
console.log(currentPercentage);
if(currentPercentage > targetPercentage){
document.getElementById('pop').style.display = 'block';
// Scrolled more than 80%
} else {
document.getElementById('pop').style.display = 'none';
// Scrolled less than 80%
}
}
​If you prefer jQuery, here is the same example translated into everybody's favorite library: http://jsfiddle.net/remibreton/8NVS6/1/
$(document).on('scroll', function(){
var targetPercentage = 80;
var currentPercentage = $(document).scrollTop() * 100 / ($(document).height() - $(window).height());
if(currentPercentage > targetPercentage){
$('#pop').css({display:'block'});
//Scrolled more than 80%
} else {
$('#pop').css({display:'none'});
//Scrolled less than 80%
}
});​
An idea would be to handle the window.scroll event and determine if the user has scrolled to the bottom of the page. Here is an example:
http://chrissilich.com/blog/load-more-content-as-the-user-reaches-the-bottom-of-your-page-with-jquery/
Hope it helps!
There is a jquery plugin that might help you in the right direction.
http://imakewebthings.com/jquery-waypoints/
I just answered basically the same question here. In that case it was a table and its header, and the basic idea is like this:
function placeHeader(){
var $table = $('#table');
var $header = $('#header');
if ($table.offset().top <= $(window).scrollTop()) {
$header.offset({top: $(window).scrollTop()});
} else {
$header.offset({top: $table.offset().top});
}
}
$(window).scroll(placeHeader);
Here's a demo.
Quoting myself:
In other words, if the top of the table is above the scrollTop, then
position the header at scrollTop, otherwise put it back at the top of
the table. Depending on the contents of the rest of the site, you
might also need to check if you have scrolled all the way past the
table, since then you don't want the header to stay visible.
To answer your question directly, it is triggered by checking the scrollTop against either the position of an element, or the height of the document minus the height of the viewport (for the scrolled to bottom use case). This check is done every time the scroll event is fired (bound using $(window).scroll(...)).

unit of increment in scrollable areas / divs in javascript?

in javascript can I make sure that my large div scroll vertically
only in chunks of (let's say) 16 pixels
In java, those are called 'units of increment'.
I can't find anything similar in javascript:
I want to ensure that a certain area (div) when partially scrolled is always a multiple of 16 the view.
That allows me to do tricks with background images and others.
thanks
var lastScroll = 0;
$('div').scroll(function(){
var el = $(this),
scroll = el.scrollTop(),
round = lastScroll < scroll ? Math.ceil : Math.floor;
lastScroll = round(scroll/16) * 16;
el.scrollTop(lastScroll);
});
http://jsfiddle.net/m9DQR/2/
Ensures scrolls are done in multiples of 16 pixels. You can easily extend this to be a plugin that allows for a variable amount (not a fixed, magical 16).
Yes, this is possible, but it will require using javascript to capture the scroll event and then manipulate it. This script (sorry jQuery is what I had) and overrides the scroll event. It then replaces it with the exact same scroll distance. You could perform your own math to adjust the value of scrollTo. We have to check both mousewheel and DOMMouseScroll events because the first is not supported by FF. This doesn't seem to apply in your case, but a user may have the number of lines to scroll set to something other than the default three. So the if statement calculates the distance. I left it in there though in case other people stumble on this question and it is important to them though.
$('body').bind('mousewheel DOMMouseScroll', function(e) {
var scrollTo = null;
if (e.type == 'mousewheel') {
scrollTo = (e.wheelDelta * -1);
}
else if (e.type == 'DOMMouseScroll') {
scrollTo = 40 * e.detail;
}
//adjust value of scrollTo here if you like.
scrollTo = 16;
if (scrollTo) {
e.preventDefault();
$(this).scrollTop(scrollTo + $(this).scrollTop());
}
});
Coming from another programming language I also found JavaScript difficult when dealing with UI. In your case I would just set a handler to the event onscroll and query the position of the div relative to the scroll position. Return false whenever position of div is not divisible by 16px and create a counter to allow reposition after another 16px is scrolled.

Categories