一、场景

使用 window.onscroll 进行滚动,从而对某些动画进行触发。

动画可能使用两种形式进行控制,一种是 css animation 控制的动画,通过 class 进行触发,另外一种是通过 js 控制的动画。

两者遇到的问题有这些:

  • 需要判断元素进入视觉区域之后才能进行动画的触发
  • 动画仅需要进行一次

二、视觉区域的控制

关于视觉区域的控制,我之前也写过一篇文章:

主要使用的函数如下:

/**
 * 判断是否在当前窗口内
 */
function isInSign(elem) {
    const elemRect = elem.getBoundingClientRect(),
        windowHeight = window.innerHeight || document.body.clientHeight;
    if (elemRect.top < windowHeight) {
        return true;
    }
    return false;
}

三、只进行一次动画

只进行一次动画,可以通过 class 进行控制,把已经执行完动画的元素添加一个 class 用来标识已经完成,比如:

(我下面的代码因为业务需要,如果没有传入 dom ,则把 window.onscroll 置为 null

/**
 * onscroll 只触发一次
 */
function onlyOnceScroll(dom){
    // 给所有需要滚动的内容加上一个 done class 用来标识滚动结束
    if(dom){
        $(dom).addClass('done');
        return false;
    }else{
        // 如果没有传入dom 直接将 window.onscroll 赋值为空
        window.onscroll = null;
    }
}

在进行动画滚动之前,先判断是否存在 class ,如果存在 done 这个 class,则不进行动画

不管是 css3 animation 还是 js 控制动画, 都可以这么操作:

// 页面滚动 数字跳动
    window.onscroll = function(){
        // 将 done 这个class排除掉
        $(".num-item .count-num").not('.done').each(function(){
            var _this = this;
            if(isInSign(this)){
                $(this).numberRock({
                    speed:$(this).attr('speed'),
                    count:$(this).attr('count'),
                    callback:function(){
                        $(_this).text($(_this).attr('count'));
                    }
                });
                // 追加 done class
                onlyOnceScroll(_this);
            }
        });
    }