app项目上需要做一个小的活动,先看下页面布局

需求是这5个板块逐个展示,展示一块的时候,页面整体向上滚动一定的距离。

刚开始考虑的时候,是准备依赖css3属性的transition实现的,包括顺序延迟都没有任何问题,可是等到真正实现的时候,发现无法监听每一个模块展示之后,实现滚动条的滚动。(或者是因为我没有考虑到怎么监听吧)

然后剩下的一条路就是setInterval和setTimeout了,首先想到的是setInterval,因为有多个模块嘛,逐一展示,自然是开启间隔定时器(setInterval)了,执行中,发现两个问题,一个是无法在合适的时候,关闭定时器了;第二个问题是,直接操作滚动条滚动的话,没有缓动效果,看起来特别生硬的感觉。

第一个问题,很容易解决了,替换成延时定时器setTimeout,每一个模块延迟不一样的时间,就解决了逐一展示的问题。

操作滚动条,需要缓动效果,就比较坑了。

讨论了很久,发现,如果直接操作页面滚动条的话,是没有办法实现缓动的。不得已,转换思路:

缓动,只有运动函数和css的animation,transition才有缓动函数,那么就是定方案了。

采用运动函数的话,肯定需要定位,那么页面的自带的滚动条可能就没法使用了。

css方案的话,需要根据子元素的滚动,来实现类似于整个document.body的向上滚动,也是一大痛点。

最终决定采用css方案,配合延迟定时器,每展示一个模块,类似于document.body的盒模型,我采用了一个.main整个包裹了所有元素,所以我这里向上滑动的就是.main,

.main向上滑动的距离等于每个模块需要滑动的距离乘以当前元素的序号。

$('.main').css({
    'transform': '-webkit-translateY(-'+ 80 * i+ 'px)',
    'transform': 'translateY(-'+ 80 * i+ 'px)',
    'transition': '-webkit-transform 800ms ease-in-out',
    'transition': 'transform 800ms ease-in-out'
});

当所有模块都展示之后,这里其实采用了一个偷懒的方法,实在是没有找到怎么监听最后一个模块已经展示完全的方案。

setTimeout(function(){
    $(document.body).click();
}, 5200);

  其实就是再开启一个延迟定时器,在5200ms之后,触发其他需要的事件。

由于需要一个触发点,所以在5200ms之后,用js模拟了一次页面点击事件,在这个点击事件内部实现所有需要完成的工作。

$(document.body).on('click', function(){
    $('.main').css({
        'transform': '-webkit-translateY(0)',
         'transform': 'translateY(0)',
         'transition': '-webkit-transform 0ms steps(1)',
         'transition': 'transform 0ms steps(1)'
    });
    $('.content').scrollTop(320);
});

  为了不影响页面滚动条的滑动,必须将向上的位移重置为0, 并且偷偷的把滚动条滚动到当前的位置。

这里transition的使用有一个技巧,从当前的位移,回到0,必须一步完成,不能让用户从效果上看出来页面在来回滚动,所以用到了steps(1)的属性,而且在0ms之内。

到这里,基本完成需求了,但是当我在操作页面的时候,又发现了一点问题,就是当模块还没有完全展示的时候,用户滑动了页面,结果看起来就不那么友好了。

所以采用了模块没有展示的时候,禁用触屏滑动的事件,等到页面模拟点击事件的时候,再放开触屏滚动的事件。

$(document.body).on('touchmove.move',function(e){
    e.preventDefault();
    e.stopPropagation();
});

 放开触屏事件: 

$(document.body).off('touchmove.move')

  基本完成需求了。叫做打完收工。

posted on 2016-12-22 11:40  烛火星光  阅读(606)  评论(0编辑  收藏  举报