?
Solved

Scroll DIV with viewport

Posted on 2009-02-19
3
Medium Priority
?
1,926 Views
Last Modified: 2012-06-27
Ok, so I have a two-column layout that looks something like this:

http://sandman.net/test/move_div.html

And as you can read on that page. I want the blue #side DIV to scroll along on the page WHEN the viewport "hits" it. I.e if I scroll the page 50px nothing will change, the DIV will scroll along with the viewport, but when the browser viewport "hits" it, it will scroll along, to make sure that it's always shown, when I scroll back up it should remain in it's current position.

If you don't understand, follow the instructions to look at the Apple Store, and you should get an idea on what I'd like.

Can this be done in CSS or does it require javascript? Please let me know. If it does equire javascript, please give me tips on how to solve it using jQuery, since that's the framework I'm using.
0
Comment
Question by:SandmanNet
  • 2
3 Comments
 
LVL 15

Expert Comment

by:Tomarse111
ID: 23679624
I'm not sure how to do this in Jquery but the method I use is as follows:

n.b. the <br>'s are theye for test purposes to make sure there is a scroll bar in the window. These can obviously be removed.

<div id="floatdiv" style="
position:absolute;
width:200px;height:50px;left:0px;top:0px;
padding:16px;background:#FFFFFF;
border:2px solid #2266AA">
!!CONTENT HERE!!
</div> 
 
<script type="text/javascript"><!--
var floatingMenuId = 'floatdiv';
var floatingMenu =
{
targetX: -250,
targetY: 10,
 
hasInner: typeof(window.innerWidth) == 'number',
hasElement: document.documentElement
&& document.documentElement.clientWidth,
 
menu:
document.getElementById
? document.getElementById(floatingMenuId)
: document.all
? document.all[floatingMenuId]
: document.layers[floatingMenuId]
};
 
floatingMenu.move = function ()
{
if (document.layers)
{
floatingMenu.menu.left = floatingMenu.nextX;
floatingMenu.menu.top = floatingMenu.nextY;
}
else
{
floatingMenu.menu.style.left = floatingMenu.nextX + 'px';
floatingMenu.menu.style.top = floatingMenu.nextY + 'px';
}
}
 
floatingMenu.computeShifts = function ()
{
var de = document.documentElement;
 
floatingMenu.shiftX =
floatingMenu.hasInner
? pageXOffset
: floatingMenu.hasElement
? de.scrollLeft
: document.body.scrollLeft;
if (floatingMenu.targetX < 0)
{
if (floatingMenu.hasElement && floatingMenu.hasInner)
{
// Handle Opera 8 problems
floatingMenu.shiftX +=
de.clientWidth > window.innerWidth
? window.innerWidth
: de.clientWidth
}
else
{
floatingMenu.shiftX +=
floatingMenu.hasElement
? de.clientWidth
: floatingMenu.hasInner
? window.innerWidth
: document.body.clientWidth;
}
}
 
floatingMenu.shiftY =
floatingMenu.hasInner
? pageYOffset
: floatingMenu.hasElement
? de.scrollTop
: document.body.scrollTop;
if (floatingMenu.targetY < 0)
{
if (floatingMenu.hasElement && floatingMenu.hasInner)
{
// Handle Opera 8 problems
floatingMenu.shiftY +=
de.clientHeight > window.innerHeight
? window.innerHeight
: de.clientHeight
}
else
{
floatingMenu.shiftY +=
floatingMenu.hasElement
? document.documentElement.clientHeight
: floatingMenu.hasInner
? window.innerHeight
: document.body.clientHeight;
}
}
}
 
floatingMenu.doFloat = function()
{
var stepX, stepY;
 
floatingMenu.computeShifts();
 
stepX = (floatingMenu.shiftX +
floatingMenu.targetX - floatingMenu.nextX) * .07;
if (Math.abs(stepX) < .5)
{
stepX = floatingMenu.shiftX +
floatingMenu.targetX - floatingMenu.nextX;
}
 
stepY = (floatingMenu.shiftY +
floatingMenu.targetY - floatingMenu.nextY) * .07;
if (Math.abs(stepY) < .5)
{
stepY = floatingMenu.shiftY +
floatingMenu.targetY - floatingMenu.nextY;
}
 
if (Math.abs(stepX) > 0 ||
Math.abs(stepY) > 0)
{
floatingMenu.nextX += stepX;
floatingMenu.nextY += stepY;
floatingMenu.move();
}
 
setTimeout('floatingMenu.doFloat()', 20);
};
 
// addEvent designed by Aaron Moore
floatingMenu.addEvent = function(element, listener, handler)
{
if(typeof element[listener] != 'function' ||
typeof element[listener + '_num'] == 'undefined')
{
element[listener + '_num'] = 0;
if (typeof element[listener] == 'function')
{
element[listener + 0] = element[listener];
element[listener + '_num']++;
}
element[listener] = function(e)
{
var r = true;
e = (e) ? e : window.event;
for(var i = element[listener + '_num'] -1; i >= 0; i--)
{
if(element[listener + i](e) == false)
r = false;
}
return r;
}
}
 
//if handler is not already stored, assign it
for(var i = 0; i < element[listener + '_num']; i++)
if(element[listener + i] == handler)
return;
element[listener + element[listener + '_num']] = handler;
element[listener + '_num']++;
};
 
floatingMenu.init = function()
{
floatingMenu.initSecondary();
floatingMenu.doFloat();
};
 
// Some browsers init scrollbars only after
// full document load.
floatingMenu.initSecondary = function()
{
floatingMenu.computeShifts();
floatingMenu.nextX = floatingMenu.shiftX +
floatingMenu.targetX;
floatingMenu.nextY = floatingMenu.shiftY +
floatingMenu.targetY;
floatingMenu.move();
}
 
if (document.layers)
floatingMenu.addEvent(window, 'onload', floatingMenu.init);
else
{
floatingMenu.init();
floatingMenu.addEvent(window, 'onload',
floatingMenu.initSecondary);
}
 
//--></script> <br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
test

Open in new window

0
 
LVL 15

Expert Comment

by:Tomarse111
ID: 23679652
Alternatively you can just do this using a fixed position div, but you dont get the same nice slide effect as if you were using JS:
<style type="text/css">
#nomove { position:fixed; left:0; top:50px; border: 1px #f00 solid;
 
 
}
</style>
<div id="nomove" >stay where you at</div> 
<div id="other">this moves </div>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br><br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
 
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
test

Open in new window

0
 
LVL 2

Accepted Solution

by:
SandmanNet earned 0 total points
ID: 23679655
I found a solutiuon with jQuery, and I'm posting it here
		$(document).ready(function() {
			var off = $("#side").offset();
		
			$(window).scroll(function(){
				var scroll = $(this).scrollTop();
				if (scroll > off.top){
					$("#side").css("padding-top", (scroll - off.top));
				} else {
					$("#side").css("padding-top", (scroll - off.top)+10);
				}
				
			});
		});

Open in new window

0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Find out what you should include to make the best professional email signature for your organization.
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
In this tutorial viewers will learn how to embed custom externally-hosted Google Fonts using the Google Font API in CSS Go to the Google Fonts website at google.com/fonts: Browse or search based on font properties or name to find a suitable font for…
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question