3

I'd like to stack elements and when they come into view, it adds the class .active. I don't want the class to be removed, so once it's added it stays there.

General idea:

If .default is in view on scroll add the class .active

So as you scroll down it adds the class when it comes into view.

After looking at similar questions I've come up with this: http://jsfiddle.net/x05vwb28/

$(window).scroll(function() {
    if (checkVisible($('.default'))) {
        $('.default').addClass('active');
    } 
});

function checkVisible( elm, eval ) {
    eval = eval || "visible";
    var vpH = $(window).height(), // Viewport Height
        st = $(window).scrollTop(), // Scroll Top
        y = $(elm).offset().top,
        elementHeight = $(elm).height();

    if (eval == "visible") return ((y < (vpH + st)) && (y > (st - elementHeight)));
    if (eval == "above") return ((y < (vpH + st)));
}

It half works... When scrolled it adds the active class to all elements instead of only to the one in view.

I'd like the first div to automatically add the class of active (because it's already in view)

And if I'm honest, as much as it kind of works... I don't understand the function.

Is there an easier way to do this?

Spokey
  • 10,974
  • 2
  • 28
  • 44
Nick
  • 2,261
  • 5
  • 33
  • 65
  • The second link on "jquery isvisible" search in google http://stackoverflow.com/questions/8774089/detect-if-an-element-is-visible – mattfetz Feb 05 '15 at 00:04
  • Not trying to be rude but you've not read my question. – Nick Feb 05 '15 at 00:08
  • Guys, it's not about if an element is visible or hidden, it's about if the element is in the view area of the window. – Spokey Feb 05 '15 at 00:08
  • What I'm a little confused on is how the hell your coding is working at all without any sort of return statement in the function. – Jhecht Feb 05 '15 at 00:22
  • There are actually 2 returns there, one never gets called tho. @Jhecht. – Spokey Feb 05 '15 at 00:30
  • I missed those in reading over it. I was about to call witchcraft. Thanks for pointing those out @Spokey – Jhecht Feb 05 '15 at 00:31

2 Answers2

2

The problem with the way your code runs now is that by passing $('.default') to the function it means that you are applying the class to all divs if any of the divs are visible, which is not what you want.

What you have to do is filter out the divs that are not in view and append the class to the ones that are.

$(window).scroll(function() {
    $('.default').filter(checkVisible).addClass('active');
    // select divs then filter them based on view 
}).scroll();

function checkVisible() {
    var elm = this;
    var eval = eval || "visible";
    var vpH = $(window).height(), // Viewport Height
        st = $(window).scrollTop(), // Scroll Top
        y = $(elm).offset().top,
        elementHeight = $(elm).height();

    if (eval == "visible") return ((y < (vpH + st)) && (y > (st - elementHeight)));
    // if (eval == "above") return ((y < (vpH + st))); you don't really need this
}
.default {width: 500px; height: 500px; margin: 0 0 20px 0; float: left; border: 2px solid black;}
.div1.active {background: url('http://a1.dspnimg.com/data/l/423341110329_Qy737Vid_l.jpg');}
.div2.active {background: url('http://a1.dspnimg.com/data/l/509084866423_rd0gX45i_l.jpg');}
.div3.active {background: url('http://a1.dspnimg.com/data/l/78223608549_WRxtYYPS_l.jpg');}
.div4.active {background: url('http://fc05.deviantart.net/fs71/f/2010/265/b/4/pink_and_blue_clouds_500x500_by_prodigy42-d2zaii3.jpg');}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<div class="default div1"></div>
<div class="default div2"></div>
<div class="default div3"></div>
<div class="default div4"></div>
Spokey
  • 10,974
  • 2
  • 28
  • 44
0

Does this do what you are trying to do? It's a pretty quick and dirty solution that could probably stand to be cleaned up, but I got it to work. Or at least, I got it to work how I understood your question.

$(document).ready(function() {
  var vp_height = $(window).height();
  $(document).on('scroll', function() {
    scroll_height = $(document).scrollTop();
    viewport_bottom = vp_height + scroll_height;
    var visible = $('body>div').filter($filter_inview).addClass('active');
    $('body>div').not(visible).removeClass('active');
  });
});

function $filter_inview(i, el) {
  var el = $(el);
  return (el.offset().top > scroll_height && el.offset().top < viewport_bottom)
}
 body>div {
   height: 300px;
   width: 100%;
 }
 body>div.active {
   border: 1px solid red;
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Hello There, Number 1</div>
<div>Hello There, Number 2</div>
<div>Hello There, Number 3</div>
<div>Hello There, Number 4</div>
<div>Hello There, Number 5</div>
Jhecht
  • 4,407
  • 1
  • 26
  • 44