滚动到视图中时将类添加到元素(可滚动的div)

时间:2014-10-01 11:20:41

标签: javascript jquery html css

是否有解决方案在滚动时向视图中的元素添加类,并在视图外删除?这需要适用于可滚动的div。到目前为止,我找到了一些解决方案,但它们似乎只适用于身体...而不是可滚动的div。

如果您知道某个插件存在,我很乐意使用它。像这样......

if ($('.journal-slider .each-slide img').inViewport() ) {
    $(this).addClass('in-view');
} else {
   $('.journal-slider .each-slide img').removeClass('in-view');
}

谢谢, [R

3 个答案:

答案 0 :(得分:2)

您要查找的插件名为waypoints

来自“开始使用”的引用:

“假设你有一个带溢出的div:滚动,你想在这个可滚动元素中有一个航点。上下文选项让你这样做。滚动下面的框。”

$('#example-context').waypoint(function() {
    notify('Hit top of context');
}, { context: '.example-scroll-div' });

编辑:不使用航路点

根据你已经做过的事情,我来到了这个:

function  checkInView(elem,partial)
{
    var container = $(".scrollable");
    var contHeight = container.height();
    var contTop = container.scrollTop();
    var contBottom = contTop + contHeight ;
 
    var elemTop = $(elem).offset().top - container.offset().top;
    var elemBottom = elemTop + $(elem).height();

    var isTotal = (elemTop >= 0 && elemBottom <=contHeight);
    var isPart = ((elemTop < 0 && elemBottom > 0 ) || (elemTop > 0 && elemTop <= container.height())) && partial ;

    return  isTotal  || isPart ;
}

$(document).ready(function(){
$(".scrollable").scroll(function(){
    var result="",result2="";
   $.each( $(".scrollable p"),function(i,e){
       if (checkInView($(e),false)) {
           $( this ).addClass( "red" );
       } else {
           $( this ).removeClass( "red" );
       }
        result += " " +  checkInView($(e),false);
       result2 += " " +  checkInView($(e),true);
    });
    $("#tt").text(result);
    $("#kk").text(result2);
});
});
.scrollable{
    margin:10px;
    height:100px;
    overflow-y:scroll;
}
p
{
    border-width:1px;
    border-color:black;
    border-style:solid;
}
.red {
    background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
full:  <div id="tt"></div>
part: <div id="kk"></div>
<div class="scrollable">
    <p>item1<span></span></p>
    <p>item2<span></span></p>
    <p>item3<span></span></p>
    <p>item4<span></span></p>
    <p>item5<span></span></p>
    <p>item6<span></span></p>
    <p>item7<span></span></p>
    <p>item8<span></span></p>
</div>

答案 1 :(得分:2)

您可以制作自己的jQuery插件来执行此操作。这样的东西需要两个函数(whenInView,whenNotInView):

$('.journal-slider .each-slide img').inViewport(
    function(){$(this).addClass("am-in-view");},
    function(){$(this).removeClass("am-in-view");}
);

它测试滚动(或调整大小)目标元素当前在视口内并调用相关函数。

以下是演示片段的全部内容。在这个例子中,我已经为.am-in-view类添加了一个动画,以便您可以看到它在元素进入视口时工作。到目前为止,尚未对除Chrome之外的任何内容进行测试。随意使用和改进。

/*! inViewport 0.0.1 
 *  jQuery plugin by Moob
 * ======================== 
 *  (requires jQuery) 
 */  
(function ($) {

    var vph=0;
    function getViewportDimensions(){
        vph = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
    }
    getViewportDimensions();    
    //on resize/scroll
    $(window).on('resize orientationChanged', function(){
        getViewportDimensions();
    });            
    
    $.fn.inViewport = function (whenInView, whenNotInView) {                  
        return this.each(function () {
            var el = $(this),
                inviewalreadycalled = false,
                notinviewalreadycalled = false;                            
            //on resize/scroll
            $(window).on('resize orientationChanged scroll', function(){
                checkInView();
            });               
            function checkInView(){
                var rect = el[0].getBoundingClientRect(),
                    t = rect.top,
                    b = rect.bottom;
                if(t<vph && b>0){
                    if(!inviewalreadycalled){
                        whenInView.call(el);
                        inviewalreadycalled = true;
                        notinviewalreadycalled = false;
                    }
                } else {
                    if(!notinviewalreadycalled){
                        whenNotInView.call(el);
                        notinviewalreadycalled = true;
                        inviewalreadycalled = false;
                    }
                }
            }
            //initial check
            checkInView();                
        });
    }             
}(jQuery));
html, body {
    margin:0;
}
.me, .not-me {
    padding:20px;
    border:1px solid #aaa;
    margin:20px;
}
.am-in-view {
    background-color:pink;
    -webkit-transition: all 1500ms;
    -moz-transition: all 1500ms;
    -o-transition: all 1500ms;
    transition: all 1500ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="me">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eveniet, pariatur.</p>
    <p>Saepe, eligendi nihil totam dolorum reprehenderit! Repellat omnis neque quasi.</p>
    <p>Eos cumque voluptatum placeat eius nisi facere neque nesciunt praesentium.</p>
    <p>Eos qui consectetur voluptatem eum, labore accusamus tempora distinctio sunt?</p>
</div>
<div class="me">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Excepturi, sit.</p>
    <p>A veritatis quis quae totam accusamus repellendus adipisci corporis soluta.</p>
    <p>Debitis animi dolor distinctio ratione dolorum ex aperiam maiores fugit?</p>
    <p>Incidunt non consequatur porro provident recusandae sunt architecto repellat enim.</p>
</div>
<div class="me">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, reprehenderit?</p>
    <p>Neque tempora perferendis dolor, mollitia debitis sunt voluptas ea ut!</p>
    <p>Maiores earum officia corporis, sint voluptatem, in laboriosam perferendis asperiores?</p>
    <p>Odit dolor voluptate laboriosam voluptatem accusamus aperiam explicabo at provident.</p>
</div>
<div class="not-me">
    <p>I'm totally normal</p>
</div>
<div class="me">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam, accusamus.</p>
    <p>Quisquam architecto repellat facere amet sapiente dolore obcaecati harum fuga.</p>
    <p>Tempora labore, unde necessitatibus ipsam repellat architecto, aliquam autem at.</p>
    <p>Sapiente quis doloremque a illum, repellat, eius corporis ab placeat.</p>
</div>
<div class="me">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptate, assumenda!</p>
    <p>Nesciunt corrupti, eaque dolores ut libero ipsam dolorem laudantium saepe.</p>
    <p>Similique quisquam quod esse expedita, voluptate quia nobis? Cum, tempore.</p>
    <p>Amet voluptatem eaque non, praesentium tenetur molestias minima architecto laboriosam?</p>
</div>
<div class="me">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore, ex?</p>
    <p>Perferendis hic, sint maxime similique quia autem cum quasi? Sed.</p>
    <p>Nemo ratione aliquid itaque est blanditiis aliquam maiores veniam ab!</p>
    <p>Reiciendis cumque fugit earum ea animi et aut molestiae dolores!</p>
</div>

<!-- how to call it -->
<script>
    $(function(){
      
        $('.me').inViewport(
            function(){$(this).addClass("am-in-view");},
            function(){$(this).removeClass("am-in-view");}
        );
      
    });
</script>

答案 2 :(得分:0)

其中offset是元素与屏幕的偏移量。你应该使用scroll事件来调用它(throttles),反复检查元素是否在视图中。

function isElementInViewport(el, offset){
        var rect = el.getBoundingClientRect();
        offset = offset || 0;

        return (
            rect.top - offset >= 0 &&
            rect.left >= 0 &&
            rect.bottom + offset <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
            rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
        );
 }

onscroll事件一起使用:

// utilizing underscore's `debounce` method
$(window).on('scroll.checkVisibility', _.debounce(check, 200));

function check(){
    var visibility = isElementInViewport(element, -100);
    if( visibility )
       // do something if visisble

}