HTML5技术

JS运动从入门到兴奋1 - 沫晴的前端世界(2)

字号+ 作者:H5之家 来源:H5之家 2016-07-16 11:00 我要评论( )

这里要说明一个知识点,在JS中用style只能获取行间样式。 不能获取css中的样式。这个时候我们用什么呢?下面的两个方法可以获取非行间样式,有兼容问题: 1 getComputedStyle:getComputedStyle(element,随意值(写

     这里要说明一个知识点,在JS中用style只能获取行间样式。 不能获取css中的样式。这个时候我们用什么呢?下面的两个方法可以获取非行间样式,有兼容问题:   

     1  getComputedStyle: getComputedStyle(element,随意值(写什么都可以,比如false)).attr:这个获取的是计算机计算后的样式,不能获取复合样式,只有标准浏览器支持IE6 7 8不兼容。

     2  currentStyle :currentStyle[attr],只有IE6 7 8兼容 ,可以获取非行间样式,还可以获取自定义样式。

     所以需要做一下兼容,我们可以封装成一个函数,如下:

function getStyle ( obj, attr ) { if(obj.currentStyle){ obj.currentStyle[attr] }else{ getComputedStyle( obj )[attr]; } } getStyle ( obj, attr ) { return obj.currentStyle?obj.currentStyle[attr] : getComputedStyle( obj )[attr]; }

//注意 IE下虽然没有opacity,但也能获取到opacity值,主要是因为
currentStyle的原因,它能读取到任何样式的值,哪怕不存在

所以对于透明度的改变,我们可以封装成如下的函数:

function startMove2(obj, iTarget, iSpeed) { clearInterval(iTimer); var iCur = 0; //用来存放当前的透明度值 iTimer = setInterval(function() { // iCur = getStyle( obj, 'opacity' ) * 100; // 因为getStyle取出来的是小数,乘以100, 是29.999900000045 这样的数,这样我们无法和iTarget进行判断,所以我们可以进行四舍五入,如下: iCur = Math.round(getStyle( obj, 'opacity' ) * 100); if (iCur == iTarget) { clearInterval(iTimer); } else { //对不同的浏览器进行分别处理 obj.style.opacity = (iCur + iSpeed) / 100; obj.style.filter = 'alpha(opacity='+ (iCur + iSpeed) +')'; } }, 30); }

这只是改变透明度的函数封装,要是能把透明度的封装函数和前面的运动封装函数,结合起来,不就能封装成一个可以改变透明度,也可以改变位置的函数了吗。。。。

那么依照我们的合并原则,找出两个封装函数的不同之处:

运动的属性不同(attr)

2 因为不同的属性处理不同,其实主要是透明度处理是有差别的,其他宽高改变位置改变其实都一样)这个时候的差别,可以采用判断来解决

 

// 还解决了解决了一个问题是因为之前只有一个定时器,现在因为有多个属性可以运动了,所以就不能只用一个定时器了去控制了,每个物体运动的时候就应该有自己的定时器,所以就把定时器就用obj.timer上,这样每个物体都不同啦。

function startMove(obj, attr, iTarget, iSpeed) { clearInterval(obj.iTimer); var iCur = 0; obj.iTimer = setInterval(function() { (attr == 'opacity') { iCur = Math.round(getStyle( obj, 'opacity' ) * 100); } else { iCur = parseInt(getStyle(obj, attr)); } if (iCur == iTarget) { clearInterval(obj.iTimer); } else { if (attr == 'opacity') { obj.style.opacity = (iCur + iSpeed) / 100; obj.style.filter = 'alpha(opacity='+ (iCur + iSpeed) +')'; } else { obj.style[attr] = iCur + iSpeed + 'px'; } } }, 30); } function getStyle(obj, attr) { if (obj.currentStyle) { return obj.currentStyle[attr]; } else { return getComputedStyle(obj, false)[attr]; } }

 

不过上面的函数,还是不能满足某些需求,比如我想要一个物体的两个属性同时运动,下面这样是实现不了的。

//下面的运动会清除掉上面的定时器 startMove(this, 'width', 200, 10); startMove(this, 'height', 200, 10);

那么怎么样实现这两个属性可以同时运动呢?这个时候我们可以考虑用json的格式

 


oDiv1.onclick = function() { startMove(this, { width : 200, height: 300 }, 10); } function startMove(obj, json, iSpeed) { clearInterval(obj.iTimer); var iCur = 0; obj.iTimer = setInterval(function() { ( var attr in json ) { var iTarget = json[attr];//把我们传进来的属性值赋给目标值 if (attr == 'opacity') { iCur = Math.round(getStyle( obj, 'opacity' ) * 100); } else { iCur = parseInt(getStyle(obj, attr)); } if (iCur == iTarget) { clearInterval(obj.iTimer); } else { if (attr == 'opacity') { obj.style.opacity = (iCur + iSpeed) / 100; obj.style.filter = 'alpha(opacity='+ (iCur + iSpeed) +')'; } else { obj.style[attr] = iCur + iSpeed + 'px'; } } } }, 30); } function getStyle(obj, attr) { if (obj.currentStyle) { return obj.currentStyle[attr]; } else { return getComputedStyle(obj, false)[attr]; } }

存在问题:上面的运动速度都是一样的,但是传进去的目标点是不一样的,这个时候就会有一个属性先到,那么运动就终止了。所以我们需要解决的是,当所有的属性都到达了目标点,才让运动终止。

解决:定义一个开关,每次运动前假设它是真的,在运动中,只要有一个属性没运动到终点,就把开关变成假,在循环外面进行判断,当所有属性都运动到终点了,开关肯定都是真的,就会清除定时器了。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

    【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

    2017-04-30 16:00

  • ABP入门系列(16)——通过webapi与系统进行交互 - 『圣杰』

    ABP入门系列(16)——通过webapi与系统进行交互 - 『圣杰』

    2017-04-25 09:04

  • Android -- 带你从源码角度领悟Dagger2入门到放弃(一) - 阿呆哥哥

    Android -- 带你从源码角度领悟Dagger2入门到放弃(一) - 阿呆哥哥

    2017-04-21 11:02

  • require.js入门 - 爱喝酸奶的吃货

    require.js入门 - 爱喝酸奶的吃货

    2017-04-14 13:05

网友点评
(