本文實例講述了JS實現滑動門效果的方法。分享給大家供大家參考,具體如下:
描述:鼠標移動到一副圖片上,會顯示該副圖片的全貌,而其他圖片會顯示概貌,效果圖如下:
一、沒有動畫效果的運動
思路:
1.定好每張圖片的初始位置(第一張完全顯示,234只露出一部分)
2.計算每道門的移動距離(即未顯露的部分)
3.綁定鼠標滑過事件
window.onload=function(){ var box=document.getElementById("box"); var img=box.getElementsByTagName("img"); //單張圖片寬度 var imgWidth=img[0].offsetWidth; //露出的寬度 var exposeWidth=160; //設置容器總寬度 var boxWidth=imgWidth+exposeWidth*(img.length-1) box.style.width=boxWidth+"px"; //設置圖片初始位置 function setImgspos(){ for(var i=1,len=img.length;i<len;i++){ //len在for循環的初始化語句裡先定義好,這樣就不需要每次都計算img的個數了,比for(var i=1;i<img.length;i++)性能高 img[i].style.left=imgWidth+exposeWidth*(i-1)+"px"; } } setImgspos(); //計算每道門打開時應移動的距離 var translate=imgWidth-exposeWidth; for(var i=0,len=img.length;i<len;i++){ (function(i){ //這裡為什麼需要匿名函數?(簡單來說是函數變量作用域的問題)img[i].onmouseover=function(){}這個函數內部使用了變量i,但是i沒有定義,於是向外查找,找到for循環裡定義的i,點擊事件是for循環執行完畢後才開始執行的,即此時i=4,所以會報錯img[i]沒有定義,這裡加一層匿名函數相當於閉包處理,i以形參的方式傳遞給內層函數 img[i].onmouseover=function(){ setImgspos(); //每次移上去先重置位置 for(var j=1;j<=i;j++){ //第二個循環體作用:可能會移多道門(比如放到第三道門上,二和三都要動,不是只動三,另外第一道門永遠不動) img[j].style.left=parseInt(img[j].style.left)-translate+"px"; } }; })(i); //這個i是實參 } };
二、展開加速、收攏減速的運動
注意:設置每道門初始位置時,不需要在寫一個function了,因為要分別寫打開和關閉動畫,會造成一個卡頓,瞬間閃爍。
思路:
1.需要鼠標滑過這道門的初始位置
2.需要鼠標滑過這道門的結尾位置
3.需要一個速度和定時器來完成緩緩移動的過程
window.onload=function(){ var box=document.getElementById("box"); var img=box.getElementsByTagName("img"); //單張圖片寬度 var imgWidth=img[0].offsetWidth; //露出的寬度 var exposeWidth=160; //設置容器總寬度 var boxWidth=imgWidth+exposeWidth*(img.length-1) box.style.width=boxWidth+"px"; //設置圖片初始位置 for(var i=1,len=img.length;i<len;i++){ img[i].pos=img[i].style.left=imgWidth+exposeWidth*(i-1)+"px"; } function openDoor(el,translate){ var begin=parseInt(el.pos); var end=begin-translate; var iSpeed=10; setTimeout(function(){ el.style.left=parseInt(el.style.left)-iSpeed+"px"; //為什麼不用begin?每次的初始位置會變 iSpeed*=1.5; //沒有這句話就是勻速運動 if(parseInt(el.style.left)<=end){ el.style.left=end+"px"; }else{ setTimeout(arguments.callee,25); //定時器有名字可以直接調用,沒名字,就用原生js方法arguments.callee } },25); }; function closeDoor(el,translate){ var begin=parseInt(el.pos)-translate; //關門默認情況是張開的 var end=begin+translate; //這裡可以直接寫var end=parseInt(el.pos); var iSpeed=100; setTimeout(function(){ el.style.left=parseInt(el.style.left)+iSpeed+"px"; //為什麼不用begin?每次的初始位置會變 iSpeed=Math.ceil(iSpeed*0.7); //沒有這句話就是勻速運動 if(parseInt(el.style.left)>=end){ el.style.left=end+"px"; }else{ setTimeout(arguments.callee,25); //定時器有名字可以直接調用,沒名字,就用原生js方法arguments.callee } },25); }; var translate=imgWidth-exposeWidth; for(var i=0,len=img.length;i<len;i++){ (function(i){ img[i].onmouseover=function(){ //開門 自己和自己左邊的全部循環到 for(var j=1;j<=i;j++){ openDoor(img[j],translate); } //關門 自己右邊的全部循環到 for(var j=i+1;j<img.length;j++){ closeDoor(img[j],translate); } }; })(i); } };
更多關於JavaScript相關內容感興趣的讀者可查看本站專題:《JavaScript切換特效與技巧總結》、《JavaScript圖形繪制技巧總結》、《JavaScript查找算法技巧總結》、《JavaScript動畫特效與技巧匯總》、《JavaScript錯誤與調試技巧總結》、《JavaScript數據結構與算法技巧總結》、《JavaScript遍歷算法與技巧總結》及《JavaScript數學運算用法總結》
希望本文所述對大家JavaScript程序設計有所幫助。