本次練習錯誤總結:
1. 正確:
startMove( document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop);
錯誤:
startMove(document.documentElement.clientHeight - oDiv.offsetTop + scrollTop);
startMove(iTarget); 這個函式的目標點 iTarget 應該是 可視窗高度 – div的高度 + 滾動條上方的滾動距離
div的高度是 offsetHeight,是一整個div的高度。 div的offsetTop是它的top位置值。
2. 必須用timer指定定時器,否則清除定時器時清除不了。
timer = setInterval(function (){ },30) // 不能直接寫setInterval(function (){ },30)
3. 函式作用域問題?? (感覺經常犯這種錯誤)
var speed = (iTarget - oDiv.offsetTop)/4;
該速度變數是定時器使用,所以要定義在定時器的函式裡面。 而不是定義到startMove( ); 這個運動函式裡。
4.
startMove(document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop);
//這裡末尾不應該加‘px’, 括號內是函式的引數,而不是賦值給樣式!
且後面定時器裡 if(oDiv.offsetTop == iTarget) offsetTop返回值為數字。 iTarget不需要px單位。
5. clearInterval ( ); 清除定時器是在startMove ( ); 運動函式裡面的一開始去清除,而不是外面。且應該在括號內指定(timer)。
6. 該段程式碼oDiv獲取過兩次。在window.onscroll函式和 function startMove( )裡分別獲取了。
因為運動函式和視窗啟動自帶的滾動條函式不是包含關係,所以要重新獲取一遍div變數。
7. 定時器格式 setInterval ( function () { },30) 括號裡要跟function函式。
8.
if(iTarget==oDiv.offsetTop) //應該是oDiv.offsetTop == iTarget,即運動的位置達到了目標值
疑問
為什麼window.onscroll函式 和後面的startMove函式是分別執行的關係,而不是包含關係?
第二次寫的程式碼批註:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>右側懸浮框</title> <style> #div1{ width: 100px; height: 150px; background-color: plum; position: absolute; right: 0; bottom: 0; } </style> <script> window.onscroll = function () { var oDiv = document.getElementById(`div1`); var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //startMove(document.documentElement.clientHeight-oDiv.offsetTop+scrollTop); startMove(document.documentElement.clientHeight-oDiv.offsetHeight+scrollTop); //這裡應該是oDiv.offsetHeight,不是offsetTop。 區別是??? }; var timer = null; function startMove(iTarget) { clearInterval(timer); var oDiv = document.getElementById(`div1`); //setInterval(function (){ 這裡沒用timer指定定時器。。。所以前面清除定時器和這裡對應不上。 timer = setInterval(function (){ var speed = (iTarget - oDiv.offsetTop)/4; //這個變數是定時器裡面使用的,要定義到定時器的函式裡。 speed = speed>0? Math.ceil(speed):Math.floor(speed); if (oDiv.offsetTop == iTarget) { clearInterval(timer); } else { oDiv.style.top = oDiv.offsetTop + speed + `px`; } },30) } </script> </head> <body style="height: 2000px";> <div id="div1"> </div> </body> </html>
錯誤程式碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>右側懸浮框</title> <style> #div1{ width: 100px; height: 150px; background-color: palevioletred; position: absolute; right: 0; bottom: 0; } </style> <script> window.onscroll = function () { var oDiv = document.getElementById(`div1`); var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; startMove(document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop); //這裡末尾不應該加‘px’! 括號內是函式的引數,而不是賦值給樣式! }; var timer = null; //clearInterval(); //此處是否需要清除? 要清除,是在startMove運動開始裡面去清除。 //timer=setInterval(function startMove(iTarget) //寫法錯誤,定時器是在startMove函式裡面開啟,定時器和函式不是同級的。 function startMove(iTarget) { var oDiv = document.getElementById(`div1`); //運動函式和視窗啟動自帶的滾動條函式不是包含關係,所以要重新獲取一遍div變數。 clearInterval(timer); timer=setInterval(function () { //setInterval格式:括號裡面要跟個函式function var speed = (iTarget - oDiv.offsetTop)/4; // speed不是前面startMove傳參的,是新的變數,這裡要用var!! speed=speed>0?Math.ceil(speed):Math.floor(speed); //if(iTarget==oDiv.offsetTop){ //應該是oDiv.offsetTop == iTarget,即運動的位置達到了目標值 if(oDiv.offsetTop == iTarget) { clearInterval(timer); } else { oDiv.style.top = oDiv.offsetTop+speed+`px`; } },30); } </script> </head> <body style="height: 2000px;"> <div id="div1"> </div> </body> </html>
正確程式碼:
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>無標題文件</title> <style> #div1 {width:100px; height:150px; background:red; position:absolute; right:0; bottom:0;} </style> <script> window.onscroll=function () { var oDiv=document.getElementById(`div1`); var scrollTop=document.documentElement.scrollTop||document.body.scrollTop; //oDiv.style.top=document.documentElement.clientHeight-oDiv.offsetHeight+scrollTop+`px`; startMove(document.documentElement.clientHeight-oDiv.offsetHeight+scrollTop); //可視窗高度-div高度+滾動條頂部距離 }; var timer=null; function startMove(iTarget) { var oDiv=document.getElementById(`div1`); //為什麼要分別獲取div1?? // 為什麼window.onscroll函式 和後面的startMove函式是分別執行的關係,而不是包含關係? clearInterval(timer); timer=setInterval(function (){ var speed=(iTarget-oDiv.offsetTop)/4; speed=speed>0?Math.ceil(speed):Math.floor(speed); if(oDiv.offsetTop==iTarget) { clearInterval(timer); } else { oDiv.style.top=oDiv.offsetTop+speed+`px`; } }, 30); } </script> </head> <body style="height:2000px;"> <div id="div1"></div> </body> </html>