user2537093
user2537093

Reputation: 139

Stop DIV from crossing specified position

I need to stop #first and #second div from crossing the green line. The example will explain you everything.

http://jsfiddle.net/3QdJt/1/

It works good when I'm scrolling UP but when I go down DIVs are jumping.

HTML

<div id="first"></div>
<div id="second"></div>
<div id="donotcross"></div>

CSS

#donotcross {
    position: relative;
    width 500px;
    height: 5px;
    top: 487px;
    background: green;
}

#first {
    position: fixed;
    width: 50px;
    height: 50px;
    background: red;
    right: 20px;
    bottom: 50%;
    margin-bottom: 50px;
}

#second {
    position: fixed;
    width: 50px;
    height: 50px;
    background: yellow;
    right: 20px;
    bottom: 50%;
    margin-bottom: -50px;
}

jQuery

$(window).scroll(function () {
    windowPos = $(this).scrollTop();
    asd = $('#first').offset().top;
    tauto = 500 - windowPos;
     if(asd <= 500) { 
       $('#first').css('top', tauto);
       $('#second').css('top', 600 - windowPos);
   } 
   if (asd > 500 ){
       $('#first').css('top', 'auto');
       $('#second').css('top', 'auto');
   }
});

Upvotes: 0

Views: 245

Answers (2)

Miljan Puzović
Miljan Puzović

Reputation: 5820

It's much effective if you put everything inside one wrapper div.

<div id="wrapper">
    <div id="first"></div>
    <div id="second"></div>
</div>
<div id="donotcross"></div>

CSS

body {
    height: 2000px;
}

#donotcross {
    position: relative;
    width 500px;
    height: 5px;
    top: 487px;
    background: green;
}

#wrapper {
    position: fixed;
    width: 70px;
    height: 130px;
    background: gray;
    right: 20px;
    text-align: center;
    top: 50%;
}

#first {
    background: red;
    width: 50px;
    height: 50px;
    margin: 10px auto;
}

#second {
    background: yellow;
    width: 50px;
    height: 50px;
    margin: 0 auto;
}

This script will work with any height and top values of #wrapper (might be dynamic), and with any height and position of #donotcross (also might be dynamic).

    var start_p = $('#wrapper').offset().top - $('#wrapper').height()/2;
    $('#wrapper').css('top', $('#donotcross').offset().top + $('#donotcross').height());

    $(window).scroll(function () {
        var windowPos = $(this).scrollTop();
        var dnc = $('#donotcross').offset().top + $('#donotcross').height() - windowPos;
        if (start_p >= dnc) $('#wrapper').css('top', start_p);
        else $('#wrapper').css('top', dnc);
    });

http://jsfiddle.net/3QdJt/3/

Upvotes: 1

Fikri Marhan
Fikri Marhan

Reputation: 359

You need to check the windowPos variable instead of checking asd > 500. The jumping is caused by you moving the boxes to be over 500. So to avoid the jumping you might want to do this

$(window).scroll(function () {
    windowPos = $(this).scrollTop();
    asd = $('#first').offset().top;
    tauto = 500 - windowPos;
     if(asd <= 500) { 
       $('#first').css('top', tauto);
       $('#second').css('top', 600 - windowPos);
   } 
   if (windowPos > 500 ){
       $('#first').css('top', 'auto');
       $('#second').css('top', 'auto');
   }
});

Edited:

To achive sticky effect, I manually calculated the boxes position instead of using top:auto

    $(window).scroll(function () {

    var center = $(window).height() / 2;
    //the 50 is the the #first and #second offset diff divide by 2
    var firstBoxTop = center - 50;
    var secondBoxTop = center + 50;

    var windowPos = $(this).scrollTop();
    if((windowPos + firstBoxTop) < 500)  { 
        firstBoxTop = 500 - windowPos; 
    }
    if((windowPos + secondBoxTop) < 600) { 
        secondBoxTop = 600 - windowPos; 
    }
    $('#first').css('top', firstBoxTop);
    $('#second').css('top', secondBoxTop);
});

Upvotes: 1

Related Questions