在咱们工做中,js动画用的最多的可能就是:网站的滚动banner图片和电商网站的分层。这些动画原理是左右或上下移动位置的改变,要完成这些改变,咱们须要了解动画元素的三大位置系列:offset、scroll和client。javascript
offset是指html中定位了的元素,相对于它一样定位了的父级元素才存在的。若是一层一层往上面找,父级元素都没有定位,则就直接找到body。offset返回的是数字(number),而且是只读的,相对而言的style.left/style.top 则返回的字符串(就是带有px单位的),能够进行修改。咱们在作动画的时候,最多的就是将offsetLeft赋值给style.left,要注意将加上单位‘px'。html
<script> obj.style.left = obj.offsetLeft + 'px'; </script
首先咱们来看看和offset有关的属性:offsetWidth、offsetHeight、offsetLeft、offsetTop、offsetParenthtml5
offsetWidth/offsetHeight 获取元素宽高,包括width/height + 2*border + 2* padding offsetLeft / offsetTop 获取元素相对于父元素的左/上距离,父元素必须是定位的。若是父元素没有定位,则直接相对于body元素 offsetParent 找到当前元素的定位父元素,没有则就是body元素
和scroll相关的属性都是在触发onscroll事件后才会存在的,因此和scroll相关的内容都是在document.onscroll里面。java
scrollWidth / scrollHeight 滚动元素的宽/高 width / height + 2* padding scrollTop / scrollLeft 滚动条移动的距离(也就是滚动后隐藏的部分) window.scrollTo(x,y)移动滚动条到什么坐标,通常设置为想要的左右
可是因为DTD的存在(html5后就没有DTD了)和IE浏览器的bug,使得scrollTop与scrollLeft存在了兼容性问题,最好是能封装一个函数解决兼容性问题。浏览器
<script> function scroll() { // 火狐、google、IE9+支持 if (window.pageYOffset !== undefined) { return { top: window.pageYOffset, left: window.pageXOffset } // 存在DTD的状况,ie低版本支持 } else if (document.compatMode == "CSS1comPat") { return { top: document.documentElement.scrollTop, left: document.documentElement.scrollLeft } } else { // 不存在DTD的状况,google支持 return { top: document.body.scrollTop, left: document.bodyscrollLeft } } } </script>
client主要有clientX与clientY两个属性,是js事件event的属性,用来判断事件发生时,鼠标距离浏览器左上角的距离。通常作的动画是和鼠标事件相关的,电商的放大镜效果和鼠标跟随效果。函数
闪动动画就是直接设置值,好比left = 100,width = 100 , top = 100 ,height = 100等。这种动画就没有过渡效果,直接跳到目标状态。动画
<script> obj.onclick = function animate(){ obj.style.left = 200 + 'px'; } </script>
匀速运动是设置一个步长(step)后,而后在定时器里面改变状态,达到目标位置结束。网站
<script> function animate(){ var timer = null; timer = setInterval(function(){ var target = 400; var step = target > obj.offsetLeft ? 10 : -10; obj.style.left = obj.offsetLeft + step + 'px'; },25); if(Math.abs(target - obj.offsetLeft) < Math.abs(step)){ obj.style.left = target; clearInterval(timer); } } </script>
缓动运动是设置一个会改变的步长(step),而后在定时器里面改变状态,知道步长变成0结束,但根据改变只会接近0而不会变成0,因此须要使用Math对象的ceil与floor方法。google
<script> var timer = null; function animate(){ timer = setInterval(function(){ var target = 400; var step = target > obj.offsetLeft ? Math.ceil((target - obj.offsetLeft)/10) : Math.floor((target-obj.offsetLeft)/10); obj.style.left = obj.offsetLeft + step + 'px'; },25); if(Math.abs(target - obj.offsetLeft) < Math.abs(step)){ obj.style.left = target; clearInterval(timer); } } </script>