Link to home
Start Free TrialLog in
Avatar of SandmanNet
SandmanNet

asked on

Scroll DIV with viewport

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.
Avatar of Tomarse111
Tomarse111
Flag of United Kingdom of Great Britain and Northern Ireland image

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

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

ASKER CERTIFIED SOLUTION
Avatar of SandmanNet
SandmanNet

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial