Fixed positioning of divs between two points of scroll - javascript

I have seven boxes. First I want to scroll box1 normally. When box2 reaches the top of the viewport it should be fixed same as in the example. I have to animate (animations may be show/hide etc) some views when I scroll on box2 again and again (Maybe for two window height or X pixel height). After the completion of animations, I need to remove the fixed positioning and start scrolling the remaining boxes normally. Any help?
[ I may use the same fixed positioning for box4 or box5 again while scrolling ]
Example http://jsfiddle.net/z0yv9gox/
Here is by code
var winHit = $(window).height();
var winWid = $(window).width();
$('.box').css({'height':winHit+'px','width':winWid+'px'});
$(window).scroll(function(){
if ($(this).scrollTop() > winHit) {
$('.box2').addClass('fixed');
}
else{
$('.box2').removeClass('fixed');
}
});
.box{height:200px;}
.box1{background:#333}
.box2{background:#ccffff;}
.box3{background:#999}
.box4{background:#ffcccc}
.box5{background:#666}
.box6{background:#999}
.box7{background:#333}
.fixed{position:fixed; top:0; left:0; z-index:2; width:100%;}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
<div class="box box4"></div>
<div class="box box5"></div>
<div class="box box6"></div>
<div class="box box7"></div>
Thanks in advance.

So if I am understanding you correctly I think you will want to put the box you want to fix inside of another div and relatively position that div and give it the height of how far you want your fixed box to travel (In my example I give it 300vh in css but if you want to add this height by javascript like in your above example you can). Then you will want to fix your box once the window gets to the top of your relatively positioned parent box. That way when you travel the required distance you can add another class the gives your fixed box an absolute position again this time placed on the bottom of your relatively positioned parent box. You will need 2 if statements for this and also you will need to calculate the height of your parent box and your fixed box. Then once the top of the window hits the top of your fixed box holder you add the fixed class and when the scroll position hits the fixed box holders height minus your fixed box's height you can add another class sticking it to the bottom of that div. If I am misunderstanding your question please let me know in the comments below.
Ok so I know that may have been kind of confusing so here it is in action along with a fiddle I worked up.
Fiddle Demo
$(window).on('scroll', function(){
var windowTop = $(window).scrollTop();
$('.fixed-box-holder').each(function(){
var boxTop = $(this).offset().top;
var boxHolderHeight = $(this).height();
var fixedBox = $(this).children('.fixed-box');
var boxHeight = fixedBox.height();
var boxStop = boxHolderHeight - boxHeight;
if (windowTop >= boxTop) {
fixedBox.addClass('fixed');
}else{
fixedBox.removeClass('fixed');
}
if(windowTop >= boxTop + boxStop){
fixedBox.addClass('scrolled');
}else{
fixedBox.removeClass('scrolled');
}
});
});
body{margin:0;}
.box{
height:100vh;
color:#fff;
}
.fixed-box-holder{
position:relative;
height:300vh;
}
.fixed-box{
position:absolute;
top:0;
left:0;
width:100%;
background:blue;
}
.fixed{
position:fixed;
z-index:1;
}
.scrolled{
position:absolute;
top:auto;
bottom:0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box" style="background:#333;">First Box</div>
<div class="fixed-box-holder">
<div class="box fixed-box">Fixed Box</div>
</div>
<div class="box" style="background:#444;">Second Box</div>
<div class="box" style="background:#555;">Third Box</div>
<div class="box" style="background:#666;">Fourth Box</div>
<div class="fixed-box-holder">
<div class="box fixed-box">Fixed Box</div>
</div>
<div class="box" style="background:#777;">Fifth Box</div>
<div class="box" style="background:#888;">Sixth Box</div>
<div class="box" style="background:#999;">Seventh Box</div>
PS on slower machines you may have some issues with smoothness as this will be a lot of calculations on the fly especially if you are going to be adding animations as well so just keep that in mind.

Related

How to find the boundary of child Divs

Im trying to right align the Title on top of the last Div. As per the below image , the text should be on top of "Hello 5 / 4 / 3". When we resize the window button will float which is working and the text should be always be on top of the last button.
Unsure why the wrapper div is adding extra space to the right of the button and not aligning to the edge of the right most div. Extra space is coming even if the Title is not there , any insights about Div width calculation would be great.
I tried calculating the number of buttons in the top row using javascript and added offset to the title , but it seems tedious and not aligning at certain resolution.
http://jsbin.com/nonexegiqa/embed?html,css,console,output
HTML
<div class="wrapper">
<div class="title">Title</div>
<div class="clear"/>
<div class="btn">Hello 1</div>
<div class="btn">Hello 2</div>
<div class="btn">Hello 3</div>
<div class="btn">Hello 4</div>
<div class="btn">Hello 5</div>
<div class="btn">Hello 6</div>
<div class="clear"/>
</div>
CSS
.wrapper{
border:solid gray 1px;
}
.btn{
width:96px;
height:46px;
float:left;
border:solid gray 1px;
margin-left : 11px;
margin-bottom : 11px;
text-align:center;
}
.title{
float:right;
}
.clear{
clear:both;
}
You need to find count of .btn in first row when page resizing, Then set position of .title to last .btn in first row.
$(window).on("resize", function(){
var parWidth = $(".wrapper").innerWidth();
var chiWidth = $(".wrapper .btn").first().outerWidth(true);
var childCount = 0;
while(parWidth >= chiWidth){
parWidth -= chiWidth;
childCount ++;
}
var left = $(".btn:eq("+(childCount-1)+")").position().left;
$(".title").css("margin-left", left);
});
To better understanding, i create demo but because you can't change demo page size in here, i create it in JSFiddle.
yes, display:flex may be very helpful. As a work around you could set the width of the .wrapper to 70vw, or something similar. The .wrapper div width is creating the "extra space."

Absolute effect in fixed position

Based on this code:
HTML:
<div style="width:1000px;height:1000px;">
<div id="box1" class="box" style="left:20px;top:20px;">
My position-x is fixed but position-y is absolute.
</div>
<div id="box2" class="box" style="left:20px;top:120px;">
My position-x is absolute but position-y is fixed.
</div>
<div id="box3" class="box" style="left:20px;top:220px;">
Im positioned fixed on both axis.
</div>
</div>
CSS:
.box
{
width:400px;
height:80px;
background:gray;
position:fixed;
}
JS:
$(window).scroll(function(){
//box one
var $win = $(window);
$('#box1').css('top', 20 -$win.scrollTop());
$('#box2').css('left', 20 -$win.scrollLeft());
});
If I give the css directly in css not in the js, how can I still make it work the same way ?
Fiddle
Hate to say it but it's not possible in plain CSS2,3.

How do I stop an inheritly positioned element from jumping up page when I change the div above it to fixed?

Okay so I have a page that uses javascript to fix the header to the top of the page (thus removing the banner) when you scroll past the bottom of the banner (about 200px down page).
On this website I've been using containers that have the position:inherit; property set to contain each part of the page. These then have a relatively positioned element inside them so I can place all my absolutely positioned elements where I like.
My problem is that id="content" keeps jumping to the top of the page when the javascript changes id="header" to position:fixed;
See here: www.obsojb.com
I have tried absolutely positioning id="content" and setting it's top value but it wouldn't work and I'm a bit stuck.
Here is a very simplified version of the HTML:
<body>
<div id="page"> <!--inherit-->
<a id="banner"></a> <!--inherit-->
<div id="header"> <!--inherit-->
<div id="lang"> <!--relative-->
<ul>...</ul> <!--inherit-->
<other divs> <!--absolute-->
</div>
<div id="nav"> <!--relative-->
<ul>..</ul> <!--inherit-->
<a id="userbutton"></a> <!--absolute-->
</div>
</div
<div id="content0"> <!--inherit-->
<div id="content"> <!--relative-->
<PAGE CONTENT> <!--absolute-->
</div>
</div>
<div id="footer"></div>
</div>
</body>
Here is my javascript:
var bannerheight // Glob var
window.onload = function() {
window.bannerheight = $('#bannerimg').height();
checkOffset();
};
window.onscroll = function(oEvent) {
checkOffset();
}
function checkOffset() {
if (window.pageYOffset >= window.bannerheight) {
document.getElementById("header").style.position = "fixed";
document.getElementById("banner").style.display = "none";
document.getElementById("padding").style.height = window.bannerheight+"px";
}
else {
document.getElementById("header").style.position = "inherit";
document.getElementById("banner").style.display = "block";
document.getElementById("padding").style.height = "0px";
}
}
and here is the relevant CSS:
#page {
margin:0px auto;
}
#lang {
position:relative;
}
#nav {
position:relative;
margin:0px auto;
}
#content0 {
height:800px;
}
#content {
position:relative;
margin:0px auto;
}
Try giving the content div a "margin-top" and set it to the number of pixels that the page is "jumping". Then when you scroll up and reset the position, undo the margin-top back to zero.
I've tested this and it solved my jumping issue.
I'm not sure what you expect as output but position: fixed works on the document, globally. It not only ignores element flow (like position: absolute) but it also ignores scrolling.
position: absolute is relative to it's offset parent which can be an item with position: relative.
You typically only want to use position: fixed if something needs to stick to the window, like a little popup that scrolls with as you go down the page. The Facebook header is a good example. Their header bar is fixed to the top of the window and stays there even if you scroll.

How to get the div top position value while scrolling

I am trying to run some script when div reaches to a certain point when it's scrolled. There is a fixed navigation and when the user scrolls the window it suppose change the nav name once it reaches close to the nav. I am using the $(window).scroll function but it only checking the div position once and not updating the value. How to make scroll check the window size every 5-10 px move so that it doesn't take too much memory/processing.
The code is set up at: http://jsfiddle.net/rexonms/hyMxq/
HTML
<div id="nav"> NAVIGATION
<div class="message">div name</div>
</div>
<div id="main">
<div id="a">Div A</div>
<div id ="b"> Div B</div>
<div id ="c"> Div C</div>
</div>​
CSS
#nav {
height: 50px;
background-color: #999;
position:fixed;
top:0;
width:100%;
}
#main{
margin-top:55px;
}
#a, #b, #c {
height:300px;
background-color:#ddd;
margin-bottom:2px;
}
SCRIPT
$(window).scroll(function() {
var b = $('#b').position();
$('.message').text(b.top);
if (b.top == 55) {
$('.message').text("Div B");
}
});​
Try this jsFiddle example
$(window).scroll(function() {
var scrollTop = $(window).scrollTop(),
divOffset = $('#b').offset().top,
dist = (divOffset - scrollTop);
$('.message').text(dist);
if (b.top == 55) {
$('.message').text("Div B");
}
});​
Your original code was only checking the position of the div relative to the top of the document which never changes. You need to calculate in the amount of scroll the window has incurred and calculate accordingly.
Also note the difference beyween jQuery's .position() and .offset() methods. The .position() method allows us to retrieve the current position of an element relative to the offset parent. Contrast this with .offset(), which retrieves the current position relative to the document.

Align Text to Left and Vertically Center in div

I have this JS code that I use to create a new div (I create several, dynamically). I want my text to be in the centered vertically and aligned to the left side of the div. Any suggestions on what to do? Here is my code:
var leftDiv = document.createElement("div"); //Create left div
leftDiv.id = "left"; //Assign div id
leftDiv.setAttribute("style", "float:left;width:70%;vertical-align:middle; height:26px;"); //Set div attributes
leftDiv.style.background = "#FFFFFF";
leftDiv.style.height = 70;
user_name = document.createTextNode(fullName + ' '); //Set user name
One other thing. This code will center the text horizontally and it seems to gravitate to the top of the div instead of the middle.
If the height of div is constant (seems like it is 70px) than you can use line-height: 70px; to render any text vertically centered.
<style type="text/css">
#myoutercontainer { position:relative }
#myinnercontainer { position:absolute; top:50%; height:10em; margin-top:-5em }
</style>
...
...
<div id="myoutercontainer">
<div id="myinnercontainer">
<p>Hey look! I'm vertically centered!</p>
<p>How sweet is this?!</p>
</div>
</div>
Set margin-top:-yy where yy is half the height of the child container to offset the item up.
Source : http://www.vanseodesign.com/css/vertical-centering/
It is not possible to vertical align text inside div with out making it table cell, or you have to insert a span inside div & give it 50% height.
Check below code.
http://jsbin.com/agekuq/edit#preview
<div
id="left"
style="background:red;
display:table-cell;
width:150px;
height:150px;
vertical-align:middle;"
> My full name</div>

Categories

Resources