...

View Full Version : how to create absolute, and then fixed div?



think123
10-08-2011, 08:24 AM
Hello everyone!

I just thought this might require some javascript, so I posted this here. Anyway, how do I create an element that is absolutely positioned first, and then, when it goes to the top of the page, it becomes fixed?

Thanks
Lucas

ironboy
10-08-2011, 12:23 PM
Try:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
* {margin:0; padding:0}
html, body {height:10000px}
.sticky {height:100px;width:100px;background:#900;position:absolute;top:300px;left:100px}
#s2 {left:300px;top:350px;background:#090}
#s3 {left:500px;top:325px;background:#009}
</style>
<script>
onload = function(){
// get the sticky elements
// - right now we choose all elements with the class sticky
var stickies = $('.sticky');
// find their original top pos
var tops = [];
for(var i = 0; i < stickies.length;i++){
tops.push(findPos(stickies[i]).top)
};
// switch between "sticky" and "normal" mode for stickies
// depending on scroll position and their original position
onscroll = function(){
var i, s, inView, scrollTop = window.pageYOffset
|| (document.documentElement && document.documentElement.scrollTop)
|| (document.body && document.body.scrollTop);
for(i = 0; i < stickies.length;i++){
inView = scrollTop - tops[i] < 0;
s = stickies[i].style;
s.position = inView ? '' : 'fixed'
s.top = inView ? '' : 0;
}
};
};

// ppk:s excellent position finder
var findPos = function (el) {
var curleft = curtop = 0;
do {
curleft += el.offsetLeft;
curtop += el.offsetTop;
}
while (el = el.offsetParent);
return {left:curleft,top:curtop};
};

// ironboy: a minimal selector engine (for use in teaching)
// if you're using jQuery you can remove this function
var $ = function (sel){
sel = '* {display:block !important; position:absolute !important;'
+ ' left:0}\n' + sel + ' {left:-10050px !important}';
var d = document, style = d.createElement('style');
style.type = 'text/css';
style.styleSheet ? (style.styleSheet.cssText = sel) :
style.appendChild(d.createTextNode(sel));
d.getElementsByTagName('head')[0].appendChild(style);
var elsAll = d.getElementsByTagName('*'), els = [];
for(var i = 0; i < elsAll.length; i++){
elsAll[i].offsetLeft < -10000 && els.push(elsAll[i]);
};
style.parentNode.removeChild(style);
els.each = function(func){
for(var i = 0; i < this.length;i++){func.call(this[i])}
};
return els
};
</script>
</head>
<body>
<div class="sticky"></div>
<div id="s2" class="sticky"></div>
<div id="s3" class="sticky"></div>
</body>
</html>

Sciliano
10-08-2011, 01:09 PM
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>None</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">

var floatContainer = "";
var trigger = "";
var staticLeft = "";
var IE = navigator.appName == "Microsoft Internet Explorer" ? true : false;
var IE6 = /.+MSIE 6.+/.test(navigator.appVersion);

function stayHome(){

var nScrollTop = document.documentElement.scrollTop;
if (nScrollTop >= trigger)
{
if (IE6)
{
floatContainer.style.top = nScrollTop - trigger + "px";
floatContainer.style.left = "5px";
}
else {
floatContainer.style.position = "fixed";
floatContainer.style.left = staticLeft - 2 + "px";
floatContainer.style.top = "2px";
}
}
else {
floatContainer.style.position = "relative";
floatContainer.style.styleFloat = "left";
if (!IE6)
{
floatContainer.style.left = "3px";
}
floatContainer.style.top = "0px";
}
}

function init(){

var nDiv = document.getElementsByTagName('div');
for (i=0; i<nDiv.length; i++)
{
if (nDiv[i].className == "semi_float_container")
{
floatContainer = nDiv[i];
staticLeft = floatContainer.offsetLeft;
}
if (nDiv[i].className == "header")
{
trigger = nDiv[i].clientHeight + nDiv[i].offsetTop;
}
}
setInterval("stayHome()", 150);
}

IE ? attachEvent('onload', init, false) : addEventListener('load', init, false);

</script>
<style type="text/css">

body
{
background-color: #d3d3d3;
margin: 0px;
padding: 0px;
}

.header
{
float: left;
width: 95%;
height: 225px;
margin-left: 12px;
margin-top: 15px;
margin-bottom: 5px;
border: 1px solid black;
background-color: #e6b280;
}

.content_container
{
float: left;
height: 1300px;
width: 75%;
border: 1px solid black;
margin-left: 12px;
background-color: #fffacd;
}

.semi_float_container
{
float: left;
width: 19%;
height: 300px;
margin-left: 5px;
border: 1px solid black;
background-color: #90ee90;
}

</style>
</head>
<body>
<div class="header"></div>

<div class="content_container"></div>

<div class="semi_float_container">Notice This Container</div>

</body>
</html>

ironboy
10-08-2011, 01:14 PM
@Sciliano:
That does not seem to work outside IE (at least not in Chrome or Safari).
Also, in IE it's a little 'bouncy'...

Logic Ali
10-08-2011, 03:29 PM
@Sciliano:
That does not seem to work outside IE (at least not in Chrome or Safari).
Also, in IE it's a little 'bouncy'...

I made a couple of small changes which should address those issues.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>None</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">

var floatContainer = "";
var trigger = "";
var staticLeft = "";
var IE = navigator.appName == "Microsoft Internet Explorer" ? true : false;
var IE6 = /.+MSIE 6.+/.test(navigator.appVersion);

function stayHome()
{

var nScrollTop = document.documentElement.scrollTop || window.pageYOffset;
if (nScrollTop >= trigger)
{
if (IE6)
{
floatContainer.style.top = nScrollTop - trigger + "px";
floatContainer.style.left = "5px";
}
else {
floatContainer.style.position = "fixed";
floatContainer.style.left = staticLeft - 2 + "px";
floatContainer.style.top = "2px";
}
}
else {
floatContainer.style.position = "relative";
floatContainer.style.styleFloat = "left";
if (!IE6)
{
floatContainer.style.left = "3px";
}
floatContainer.style.top = "0px";
}


}

function init(){

var nDiv = document.getElementsByTagName('div');
for (i=0; i<nDiv.length; i++)
{
if (nDiv[i].className == "semi_float_container")
{
floatContainer = nDiv[i];
staticLeft = floatContainer.offsetLeft;
}
if (nDiv[i].className == "header")
{
trigger = nDiv[i].clientHeight + nDiv[i].offsetTop;
}
}
// setInterval("stayHome()", 150);
}

IE ? attachEvent('onload', init, false) : addEventListener('load', init, false);

IE ? attachEvent('onscroll', stayHome, false) : addEventListener('scroll', stayHome, false);

</script>
<style type="text/css">

body
{
background-color: #d3d3d3;
margin: 0px;
padding: 0px;
}

.header
{
float: left;
width: 95%;
height: 225px;
margin-left: 12px;
margin-top: 15px;
margin-bottom: 5px;
border: 1px solid black;
background-color: #e6b280;
}

.content_container
{
float: left;
height: 1300px;
width: 75%;
border: 1px solid black;
margin-left: 12px;
background-color: #fffacd;
}

.semi_float_container
{
float: left;
width: 19%;
height: 300px;
margin-left: 5px;
border: 1px solid black;
background-color: #90ee90;
}

</style>
</head>
<body>
<div class="header"></div>

<div class="content_container"></div>

<div class="semi_float_container">Notice This Container</div>

</body>
</html>

DaveyErwin
10-08-2011, 04:52 PM
tested in google chromr, fire fox and ie7 on windows xp



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="generator" content="daveyerwin">
<title>Untitled</title>
<script type="text/javascript">
var atof;
var flag = true;
var stor;
function fixit(){
var ot = (window.pageYOffset || document.documentElement.scrollTop);
if(ot > atof.offsetTop && flag){
flag = false;
stor = ot;
atof.style.top = 0;
atof.style.position="fixed";
}
if(ot < stor && !flag){
flag = true;
atof.style.position="absolute";
atof.style.top = null;
}
}
function init(){
atof=document.getElementById("atof");
}
</script>

<style type="text/css">
#atof{position:absolute;bottom:0;}
</style>
</head>
<body onscroll="fixit()" onload="init()">
<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>
<div id="atof"><p>hiyas</p></div>
</body>
</html>


EDIT
another example...
tested in ie7, ie9, chrome(webkit) and firefox
i had to make a little change
in the onscroll attatching
to make it
work in ie9



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta name="generator" content="daveyerwin">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>IIS7</title>
<style type="text/css">

body {
color:#000000;
background-color:#B3B3B3;
margin:0;
}

#container {
position:relative;
height:2000px;
}

