Check if element is into view and add class if so

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?


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>

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>
链接地址: http://www.djcxy.com/p/83540.html

上一篇: 等待元素显示给用户

下一篇: 检查元素是否在视图中,如果是,则添加类