function getStyle(obj,name){ //獲取非行間樣式函數 if(obj.currentStyle){ return obj.currentStyle[name]; //兼容ie系列 }else{ return getComputedStyle(obj,false)[name]; //兼容火狐和chrome } } function startMove(obj,json,fn){ //運動框架 clearInterval(obj.timer); //定時器先清後開 obj.timer=setInterval(function(){ var bStop=true; //用於檢測每項運動是否完成的標識 for(var attr in json){ var cur=0; //變量cur用來存放獲取到的現有樣式值 if(attr=='opacity'){ //獲取現有樣式,不透明度和其餘樣式分開 cur=Math.round(parseFloat(getStyle(obj,attr))*100); }else{ cur=parseInt(getStyle(obj,attr)); } var iSpeed=(json[attr]-cur)/6; //緩衝運動計算速度 iSpeed=iSpeed>0?Math.ceil(iSpeed):Math.floor(iSpeed); //判斷向上或向下取整 if(cur!=json[attr]){ //若每次循環有未達到目標的項目,設置爲false bStop=false; } cur+=iSpeed; //物體運動函數 if(attr=='opacity'){ obj.style.filter='alpha(opacity='+cur+')' obj.style.opacity=cur/100; }else{ obj.style[attr]=cur+'px'; } } if(bStop==true){ //當bStop爲true時才結束循環 clearInterval(obj.timer); if(fn){fn();} //鏈式運動函數 } },30) }
簡單說一下chrome
用getStyle函數獲取對象現有的樣式,由於直接使用offset獲取對象樣式存在bug,offset獲取的是包含content的width,padding和border的盒子模型寬度,而style.width設置的僅僅是包含content的width值,不含padding和border。當對象有border和padding值時會形成運動效果錯誤。json
運動函數startMove包含三個參數,分別是obj--需添加運動效果的對象;json--運動對象改變的樣式及數值;fn--回調函數(可選)。對象運動時改變的樣式名和數值是以json的方做爲參數傳入,能夠通知改變多個值。框架
運動過程依然是用計時器實現的,setInterval前必定要保證先clearInterval,防止多個定時器同時開啓。函數
定義bStop變量,用於肯定當多個運動同時發生時,檢測每一個運動事件是否完成,如有爲完成的運動,值設爲false,肯定全部運動完成即bStop值爲true時,中止計時器clearInterval中止運動。佈局
for in循環出獲取到的對象樣式,存在變量cur中。加個獲取樣式判斷,若獲取的是opacity,opacity*100並四捨五入取整,如果其餘樣式,加上px。網站
緩衝運動的速度採用的是對象樣式的(目標值-現有值)再除以任意數字,數字越大運動速度越慢。由於現有值在不斷變化,因此越接近目標值速度越慢,達到緩衝的目的。速度須要作判斷,如果正向運動,(目標值-現有值)結果爲正,向上取整,如果反向運動,(目標值-現有值)結果爲負,想下取整。spa
cur與速度進行疊加運算後賦值給obj.style,實現運動效果。code
判斷回調函數fn是否存在,若存在則執行fn();
對象具體的調用方式以下:事件
startMove(obj,{'width':500,'height':500,'opacity':0.5});
注意:改變寬高和定位的時候不須要加px,函數會自動給加上。
以上就是一個較爲完美的運動框架,加上佈局後調用能夠實現各大網站上主流的焦點圖,輪播圖的運動效果以及其餘一些運動效果。歡迎你們吐槽,相互交流~O(∩_∩)O~