PC端網頁特效
1.元素偏移量offset系列
· 獲得元素距離帶有定位父元素的位置
· 獲得元素自身的大小(寬度高度)
· 注意:返回的數值都不帶單位
offset 系列常用屬性
<script type="text/javascript"> var father = document.querySelector('.father'); var son = document.querySelector('.son'); //1.可以得到元素的偏移位置 返回的不帶單位的數值 console.log(father.offsetTop);//它以帶有定位的父級為準,如果沒有父級或者父級沒有定位 則以body為準 console.log(son.offsetLeft); //2.可以得到元素的大小 寬度和高度 是包含padding + border + width console.log(father.offsetWidth); //3.返回帶有定位的父級,否則返回的是body console.log(son.offsetParent);//返回帶有定位的父級,否則返回的是body console.log(son.parentNode);//返回最近一級的父級 不管父級有沒有定位 </script>
1.2 offset 與style區別
拖動的模態框 案例
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> *{ padding: 0; margin:View Code0; } .login-header{ text-align: center; margin: 200px 0 0; } .login{display: none; width: 512px; height: 280px; position: fixed; border: 1px solid #ebebeb; left: 50%; top: 50%; background: #fff; box-shadow: 0px 0px 20px #ddd; z-index: 9999; transform: translate(-50%,-50%); cursor: move; } .login-title{ width: 100%; margin: 10px 0 0 0; text-align: center; line-height: 40px; height: 40px; } .login-input-content{ margin-top: 20px; } .login-button{width: 50%; margin: 30px auto 0; line-height: 40px; font-size: 14px; border: 1px solid #EBEBEB; text-align: center; } .login-bg{ display: none; width: 100%; height: 100%; position: fixed; top: 0; left: 0; background: rgba(0,0,0,.3); } a{ text-decoration: none; color: #000; } .login-button a{ display: block; } .login-input input.list-input{ float: left; line-height: 35px; height: 35px; width: 350px; border: 1px solid #EBEBEB; text-indent: 5px; } .login-input{ overflow: hidden; margin: 0 0 20px; } .login-input label{ float: left; width: 90px; padding-right: 10px; text-align: right; line-height: 35px; height: 35px; font-size: 14px; } .login-title span{ position: absolute; font-size: 12px; right: -20px; top: -30px; background-color: #FFFFFF; border: 1px solid #ebebeb; width: 40px; height: 40px; border-radius: 20px; } </style> </head> <body> <div class="login-header"><a id="link" href="javascript:;">點選,彈出登陸框</a></div> <div id="login" class="login"> <div id="title" class="login-title"> 登入會員<span><a href="" id="closeBtn" class="close-login">關閉</a></span> </div> <div class="login-input-content"> <div class="login-input"> <label>使用者名稱:</label> <input type="text" id="username" placeholder="請輸入使用者名稱" name='info[username]' class="list-input" /> </div> <div class="login-input"> <label>登入密碼:</label> <input type="password" placeholder="請輸入登入密碼" name="info[password]" id="password" class="list-input"/> </div> </div> <div id="loginBtn" class="login-button"><a href="javascript:void(0)" id="login-button-submit">登入會員</a></div> </div> <!--遮蓋層--> <div id="bg" class="login-bg"></div> <script type="text/javascript"> //1.獲取元素 var link = document.querySelector('#link'); var login = document.querySelector('#login'); var closeBtn = document.querySelector('#closeBtn'); var bg = document.querySelector('#bg'); var title = document.querySelector('#title'); link.addEventListener('click',function(){ login.style.display = 'block'; bg.style.display = 'block'; }) closeBtn.addEventListener('click',function(){ login.style.display = 'none'; bg.style.display = 'none'; }) // 當滑鼠頂部標題欄按下,獲得滑鼠在盒子內的座標 title.addEventListener('mousedown',function(e){ //獲取滑鼠在盒子內的座標x,y var x = e.pageX - login.offsetLeft; var y = e.pageY - login.offsetTop; //當滑鼠移動 把滑鼠在頁面中的座標 減去 滑鼠在盒子內的座標 就是模態框的座標 document.addEventListener('mousemove',move) function move(e){ // login.style.left = e.pageX - x +'px'; login.style.top = e.pageY - y +'px'; } //滑鼠彈起,就讓滑鼠移動事件移除 document.addEventListener('mouseup',function(){ document.removeEventListener('mousemove',move); }) }) </script> </body> </html>
仿京東放大鏡效果 案例
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .preview_img{ position: relative; width: 300px; height: 300px; } .proImg{ width: 100%; height: 100%; } .mask{ display: none; position: absolute; top: 0; left: 0; width: 200px; height: 200px; background: #f5e59f; opacity: .5; } .big{ display: none; position: absolute; top: 0; left: 310px; width: 500px; height: 500px; z-index: 999; overflow: hidden; border: 1px solid #eee; } .big img{ position: absolute; top: 0; left: 0; } </style> </head> <body> <div class="preview_img"> <img src="../img/proImg.jpg" class="proImg"/> <div class="mask"></div> <div class="big"><img src="../img/bigImg.jpg" alt="" class="bigImg"/></div> </div> <script type="text/javascript"> var preview = document.querySelector('.preview_img'); var mask = document.querySelector('.mask'); var big = document.querySelector('.big'); //當滑鼠經過 就顯示和隱藏 mask遮擋層 和big 大圖片層 preview.addEventListener('mouseover',function(){ mask.style.display = 'block'; big.style.display = 'block'; }) preview.addEventListener('mouseout',function(){ mask.style.display = 'none'; big.style.display = 'none'; }) //滑鼠移動的時候,讓黃色盒子跟著滑鼠走 preview.addEventListener('mousemove',function(e){ //先計算出滑鼠在盒子內的座標 var x = e.pageX - preview.offsetLeft; var y = e.pageY - preview.offsetTop; //減去盒子高度的一半 就是mask最終left和top值 var maskx = x - mask.offsetWidth / 2 ; var masky = y - mask.offsetHeight / 2 ; var maskMax = preview.offsetWidth - mask.offsetWidth; if(maskx <= 0){ maskx = 0; }else if(maskx >= maskMax){ maskx = maskMax; } if(masky <= 0){ masky = 0; }else if(masky >= preview.offsetHeight - mask.offsetHeight){ masky = preview.offsetHeight - mask.offsetHeight; } mask.style.left = maskx +'px'; mask.style.top = masky +'px'; //大圖片的移動距離 = 遮擋層移動距離 * 大圖片最大移動距離 / 遮擋層的最大移動距離 var bigImg = document.querySelector('.bigImg'); //大圖最大移動距離 var bigMax = bigImg.offsetWidth - big.offsetWidth; //大圖的移動距離x y var bigImgx = maskx * bigMax / maskMax; var bigImgy = masky * bigMax / maskMax; bigImg.style.left = -bigImgx + 'px'; bigImg.style.top = -bigImgy + 'px'; }) </script> </body> </html>View Code
2. 元素可視區client系列
client系列屬性
clientWidth與offsetWidth最大的區別就是不包含邊框
淘寶flexible.js原始碼分析
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>
1.立即執行函式(function(){})()
立即執行函式:不需要呼叫,立馬能夠自己執行的函式。
主要作用:建立一個獨立的作用域。避免了命名衝突問題。
2.寫法:
① (function(){})()或者
② (function(){}());
<script type="text/javascript"> //1.立即執行函式:不需要呼叫,立馬能夠自己執行的函式 //2.寫法 也可以傳遞引數進來 //(function(){})() 或者 (function(){}()); (function(a,b){ console.log(a + b); var num = 10; })(1,2);//第二個小括號可以看做是呼叫函式 (function(a,b){ console.log(a + b); var num = 10;//區域性變數 }(2,3)); //3.立即執行函式最大的作用 獨立建立了一個作用域 裡面所有變數都是區域性變數 不會有命名衝突情況 </script>
pageshow事件(重新載入頁面觸發)
跟load事件不同的是 pageshow這個事件在頁面顯示時觸發,無論頁面是否來自快取。在重新載入頁面中,
pageshow會在load事件觸發後觸發;根據事件物件中的presisted來判斷是否是快取中的頁
面觸發的pageshow事件,注意這個事件給window新增。
(function flexible (window, document) { //獲取html的根元素 var docEl = document.documentElement //dpr 物理畫素比 var dpr = window.devicePixelRatio || 1 // adjust body font size 設定body字型大小 function setBodyFontSize () { //如果頁面中有body這個元素 就設定body的字型大小 if (document.body) { document.body.style.fontSize = (12 * dpr) + 'px' } else { //如果頁面中沒有body這個元素,則等頁面主要DOM元素載入完畢後設置字型大小 document.addEventListener('DOMContentLoaded', setBodyFontSize) } } setBodyFontSize(); // set 1rem = viewWidth / 10 設定html元素的文字大小 function setRemUnit () { var rem = docEl.clientWidth / 10 docEl.style.fontSize = rem + 'px' } setRemUnit() // reset rem unit on page resize 當頁面尺寸大小發生變化的時候,要重新設定下rem的大小 window.addEventListener('resize', setRemUnit) //pageshow 是重新載入頁面觸發的事件 window.addEventListener('pageshow', function (e) { //e.persisted 返回的是true 如果頁面是從快取取過來的頁面 也需要重新計算一下rem大小 if (e.persisted) { setRemUnit() } }) // detect 0.5px supports 有些移動端瀏覽器不支援0.5畫素的寫法 if (dpr >= 2) { var fakeBody = document.createElement('body') var testElement = document.createElement('div') testElement.style.border = '.5px solid transparent' fakeBody.appendChild(testElement) docEl.appendChild(fakeBody) if (testElement.offsetHeight === 1) { docEl.classList.add('hairlines') } docEl.removeChild(fakeBody) } }(window, document))flexible註釋詳解
3.元素滾動scroll系列
scroll系列屬性
頁面被捲去的頭部:可以通過window.pageYOffset 獲得 如果是被捲去的左側 window.pageXOffset
元素被捲去不透 是element.scrollTop,如果是頁面被捲去頭部 則是window.pageYOffset
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .slider-bar{ position: absolute; left: 50%; top: 300px; margin-left: 600px; width: 45px; height: 130px; background-color: pink; } .w{ width: 1200px; margin: 10px auto; } .header{ height: 150px; background-color: purple; } .banner{ height: 250px; background-color: skyblue; } .main{ height:1000px; background-color:yellowgreen; } span{ display: none; position:absolute; bottom:0; } </style> </head> <body> <div class="slider-bar"><span class="goback">返回頂部</span></div> <div class="header w">頭部區域</div> <div class="banner w">banner區域</div> <div class="main w">主體部分</div> <script type="text/javascript"> var sliderbar = document.querySelector('.slider-bar'); var goback = document.querySelector('.goback'); var banner = document.querySelector('.banner'); var main = document.querySelector('.main'); //bannerTop 就是被捲去頭部的大小 一定要寫到滾動的外面 var bannerTop = banner.offsetTop; var sliderbarTop = sliderbar.offsetTop; var mainTop = main.offsetTop; //頁面滾動事件scoll document.addEventListener('scroll',function(){ //window.pageYOffset 頁面被捲去的頭部 if(window.pageYOffset> bannerTop){ sliderbar.style.position = 'fixed'; sliderbar.style.top = sliderbarTop - bannerTop + 'px'; }else{ sliderbar.style.position = 'absolute'; sliderbar.style.top = sliderbarTop + 'px'; console.log(sliderbarTop); } //當頁面滾動到main盒子 就顯示goback模組 if(window.pageYOffset > mainTop){ goback.style.display = 'block'; }else{ goback.style.display = 'none'; } }) </script> </body> </html>仿淘寶固定側邊欄
頁面被捲去的頭部 有相容性問題,因此被捲去的頭部通常有以下幾種寫法:
① 聲明瞭DTD,使用document.documentElement.scrollTop
② 未宣告DTD,使用document.body.scrollTop
③ 新方法window.pageYOffset 和 window.pageXOffset,IE9開始支援
三大系列對比
他們主要用法:
① offset系列經常用於獲得元素位置 offsetLeft offsetTop
② client經常用於獲取元素大小 clientWidth clientHeight
③ scroll經常用於獲取滾動距離 scrollTop scrollLeft
mouseenter 和 mouseover的區別
· 當滑鼠移動到元素上時就會觸發mouseenter事件
· mouseover 滑鼠經過自身盒子會觸發,經過子盒子還會觸發。mouseenter 只經過自身盒子觸發
· 因為mouseenter 不會冒泡
4.動畫函式封裝
4.1 動畫實現原理
核心原理:通過定時器setInterval()不斷移動盒子位置。
動畫物件一定要加定位
<script type="text/javascript"> //動畫原理 //① 獲得盒子當前位置 //② 讓盒子在當前位置加上1個移動距離 //③ 利用定時器不斷重複這個操作 //④ 加一個結束定時器的條件 //⑤ 注意此元素需要新增定位,才能使用element.style.left var div = document.querySelector('div'); var timer = setInterval(function(){ if(div.offsetLeft >= 400){ clearInterval(timer); } div.style.left = div.offsetLeft + 1 + 'px'; },30) </script>
4.2 動畫函式簡單封裝
注意函式需要傳遞2個引數,動畫物件和移動到的距離。
<script type="text/javascript"> //var obg = {}; //obg.name = 'andy'; //簡單動畫函式封裝obj目標物件 target 目標位置 function animate(obg,target){ //當我們不斷的點選按鈕,這個元素的速度會越來越快 因為開啟了太多的定時器 //解決方案就是 讓元素只有一個定時器執行 clearInterval(obj.timer); obj.timer = setInterval(function(){ if(obg.offsetLeft >= target){ clearInterval(timer); } obg.style.left = obg.offsetLeft + 1 + 'px'; },30) } var btn = document.querySelector('button'); btn.addEventListener('click',function(){ animate(span,400); }) animate(div,300); </script>
4.4緩動效果原理
緩動動畫公式:(目標值 - 現在的位置) / 10 作為每次移動的距離步長
勻速動畫 就是 盒子當前的位置 + 固定的值 10
緩動動畫 就是 盒子當前的位置 + 變化的值(目標值 - 現在的位置)/10
<button class="btn800">點選夏雨湖到800</button> <button class="btn300">點選夏雨湖到300</button> <div></div> <span></span> <script type="text/javascript"> //var obg = {}; //obg.name = 'andy'; var span = document.querySelector('span'); var div = document.querySelector('div'); //簡單動畫函式封裝obj目標物件 target 目標位置 function animate(obj,target){ //當我們不斷的點選按鈕,這個元素的速度會越來越快 因為開啟了太多的定時器 //解決方案就是 讓元素只有一個定時器執行 clearInterval(obj.timer); obj.timer = setInterval(function(){ //緩動動畫公式:(目標值 - 現在的位置) / 10 作為每次移動的距離步長 //把步長值改為整數 不要出現小數問題 var step = (target - obj.offsetLeft) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); if(obj.offsetLeft == target){ clearInterval(obj.timer); } //把每次加1 這個步長值改為一個慢慢變小的值 obj.style.left = obj.offsetLeft + step + 'px'; },40) } var btn800 = document.querySelector('.btn800'); var btn300 = document.querySelector('.btn300'); btn800.addEventListener('click',function(){ animate(span,800); }); btn300.addEventListener('click',function(){ animate(span,300); }) //勻速動畫 就是 盒子當前的位置 + 固定的值 10 //緩動動畫 就是 盒子當前的位置 + 變化的值(目標值 - 現在的位置)/10 </script>
4.6 動畫函式添加回調函式
回撥函式原理:函式可以作為一個引數。將這個函式作為引數傳到另一個函式裡面,當那個函式執行完之後,再執行穿進去的這個函式,這個過程叫回撥
回撥函式 寫到定時器結束裡面
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> div{ width: 200px; height: 200px; background-color: pink; position: absolute; } span{width: 300px; height: 300px; background-color: purple; position: absolute; } </style> </head> <body> <button class="btn800">點選夏雨湖到800</button> <button class="btn300">點選夏雨湖到300</button> <div></div> <span></span> <script type="text/javascript"> //var obg = {}; //obg.name = 'andy'; var span = document.querySelector('span'); var div = document.querySelector('div'); //簡單動畫函式封裝obj目標物件 target 目標位置 function animate(obj,target,callback){ //當我們不斷的點選按鈕,這個元素的速度會越來越快 因為開啟了太多的定時器 //解決方案就是 讓元素只有一個定時器執行 clearInterval(obj.timer); obj.timer = setInterval(function(){ //緩動動畫公式:(目標值 - 現在的位置) / 10 作為每次移動的距離步長 //把步長值改為整數 不要出現小數問題 var step = (target - obj.offsetLeft) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); if(obj.offsetLeft == target){ clearInterval(obj.timer); //回撥函式寫到結束定時器裡面 if(callback){ callback(); } } //把每次加1 這個步長值改為一個慢慢變小的值 obj.style.left = obj.offsetLeft + step + 'px'; },40) } var btn800 = document.querySelector('.btn800'); var btn300 = document.querySelector('.btn300'); btn800.addEventListener('click',function(){ animate(span,800,function(){ span.style.backgroundColor = 'yellow'; }); }); btn300.addEventListener('click',function(){ animate(span,300,function(){ span.style.backgroundColor = 'yellow'; }) }) //勻速動畫 就是 盒子當前的位置 + 固定的值 10 //緩動動畫 就是 盒子當前的位置 + 變化的值(目標值 - 現在的位置)/10 </script> </body> </html>回撥函式
輪播圖案例
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src="../js/animate.js" type="text/javascript"></script> <script src="../js/rotation.js" type="text/javascript" charset="utf-8"></script> <style type="text/css"> *{ padding: 0; margin: 0; } ul,ol{ list-style: none; } .focus{ position: relative; width: 720px; height: 455px; background-color: purple; overflow: hidden; } .focus li img{ width: 720px; height: 455px; } .focus ul{ position: absolute; top: 0; left: 0; width: 600%; } .focus ul li{ float: left; } .arrow-l,.arrow-r{ position: absolute; display: none; top: 50%; margin-top: -20px; width: 24px; height: 40px; background:rgba(0,0,0,.3); text-align: center; line-height: 40px; z-index: 999; } .arrow-r{ right: 0; } .circle{ position: absolute; bottom: 10px; left: 50px; } .circle li{float: left; width: 8px; height: 8px; border: 2px solid rgba(255,255,255,.5); margin: 0 3px; border-radius: 50%; cursor: pointer; } .current{ background-color: #fff; } </style> </head> <body> <div class ="focus"> <!--左側按鈕--> <a href="javascript:;" class="arrow-l"><</a> <!--右側按鈕--> <a href="javascript:;" class="arrow-r">></a> <!--核心滾動區域--> <ul> <li><a href="#"><img src="../upload/focus1.jpg" alt="" /></a></li> <li><a href="#"><img src="../upload/focus2.jpg" alt="" /></a></li> <li><a href="#"><img src="../upload/focus3.jpg" alt="" /></a></li> <li><a href="#"><img src="../upload/focus4.jpg" alt="" /></a></li> </ul> <!--小圓圈--> <ol class="circle"> </ol> </div> </body> </html>HTML部分
//var obg = {}; //obg.name = 'andy'; //簡單動畫函式封裝obj目標物件 target 目標位置 function animate(obj,target,callback){ //當我們不斷的點選按鈕,這個元素的速度會越來越快 因為開啟了太多的定時器 //解決方案就是 讓元素只有一個定時器執行 clearInterval(obj.timer); obj.timer = setInterval(function(){ //緩動動畫公式:(目標值 - 現在的位置) / 10 作為每次移動的距離步長 //把步長值改為整數 不要出現小數問題 var step = (target - obj.offsetLeft) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); if(obj.offsetLeft == target){ clearInterval(obj.timer); //回撥函式寫到結束定時器裡面 if(callback){ callback(); } } //把每次加1 這個步長值改為一個慢慢變小的值 obj.style.left = obj.offsetLeft + step + 'px'; },40) }animateJS
window.addEventListener('load',function(){ //1.獲取元素 var arrow_l = document.querySelector('.arrow-l'); var arrow_r = document.querySelector('.arrow-r'); var focus = document.querySelector('.focus'); var focusWidth = focus.offsetWidth; //2、滑鼠經過focus 就顯示隱藏左右按鈕 focus.addEventListener('mouseenter',function(){ arrow_l.style.display = 'block'; arrow_r.style.display = 'block'; clearInterval(timer); timer = null; }) focus.addEventListener('mouseleave',function(){ arrow_l.style.display = 'none'; arrow_r.style.display = 'none'; timer = setInterval(function(){ //手動呼叫點選事件 arrow_r.click(); },2000) }) //3.動態生成小圓圈 有幾張圖 就生成幾個小圓圈 var ul = focus.querySelector('ul'); var ol = focus.querySelector('.circle'); for(var i = 0; i< ul.children.length; i++){ //建立一個li var li = document.createElement('li'); //記錄當前小圓圈的索引號 通過自定義屬性來做 li.setAttribute('index',i); //把li插入到ol裡面 ol.appendChild(li); //4.小圓圈排他思想 直接生成小圓圈的同時 直接幫定點選事件 li.addEventListener('click',function(){ //把所有li清除current 類名 for(var i = 0;i < ol.children.length; i++){ ol.children[i].className = ''; } //當前的li 設定current類名 this.className = 'current'; //5.點選小圓圈,移動圖片 移動的是ul //ul 的移動距離 = 小圓圈的索引號 * 圖片的寬度 注意 是負值 //當點選了某個li 就拿到當前li的索引號 var index = this.getAttribute('index'); //當點選li 就把當前的索引號 給num num = index; animate(ul,-index*focusWidth); //當點選li 就把當前的索引號 給circle circle = index; }) } ol.children[0].className = 'current'; //6.克隆第一張圖片(li)放到ul最後面 var first = ul.children[0].cloneNode(true); ul.appendChild(first); //7.點選右側按鈕,圖片滾動一張 var num = 0; //circle 控制小圓圈的播放 var circle = 0; //flag 節流閥 var flag = true; //右側按鈕做法 arrow_r.addEventListener('click',function(){ if(flag){ flag = false; //關閉節流閥 //如果走到最後 複製的一張圖片,此時 ul要快速復原 left 改為0 if(num == ul.children.length - 1){ ul.style.left = 0; num = 0; } num++; animate(ul, -num * focusWidth,function(){ flag = true; //開啟節流閥 }); //8.點選右側按鈕,小圓圈跟隨一起變化 可以再宣告一個變數控制小圓圈的播放 circle++; //如果circle == 4 說明走到最後克隆的這張圖片了 就復原 if(circle == ol.children.length){ circle = 0; } circleChange(); } }); //左側按鈕做法 arrow_l.addEventListener('click',function(){ if(flag){ flag = false; //關閉節流閥 //如果走到最後 複製的一張圖片,此時 ul要快速復原 left 改為0 if(num == 0){ ul.style.left = -num * focusWidth + 'px'; num = ul.children.length - 1; } num--; animate(ul, -num * focusWidth,function(){ flag = true; //開啟節流閥 }); //8.點選右側按鈕,小圓圈跟隨一起變化 可以再宣告一個變數控制小圓圈的播放 circle--; //如果circle <0 說明 第一張圖片,則小圓圈要改為第4個小圓圈 // if(circle < 0){ // circle = ol.children.length - 1; // } circle = circle < 0 ? ol.children.length - 1 : circle; circleChange(); } }); function circleChange(){ //先清除其餘小圓圈的current類名 for(var i = 0; i< ol.children.length;i++){ ol.children[i].className = ''; } ol.children[circle].className ='current'; } //10.自動播放圖片 var timer = setInterval(function(){ //手動呼叫點選事件 arrow_r.click(); },2000) })ratationJS
5.常見網頁特效案例
5.1 節流閥
防止輪播圖按鈕連續點選造成播放過快。
節流閥目的:當上一個函式動畫內容執行完畢,再去執行下一個函式動畫,讓世界無法連續觸發。
核心實現思路:利用回撥函式,新增一個變數來控制,鎖住函式和解鎖函式。
開始設定一個變數var flag = true;
if(flag){flag = flase; do something}關閉水龍頭 程式碼在ratationJS
返回頂部案例
//3.當我們點選了返回頂部模組 就讓視窗滾動到頁面最上方 goback.addEventListener('click',function(){ //裡面的x和y 不跟單位 直接寫數字 //.scroll(0,0); //因為是視窗 所以物件是window animate(window,0); }); //簡單動畫函式封裝obj目標物件 target 目標位置 function animate(obj,target,callback){ //當我們不斷的點選按鈕,這個元素的速度會越來越快 因為開啟了太多的定時器 //解決方案就是 讓元素只有一個定時器執行 clearInterval(obj.timer); obj.timer = setInterval(function(){ //緩動動畫公式:(目標值 - 現在的位置) / 10 作為每次移動的距離步長 //把步長值改為整數 不要出現小數問題 var step = (target - window.pageYOffset) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); if(window.pageYOffset == target){ clearInterval(obj.timer); //回撥函式寫到結束定時器裡面 // if(callback){ // callback(); // } callback && callback(); } //把每次加1 這個步長值改為一個慢慢變小的值 window.scroll(0,window.pageYOffset + step); },15) }返回頂部程式碼
導航筋斗雲效果 案例(呼叫的animate函式在上面的animateJS)
<div id="c_nav" class="c-nav"> <!--筋斗雲圖片--> <span class="cloud"></span> <ul> <li class='current'><a href="#">首頁新聞</a></li> <li><a href="#">師資力量</a></li> <li><a href="#">活動策劃</a></li> <li><a href="#">企業文化</a></li> <li><a href="#">公司簡介</a></li> <li><a href="#">連續我們</a></li> </ul> </div> <script src="../js/animate.js" type="text/javascript" charset="utf-8"></script> <script> var cloud = document.querySelector('.cloud'); var c_nav = document.querySelector('.c-nav'); var lis = c_nav.querySelector('li'); //給所有li繫結事件 //這個current作為筋斗雲的起始位置 var current = 0; for(var i = 0; i< lis.length;i++){ //滑鼠經過把當前li的位置作為目標值 lis[i].addEventListener('mouseenter',function(){ animate(cloud,this.offsetLeft); }) //滑鼠離開就復原為0回到起始位置 lis[i].addEventListener('mouseleave',function(){ animate(cloud,current); }) //當滑鼠點選,就把當前位置作為目標值 lis[i].addEventListener('click',function(){ current = this.offsetLeft; }) } </script>