#atof {
position:absolute;
top:100px;
background-color:red;
height:2em;
}
</style>
<script type="text/javascript">

var atof;
var stor;
var flag=true;
function fixit(){
var ot = (window.pageYOffset || document.documentElement.scrollTop);
if(ot > atof.offsetTop && flag){
flag = false;
stor = ot;
atof.style.position="fixed";
atof.style.top = "0px";

}
if(ot < stor && !flag){
flag = true;
atof.style.position="absolute";
atof.style.top = null;
}
}
function init(){
atof=document.getElementById("atof");
window.onscroll=fixit;
}
</script>

</head>
<body onload="init();">
<div id="container"><div id="atof">
<p>hiyas</p>
</div></div>
</body>
</html>

ironboy
10-08-2011, 06:01 PM
@DaveyErwin:
That didn't do much (at least not in webkit browsers...)... :confused:

@All:
The code I posted works without glitches and cross browser.
So unless someone has anything better I suggest using it :cool:

[EDIT]
@LogicalAli: Indeed, you fixed Sciliano's script. Well done!
(It still contains browser detection though - don't like the code smell of that.)

Logic Ali
10-08-2011, 06:16 PM
@All:
The code I posted works without glitches and cross browser.
So unless someone has anything better I suggest using it :cool:

I just fixed what I saw wrong even though it wasn't the way I would have done it.
You might want to look again at this statement:



scrollTop = window.pageYOffset
|| (document.documentElement && document.documentElement.scrollTop);

ironboy
10-08-2011, 07:52 PM
@LogicalAli:
Yep, and you did a good job! :) Didn't mean to criticize you

B.t.w.
Why do you think I should look at that?
(Do you want me to include quirksmode support? ;))


EDIT
Alright I'll do that (although IE6 is dead):


scrollTop = window.pageYOffset
|| (document.documentElement && document.documentElement.scrollTop)
|| (document.body && document.body.scrollTop);

Logic Ali
10-08-2011, 08:14 PM
EDIT
Alright I'll do that (although IE6 is dead):


scrollTop = window.pageYOffset
|| (document.documentElement && document.documentElement.scrollTop)
|| (document.body && document.body.scrollTop);You're missing the point;

window.pageYOffset if supported evaluates to an integer.


(document.documentElement && document.documentElement.scrollTop)
|| (document.body && document.body.scrollTop)
evaluates to a boolean.

ironboy
10-08-2011, 08:16 PM
Nope it doesn't :)

Try this for yourself

alert(true && 2)

Logic Ali
10-08-2011, 10:21 PM
Nope it doesn't :)

Try this for yourself

alert(true && 2)
So it does. I didn't know that ANDing non-integers evaluates to the last operand.

ironboy
10-08-2011, 10:56 PM
:D Can be quite useful, the same goes for OR:ing:



alert(false || 3);

think123
10-09-2011, 05:04 AM
thanks guys!



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum