在这个世界上,有些人解决的是大问题,有些人解决的是小问题,而TweenLite解决的就是一个小到不能再小的问题——缓动(Tween)。所谓缓动,是指在两种状态之间进行平滑的转换,包括缩小、放大、旋转和渐变等几种操作。无论是在web编程中,还是Android或iOS中,Tween一直有人去实践,有UI的地方,就有Tween。
本文的主题是要实现页面的平滑滚动,为何要在文章开头大肆讨论Tween呢?如果从无插件实现的角度,确实没有半毛钱关系,但是其实现的机理背后,就是Tween原理。
好了,回到主题吧。在浏览器的默认状态下,如果不开启浏览器的平滑滚动,浏览器的滚动条在鼠标滚轮滚动时,是一顿一顿的,根据鼠标滚轮的不同,每一顿滑动的具体是不一样的,仔细观察就会发现,鼠标滚轮滚动一个刻度,浏览器滚动条直接跳到对应的高度,中间没有任何过渡效果。Firefox在开启平滑滚动的时候,这种现象将会消失,滚轮滚动一个刻度时,滚动条平滑的滚到对应的位置,但是Firefox需要借助硬件支持这一功能。
对于一般网页,这种一顿一顿的现象并没有太大的影响。但是当网站需要借助滚到来实现某些效果的时候,例如视差滚动的时候,就会发现这种体验糟糕透了。而且如果页面平滑滚动,也会让人阅读更加舒服,不会有跳动的感觉。本文就用jQuery来实现这一效果。
前面提到的TweenLite是一个插件,可以从这里了解和获取。通过TweenLite实现的缓动效果,不单单是滚动条的缓动这么简单,你可以自己看它的一些案例。
但是在没有插件的情况下,如何来做到平滑效果呢?我们简单的分析一下。
首先,我们需要监听鼠标滚轮事件,鼠标滚轮滚动的时候,我们需要截获滚轮实际要滚动的距离,同时拦截滚轮事件,不允许机器默认的滚动动作,接着再用我们自己的代码实现对等距离的滑动,从而实现滑动的平滑。
具体代码如下:
var $window = jQuery(window); //Window object var scrollTime = 400; //Scroll time var scrollDistance = 300; //Distance. Use smaller value for shorter scroll and greater value for longer scroll var mobile_ie = -1 !== navigator.userAgent.indexOf("IEMobile"); function smoothScrollListener(event) { event.preventDefault(); var delta = event.wheelDelta / 120 || -event.detail / 3; var scrollTop = $window.scrollTop(); var finalScroll = scrollTop - parseInt(delta * scrollDistance); $('html,body').stop().animate({scrollTop: finalScroll},scrollTime); } if (!jQuery('html').hasClass('touch') && !mobile_ie) { if (window.addEventListener) { window.addEventListener('mousewheel', smoothScrollListener, false); window.addEventListener('DOMMouseScroll', smoothScrollListener, false); } }
首先,我们来看下上面的代码。先声明了三个变量,分别存储window对象,每次滚动滚轮一个刻度要多少时间,第三个变量定义每一个滚轮刻度滑动多长的距离。
其次,对滚轮事件进行监听。代码在末尾,使用addEventListener监听滚轮事件,当事件发生时,调用smoothScrollListener函数。
最后,实现平滑滚动。当监听到滚轮事件后,首先用preventDefault()阻止默认响应,浏览器本身的滚动被阻止,在这种情况下,即使你滚动滚轮,浏览器也不会滚动。接下来是计算,通过当前的滚动条位置,减去滚动刻度和刻度距离的计算值(有正负,正负即滚动的方向),得到应该滚动多少距离。最后,使用jQuery的animate实现这个距离的平滑滚动效果。
代码简单,但却需要经过长时间的思考才能获得,只有经常尝试,方能获得这些灵感。
2015-12-22 6160 jquery
非常感谢,您的方法简单易懂,又能了解逻辑!!!