版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
JavaScript基礎(chǔ)知識(shí)到高級(jí)應(yīng)用
Scsnbxjyjhf
JavaScript的資料很多,但從未從頭到尾學(xué)完過(guò)。偶遇blue老師的被榮為“最經(jīng)典的
JavaScrip視頻教程”后,愛(ài)不釋眼,筆記過(guò)程中奇想何不筆錄下來(lái),故有此教程。教程中夾
有個(gè)人的理解,由于水平有限,請(qǐng)以blue老師的講解為準(zhǔn)。
第八課JS運(yùn)動(dòng)基礎(chǔ)
一、運(yùn)動(dòng)基礎(chǔ)
運(yùn)動(dòng)不只是位置的變化,還可以是其它一些變化,如透明度的變化,我們都可以歸為運(yùn)
動(dòng)。
1、讓一個(gè)DIV動(dòng)起來(lái)
讓一個(gè)div動(dòng)起來(lái)大體上需要兩步:第一步,給div加絕對(duì)定位屬性以及諸如left的定
位值,否則這個(gè)div是不能動(dòng)起來(lái)的;第二步,開(kāi)一個(gè)定時(shí)器,讓定時(shí)器執(zhí)行的函數(shù)不斷改
變那個(gè)div的Ie代的值,這樣這個(gè)div就會(huì)運(yùn)動(dòng)起來(lái)了。如下例:
<!DOCTYPEHTML>
<html>
<head>
<metacharset="utf-8">
無(wú)標(biāo)題文檔
<style>
#divl{width:200px;height:200px;background:red;position:absolute;top:50px;left:Opx;}
</style>
<script>
functionstartMove()
varoDiv=document.getElementByld('divl');
setlnterval(function(){
oDiv.style.left=oDiv.offsetLeft+10+'px';
),30);
)
</script>
</head>
<body>
<inputid="btnl"type="button"value="開(kāi)始運(yùn)動(dòng)"onclick="startMove()"/>
<divid="divl">
</div>
</body>
</html>
定時(shí)器里的30,其單位是毫秒,即每隔30毫秒運(yùn)行函數(shù)一次,為什么是30,這是一個(gè)
經(jīng)驗(yàn)值,設(shè)為30時(shí),其運(yùn)行顯得相對(duì)平滑一些,看起來(lái)合理一些。
為什么使用。ffsetLeft來(lái)給left賦值,以及為何還要加上'p*這樣的單位字符,請(qǐng)參看第
五課定時(shí)器里第五節(jié)的無(wú)縫滾動(dòng)課程內(nèi)容。
開(kāi)始運(yùn)動(dòng)
程序運(yùn)行界面如上圖所示,當(dāng)我們單擊一下“開(kāi)始運(yùn)動(dòng)”按鈕后,那個(gè)紅色的div就會(huì)
一直往右邊跑,即使運(yùn)動(dòng)到屏幕外也在跑(通過(guò)觀察下邊的滾動(dòng)條變化可發(fā)現(xiàn)它仍在運(yùn)行)。
如果我們想讓它運(yùn)動(dòng)到某個(gè)位置如左邊距為300Px時(shí)停下來(lái),該怎樣做呢?關(guān)閉定時(shí)器
就可達(dá)到此目的。
先定義一個(gè)變量用于存放定時(shí)器vartimer=null,開(kāi)定時(shí)器就把定時(shí)器賦給這個(gè)變量
timer=setlnterval(function(){...},30),然后在定時(shí)器執(zhí)行的函數(shù)里增加一判斷語(yǔ)句,如果div
的左邊距等于300時(shí),就關(guān)閉定時(shí)器,其JS代碼如下:
<script>
vartimer=null;
functionstartMove()
(
varoDiv=document.getElementByld('divl');
timer=setlnterval(function(){
if(oDiv.offsetLeft==300)
(
clearlnterval(timer);
}
oDiv.style.left=oDiv.offsetLeft+10+'px';
}f30);
)
</script>
經(jīng)此一改,div確實(shí)能自動(dòng)停下來(lái)了,但此程序有不完善的地方,當(dāng)div停下來(lái)的時(shí)候,
我們?cè)俅螁螕簟伴_(kāi)始運(yùn)動(dòng)”按鈕,div又會(huì)不斷地向右邊跑起來(lái)了。
我們可能是會(huì)想不通的,雖然再次單擊“開(kāi)始運(yùn)動(dòng)”按鈕,定時(shí)器會(huì)重啟,但
if(oDiv.offsetLeft==300)為真,緊接著就會(huì)關(guān)閉這個(gè)定時(shí)器的,為何還要?jiǎng)幽兀?/p>
實(shí)際上定時(shí)器是先啟動(dòng)后關(guān)閉,在啟動(dòng)的過(guò)程中又要關(guān)閉時(shí),它會(huì)把關(guān)閉動(dòng)作推遲到下
一個(gè)時(shí)間段里去執(zhí)行,現(xiàn)在這個(gè)時(shí)間段里的代碼會(huì)照常執(zhí)行一遍。按常理來(lái)講好像也說(shuō)得過(guò)
去,那就是如果定時(shí)器都未啟動(dòng)又何必談關(guān)閉呢,所以它會(huì)先讓定時(shí)器啟動(dòng)起來(lái)使定時(shí)器存
在,再去關(guān)閉。那么按此原理,oDiv.style.left=oDiv.offsetLeft+10+'px'這句照樣執(zhí)行,此時(shí)div
的left值就為310px了,那么在下一時(shí)間段里來(lái)執(zhí)行關(guān)閉動(dòng)作時(shí),oDiv.offsetLeft==300就不
為真了,所以會(huì)動(dòng)起來(lái)。
這是使用==判斷所造成的,我們?nèi)绻裲Div.style.left=oDiv.offsetLeft+10+'px'中的10改成
7即oDiv.style.left=oDiv.offsetLeft+7+'px'再運(yùn)行時(shí),將發(fā)現(xiàn)div根本不會(huì)停下來(lái)。因?yàn)楫?dāng)?shù)?2
個(gè)30毫秒時(shí),div的left值為294px,第43個(gè)30毫秒時(shí),div的left值為301px,始終不會(huì)
等于300px,無(wú)條件成立的時(shí)候,所以它會(huì)一直動(dòng)。
解決辦法也很簡(jiǎn)單,只需將oDiv.offsetLeft==300這句改成oDiv.offsetLeft>=300即可。
經(jīng)此一改,雖然div不會(huì)不停地運(yùn)動(dòng)了,但會(huì)出現(xiàn)另一個(gè)現(xiàn)象,每再單擊一次“開(kāi)始運(yùn)
動(dòng)”按鈕,div總會(huì)向右挪動(dòng)一點(diǎn),這一點(diǎn)是7Px那么大。其原因就是上面所講的定時(shí)器會(huì)
把其中的代碼執(zhí)行一遍所造成的。
完美的做法是,把移動(dòng)div的這句oDiv.style.left=oDiv.offsetLeft+speed+'px'放到if的else
部分里,條件不滿(mǎn)足時(shí)才會(huì)被執(zhí)行,就避免了放在外邊總會(huì)被執(zhí)行至少一遍的弊端了:
</style>
<script>
vartimer=null;
functionstartMove()
(
varoDiv=document.getElementByld('divl');
timer=setlnterval(function(){
varspeed=10;
if(oDiv.offsetLeft>=300)
(
clearlnterval(timer);
)
else
(
oDiv.style.left=oDiv.offsetLeft+speed+'px*;
}
},30);
)
</script>
這下前面所遇到的問(wèn)題好像都解決了,似乎程序很完美了,其實(shí)不然,當(dāng)我們開(kāi)始運(yùn)行
程序后,我們不斷地單擊“開(kāi)始運(yùn)動(dòng)”按鈕,將發(fā)現(xiàn)div的移動(dòng)速度每單擊一次就會(huì)增加一
些,單擊的次數(shù)越多,其運(yùn)動(dòng)的速度就越快。
其原因是,每單擊一次程序就開(kāi)一個(gè)定時(shí)器,多個(gè)定時(shí)器疊加在一起,所以移動(dòng)速度就
大了。解決辦法也很簡(jiǎn)單,在開(kāi)定時(shí)器之前,關(guān)閉原先的定時(shí)器,這樣就保證只有一個(gè)定時(shí)
器了:
<script>
vartimer=null;
functionstartMove()
(
varoDiv=document.getElementByld('divl,);
clearlnterval(timer);
timer=setlnterval(function(){
varspeed=l;
if(oDiv.offsetLeft>=300)
(
clearlnterval(timer);
}
else
(
oDiv.styleJeft=oDiv.offsetLeft+speed+*px';
}
},30);
)
</script>
現(xiàn)在我們就有一套比較完整的運(yùn)動(dòng)代碼了。
2、簡(jiǎn)單的運(yùn)動(dòng)框架
所謂框架就是一套完整的固定的流程,就像模板一樣,直接套用即可。
上面程序的完善過(guò)程,就是運(yùn)動(dòng)框架的形成過(guò)程,其最終版就相當(dāng)于一個(gè)框架。據(jù)此我
們總結(jié)出這個(gè)運(yùn)動(dòng)框架必須具備下列兩點(diǎn):
1、在開(kāi)始運(yùn)動(dòng)時(shí),關(guān)閉已有定時(shí)器
2、把運(yùn)動(dòng)和停止隔開(kāi)(if/else)
二、運(yùn)動(dòng)框架應(yīng)用實(shí)例
1、“分享到”側(cè)邊欄
如圖,程序開(kāi)始時(shí)只有“分享到”浮在左邊,當(dāng)鼠標(biāo)移入后,原先處于屏幕外的綠
色div層向右運(yùn)動(dòng),運(yùn)動(dòng)到剛好全部顯示時(shí)停止。當(dāng)鼠標(biāo)移開(kāi)時(shí),綠色div層向左運(yùn)動(dòng),待
剛剛?cè)恳瞥銎聊粫r(shí)停止。
<!DOCTYPEHTML>
<html>
<head>
<metacharset="utf-8">
無(wú)標(biāo)題文檔
<style>
#divl{width:150px;height:200px;background:green;position:absolute;left:-150px;}
#divlspan{position:absolute;width:20px;height:60px;line-height:20px;background:blue;
right:-20px;top:70px;}
</style>
<script>
window.onload=function()
(
varoDiv=document.getElementByld('divl');
oDiv.onmouseover=function()
startMove();
);
oDiv.onmouseout=function()
(
startMove2();
);
);
vartimer=null;
functionstartMove()
(
varoDiv=document.getElementByld(,divl');
clearlnterval(timer);
timer=setlnterval(function(){
if(oDiv.offsetLeft==0)
(
clearlnterval(timer);
}
else
(
oDiv.style.left=oDiv.offsetLeft+10+'px';
)
},30);
}
functionstartMove2()
(
varoDiv=document.getElementByld(,divl,);
clearlnterval(timer);
timer=setlnterval(function(){
if(oDiv.offsetLeft==-150)
clearlnterval(timer);
)
else
(
oDiv.style.left=oDiv.offsetLeft-10+'px';
)
},30);
)
</script>
</head>
<body>
<divid=ndivl">
<span>分享至k/span>
</div>
</body>
</html>
在布局上,綠色的DIV的定位屬性為absolute,其父級(jí)為body,所以它是相對(duì)于body
來(lái)定位的?!胺窒淼健笔且粋€(gè)span,其定位屬性也為absolute,其結(jié)構(gòu)上的父級(jí)是這個(gè)綠色
的div,而這個(gè)父級(jí)也設(shè)定了定位屬性,那么這個(gè)父級(jí)就是span的定位父級(jí),所以這個(gè)span
是相對(duì)于div來(lái)定位的。
div的寬度為150px,其left為-150px,相對(duì)于body定位下來(lái),剛好處于屏幕外,其右
邊緣與屏幕左邊緣齊。
span的寬度為20px,其right為-20px,則它相對(duì)于div定位下來(lái),就是剛好處于div外,
其左邊緣與div的右邊緣齊,在屏幕上就是它的左邊緣剛好與屏幕的左邊緣齊,好似浮在屏
幕的左邊。整體效果如上圖所示。
運(yùn)動(dòng)部分用JS完成。
鼠標(biāo)移入div時(shí),onmouseover激活,執(zhí)行startMove函數(shù),函數(shù)里首先關(guān)閉原有定時(shí)
器,開(kāi)新定時(shí)器,定時(shí)器執(zhí)行的函數(shù)里判斷側(cè)邊欄的左邊距是否為0,如為0,即側(cè)邊欄剛
好全部顯示在屏幕上,關(guān)閉定時(shí)器,停止運(yùn)行。如果不為0,執(zhí)行else語(yǔ)句,每30毫秒把
側(cè)邊欄左邊距加10px,側(cè)邊欄則會(huì)向右運(yùn)動(dòng)。
鼠標(biāo)移出div時(shí),onmouseout激活,執(zhí)行startMove2函數(shù),函數(shù)里首先關(guān)閉原有定時(shí)
器,開(kāi)新定時(shí)器,定時(shí)器執(zhí)行的函數(shù)里判斷側(cè)邊欄的左邊距是否為-150,如為-150,即側(cè)邊
欄剛好全部移出屏幕,關(guān)閉定時(shí)器,停止運(yùn)行。如果不為-150,執(zhí)行else語(yǔ)句,每30毫秒
把側(cè)邊欄左邊距減10px,側(cè)邊欄則會(huì)向左運(yùn)動(dòng)。
功能己達(dá)到,運(yùn)行時(shí)一切正常',但還沒(méi)有完,一個(gè)程序設(shè)計(jì)的最后一步就是代碼優(yōu)化。
實(shí)際上在上面的程序中,函數(shù)startMove與startMove2有許多相同的地方,應(yīng)該能合并成
一個(gè)函數(shù)的。
根據(jù)前面課程中所講的原理,不同部分用參數(shù)代替的原則,那么startMove與
startMove2不同的是移動(dòng)的目標(biāo)位置點(diǎn)與移動(dòng)的速度(大小、方向),將此兩項(xiàng)用參數(shù)代替
合并后的JS代碼如下:
<script>
window.onload=function()
(
varoDiv=document.getElementByld('divl');
oDiv.onmouseover=function()
(
startMove(0,10);
);
oDiv.onmouseout=function()
{
startMove(-150,-10);
);
);
vartimer=null;
functionstartMove(iTargetzspeedj)
(
varoDiv=document.getElementByld('divl');
clearlnterval(timer);
timer=setlnterval(function(){
if(oDiv.offsetLeft==iTarget)
(
clearlnterval(timer);
)
else
(
oDiv.style.left=oDiv.offsetLeft+speed+'px';
)
),30);
)
</script>
但這還不是最簡(jiǎn)代碼,對(duì)于那個(gè)速度,兩者在大小上是一樣,只有方向不同,為正時(shí)表
示向右移動(dòng),為負(fù)時(shí)表示向左移動(dòng),然而這個(gè)方向可由傳入的目標(biāo)點(diǎn)的值與div自己的
offsetLeft值比較一下就可得知,因如果oDiv.offsetLeft>iTarget則其移動(dòng)應(yīng)該是向左的,故其
速度為?10,反之為+10,所以我們還可以只使用一個(gè)參數(shù)進(jìn)一步簡(jiǎn)化:
<script>
window.onload=function()
(
varoDiv=document.getElementByld('divl,);
oDiv.onmouseover=function()
(
startMove(O);
);
oDiv.onmouseout=function()
startMove(-150);
);
);
vartimer=null;
functionstartMove(iTarget)
(
varoDiv=document.get日ementByld('divl');
clearlnterval(timer);
timer=setlnterval(function(){
varspeed=0;
if(oDiv.offsetLeft>iTarget)
(
speed=-10;
)
else
(
speed=10;
)
if(oDiv.offsetLeft==iTarget)
(
clearlnterval(timer);
)
else
(
oDiv.style.left=oDiv.offsetLeft+speed+'px';
)
},30);
)
</script>
也許你會(huì)認(rèn)為這樣做的結(jié)果反而因要判斷移動(dòng)方向而增加了代碼字節(jié),不能算是優(yōu)化。
這是你把優(yōu)化的標(biāo)準(zhǔn)只定為代碼的字節(jié)數(shù)量上而也,實(shí)際上代碼的優(yōu)化不只體現(xiàn)在代碼量減
少方面,更主要的是體現(xiàn)在讓用戶(hù)怎么以最簡(jiǎn)單的方式使用上,因傳入的參數(shù)越少,而功能
又不變,用戶(hù)就覺(jué)得越簡(jiǎn)單,這就是優(yōu)化的目的。
2、圖片淡入淡出
在火狐、谷歌中,可使用Opacity屬性用來(lái)設(shè)置一個(gè)元素的透明度,取值范圍是0~1之
間,不可為負(fù)值。opacity取值為1是完全不透明,取值為0是完全透明,視覺(jué)上看不見(jiàn)。
其語(yǔ)法如opacity:0.3,意為透明度為30%。IE9+才開(kāi)始支持CSS3opacity,而對(duì)IE6-IE8我
們習(xí)慣使用filter濾鏡屬性來(lái)進(jìn)行實(shí)現(xiàn)。IE從4.0版開(kāi)始,就提供了一些內(nèi)置的多媒體濾鏡
特效,具體的使用方法是:
語(yǔ)法:filter:filters
參數(shù):filters:要使用的濾鏡效果。多個(gè)濾鏡之間用空格隔開(kāi)。
IE4.0以上版本,支持以下14種濾鏡:
濾鏡名說(shuō)明
Alpha讓HTML元件呈現(xiàn)出透明的漸進(jìn)效果
Blur讓HTML元件產(chǎn)生風(fēng)吹模糊的效果
Chroma讓圖像中的某一顏色變成透明色
DropShadow讓HTML元件有一個(gè)下落式的陰影
FlipH讓HTML元件水平翻轉(zhuǎn)
FlipV讓HTML元件垂直翻轉(zhuǎn)
Glow在元件的周?chē)a(chǎn)生光暈而模糊的效果
Gray把一個(gè)彩色的圖片變成黑白色
Invert產(chǎn)生圖片的照片底片的效果
Light在HTML元件上放置一個(gè)光影
Mask利用另一個(gè)HTML元件在另一個(gè)元件上產(chǎn)生圖像的遮罩
Shadow產(chǎn)生一個(gè)比較立體的陰影
Wave讓HTML元件產(chǎn)生水平或是垂直方向上的波浪變形
XRay產(chǎn)生HTML元件的輪廓,就像是照X光一樣
羅列出這么多來(lái),目的是讓大家有所了解,我們這里只管利用Alpha濾鏡來(lái)控制透明度
實(shí)現(xiàn)淡入淡出即可,其語(yǔ)法為filter:alpha(opacity=sqlN)wJcfilter:alpha(opacity:sqlN),
sqIN取值從0到100,0表是完全透明,100表示完全不透明。
FF與IE這兩大類(lèi)瀏覽器對(duì)透明度的支持方式不同,假設(shè)我們要將ID為div1的透明度
設(shè)為30%,怎樣做到兼容呢?
其實(shí)很簡(jiǎn)單,就是把兩種寫(xiě)法均寫(xiě)出來(lái),不支持的那種寫(xiě)法會(huì)被瀏覽器忽略,如:
ftdivl{width:200px;height:200px;background:red;filter:alpha(opacity:30);opacity:0.3;}
下面我們著手來(lái)實(shí)現(xiàn)淡入淡出功能。
如下圖,div初始透明度為30%,當(dāng)鼠標(biāo)進(jìn)入后,透明度值逐漸變?yōu)?00%,鼠標(biāo)移出后
逐漸還原為30%。
在JS里,運(yùn)動(dòng)不只是位置的變化,這種透明度的變化也可用我們前面介紹的運(yùn)動(dòng)框架
來(lái)完成,所以這也是一種運(yùn)動(dòng)。
在前邊所做的“分享到”實(shí)例中,因在JS里有。ffsetLeft屬性讓我們能很方便地獲得元
素的位置,所以實(shí)現(xiàn)運(yùn)動(dòng)功能就變得容易一些,而透明度,在JS里是沒(méi)有。ffsetAlpha這屬
性的,也就是說(shuō)我們是不能像位置那樣去直接獲取與設(shè)置了。
在這里,我們應(yīng)用了程序設(shè)計(jì)的一個(gè)重要思想,就是把一些要表現(xiàn)的東西,用一些變量
來(lái)存取,把要進(jìn)行的操作轉(zhuǎn)換成對(duì)變量的操作,從而達(dá)到控制的目的。
我們定義一個(gè)全局變量varalpha=3O;其初值為30,表示透明度,如果鼠標(biāo)是移入,我們
讓其值變大,然后賦給div;如果是鼠標(biāo)移出,讓其值變小,再賦給div。也就是通過(guò)一個(gè)中
間變量來(lái)模擬透明度,存取該變量的值從而操作透明度,其完整代碼如下:
<(DOCTYPEHTML>
<html>
<head>
<metacharset="utf-8">
<title>無(wú)標(biāo)題文檔
<style>
#divl{width:200px;height:200px;background:red;filter:alpha(opacity:30);opacity:。.3;}
</style>
<script>
window.onload=function()
(
varoDiv=document.getElementByld('divl');
oDiv.onmouseover=function()
(
startMove(lOO);
);
oDiv.onmouseout=function()
(
startMove(30);
);
);
varalpha=30;
vartimer=null;
functionstartMove(iTarget)
(
varoDiv=document.getElementByld('divl,);
clearlnterval(timer);
timer=setlnterval(function(){
varspeed=0;
if(alpha<iTarget)
speed=10;
else
speed=-10;
)
if(alpha==iTarget)
(
clearlnterval(timer);
}
else
(
alpha+=speed;
oDiv.style.filter='alpha(opacity:'+alpha+')';
oDiv.style.opacity=alpha/100;
)
),30);
)
</script>
</head>
<body>
<divid="divl"x/div>
</body>
</html>
三、緩沖運(yùn)動(dòng)
1、緩沖運(yùn)動(dòng)基本
前面所講的運(yùn)動(dòng)是勻速運(yùn)動(dòng),緩沖運(yùn)動(dòng)是變速運(yùn)動(dòng),像拉伸或壓縮的彈簧被釋放后一樣,
是先快后慢。彈簧產(chǎn)生這種運(yùn)動(dòng)是因彈簧的形變?cè)诟淖?,其彈力在不斷變小,加速度不斷?/p>
小,所以會(huì)先快后慢。在JS里我們用一變化的變量來(lái)代替速度,讓它先大后小,最后為零,
就模擬出緩沖了。
一個(gè)元素要從一個(gè)初始位置到一個(gè)目標(biāo)位置,起初時(shí)的距離較遠(yuǎn),我們讓其速度較大,
隨著距離越來(lái)越近,我們讓其速度越來(lái)越小,到達(dá)目標(biāo)位置時(shí)速度為零,這樣展現(xiàn)出來(lái)的就
是緩沖運(yùn)動(dòng)了。
速度的大小跟距離有關(guān),距離大速度就大,距離小速度就小,換句話說(shuō),速度與距離成
正比。
假設(shè)一個(gè)div要運(yùn)動(dòng)到300處,這個(gè)300就是目標(biāo)位置,div在運(yùn)動(dòng)中的位置即當(dāng)前位
置是在不斷變化的,我們可用JS里。ffsetLeft來(lái)取得,假設(shè)div元素存儲(chǔ)在oDiv變量里,那
么oDiv.offsetLeft就是這個(gè)div運(yùn)動(dòng)過(guò)程中的當(dāng)前位置,表達(dá)式300-oDiv.offsetLeft的值就會(huì)
越來(lái)越小,能否就用它來(lái)當(dāng)作速度呢:
<!DOCTYPEHTML>
<html>
<head>
<metacharset="utf-8">
無(wú)標(biāo)題文檔
<style>
#divl{width:100px;height:100px;background:red;position:absolute;left:O;top:50px;}
</style>
<script>
functionstartMove()
(
varoDiv=document.getElementByld('divl');
setlnterval(function(){
varspeed=300-oDiv.offsetLeft;
oDiv.style.left=oDiv.offsetLeft+speed+'px';
},30);
)
</script>
</head>
<body>
<inputtype="button"value="開(kāi)始運(yùn)動(dòng)"onclick="startMove()"/>
<divid="divl">
</div>
</body>
</html>
運(yùn)行程序,當(dāng)我們一單擊“開(kāi)始運(yùn)動(dòng)”按鈕,一瞬間,紅色塊就到達(dá)了目的地。
開(kāi)始時(shí),div的left值為0.oDiv.offsetLeft也就等于0,那么300-oDiv.offsetLeft就等于
300,即速度值就為其距離值,所以定時(shí)器一啟動(dòng),在第一個(gè)30毫秒內(nèi)就把它直接移到目標(biāo)
位置了。
知道原因了,解決也就簡(jiǎn)單了,我們可以取這個(gè)差值的幾分之幾作為速度值即可解決這
個(gè)問(wèn)題,比如將varspeed=300-oDiv.offsetLeft;這句改成varspeed=(300-oDiv.offsetLeft)/10;
經(jīng)此一改后,再運(yùn)行程序,運(yùn)動(dòng)緩沖起來(lái)了,達(dá)到我們的目的了。但程序設(shè)計(jì)不能到此
就完事了,我們還要看有沒(méi)有bug。
我們布局上,增加一個(gè)div,位置在目標(biāo)位置300處,其寬度為lpx,高度為300px,看
起來(lái)就是一條線:
#div2{width:lpx;height:300px;positiomabsolute;left:300px;top:0;background:black;}
開(kāi)始運(yùn)動(dòng)
程序運(yùn)行后如下圖所示:
開(kāi)始運(yùn)動(dòng)
那個(gè)紅色塊并沒(méi)有到達(dá)300處。
如果我們?cè)贘S中增力「一句:document.title=oDiv.offsetLeft+/+speed;將紅色塊當(dāng)前的左邊
距、速度值作為文檔的標(biāo)題信息顯示出來(lái):
<!DOCTYPEHTML>
<html>
<head>
<metacharset=nutf-8">
無(wú)標(biāo)題文檔</title>
<style>
#divl{width:100px;height:100px;background:red;position:absolute;left:O;top:50px;}
#div2{width:lpx;height:300px;position:absolute;left:300px;top:0;background:black;}
</style>
<script>
functionstartMove()
(
varoDiv=document.getElementByld(,divl,);
setlnterval(function(){
varspeed=(300-oDiv.offsetLeft)/10;
oDiv.style.left=oDiv.offsetLeft+speed4-'px';
document.title=oDiv.offsetLeft+7+speed;
),30);
)
</script>
</head>
<body>
<inputtype="button”value二”開(kāi)始運(yùn)動(dòng)"onclick="startMove()"/>
<divid="divl"x/div>
<divid=,,div2"x/div>
</body>
</html>
上圖為在chrome中運(yùn)行情況,從標(biāo)題文字信息可看出此時(shí)div的左邊距為296,速度
為0.4。
上圖為在IE中運(yùn)行情況,從標(biāo)題文字信息可看出此時(shí)div的左邊距為291,速度為0.9。
雖然這兩大類(lèi)瀏覽器的計(jì)算結(jié)果不一致,但都沒(méi)有準(zhǔn)確地運(yùn)動(dòng)到300處。
下面我們以IE為例來(lái)探討為什么會(huì)停在291處。
像素ipx,是屏幕顯示時(shí)的最小單位。如果我們把樣式寫(xiě)成left:291.9px,瀏覽器會(huì)直接
把后面的小數(shù)忽略掉定為291,也就是說(shuō),當(dāng)div運(yùn)行到291處時(shí),它與目標(biāo)點(diǎn)300之間的
距離為9,varspeed=(300-oDiv.offsetLeft)/10后的speed為0.9,緊接著執(zhí)行下句:
oDiv.style.left=oDiv.offsetLeft+speed+'px',其left賦值后將為291.9,瀏覽器會(huì)把小數(shù)位直接
干掉,最終賦值為291,再到下一個(gè)30毫秒段時(shí),程序也是這樣處理的,所以它會(huì)停在291
處。
在JS里有一Math對(duì)象,里面集成了許多數(shù)學(xué)方法,其中有一對(duì)向上取整ceil。、向下
取整floor。的方法正好能用在這里,解決這個(gè)問(wèn)題。
向上取整,就是取大于它的最小整數(shù),如:
ceil(3.14)=4;ceil(-1.32)=-l;ceil(-0.998)=0o
向下取整,就是取小于它的最大整數(shù),
$0floor(3.99)=3;floor(-1.32)=-2;floor(-0.998)=-lo
我們?cè)谏厦娴腏S代碼中增加一句:
<script>
functionstartMove()
varoDiv=document.getElementByld(*divl');
setlnterval(function(){
varspeed=(300-oDiv.offsetLeft)/10;
speed=Math,ceil(speed);
oDiv.style.left=oDiv.offsetLeft+speed+'px';
document.title=oDiv.offsetLeft+7+speed;
},30);
)
</script>
再次運(yùn)行,就可解決那個(gè)問(wèn)題了:
?詞收藏夾,電300,0
當(dāng)speed=0.9時(shí),speed=Math.ceil(speed)后speed=l,div將向前運(yùn)動(dòng)Ipx,左邊距變?yōu)?/p>
292,下一循環(huán)時(shí),speed=0.8,ceil后仍為1,div又向前移動(dòng)lpx,左邊距變?yōu)?93,如此循
環(huán)直到300,速度為。時(shí)停止。
但這一改進(jìn),只適用于從左往右運(yùn)動(dòng)這種情況。如果我們把div的left的值由0變?yōu)?00:
#divl{width:100px;height:100px;background:red;position:absolute;left:600px;top:50px;},其
它不變,再運(yùn)行:
這是初始狀態(tài)
這是程序運(yùn)動(dòng)后的結(jié)果
那個(gè)紅色塊又不能準(zhǔn)確到達(dá)300位置。
因現(xiàn)在的初始位置在600處,比目標(biāo)位置大,移動(dòng)過(guò)程中的當(dāng)前位置均比目標(biāo)位置大,
由varspeed=(300-oDiv.offsetLeft)/10計(jì)算出來(lái)的速度值為負(fù)值,那么
oDiv.style」eft=oDiv.offsetLeft+speed+'px'將會(huì)使它的左邊距值不斷減小,即向左移動(dòng),然而在
這句之前的向上取整speed=Math.ceil(speed)會(huì)出現(xiàn)ceil(-0.9)=0,所以它會(huì)停在309處。此時(shí)
我們將speed=Math.ceil(speed)改成speed=Math.floor(speed);向下取整,使其floor(-0.9)=-l即
解決此問(wèn)題。
我們?cè)诔绦蛑惺褂靡慌袛嗾Z(yǔ)句,如果速度為正,則向上取整,反之向下取整,那么我們
就可以用一套程序完成兩套程序才能完成的事情,就可大大增強(qiáng)程序的通用性了:
<script>
functionstartMove()
varoDiv=document.getElementByld('divl');
setlnterval(function(){
varspeed=(300-oDiv.offsetLeft)/10;
//speed=Math.floor(speed);
speed=speed>0?Math.ceil(speed):Math.floor(speed);
oDiv.style.left=oDiv.offsetLeft+speed+'px';
document.title=oDiv.offsetLeft+7+speed;
},30);
)
</script>
2、緩沖運(yùn)動(dòng)實(shí)例
(l)onscroll事件及scrollTop屬性
html里面的事件中,onscroll是滾動(dòng)條在滾動(dòng)時(shí)觸發(fā)的事件。
為窗口添加滾動(dòng)條事件其實(shí)非常的簡(jiǎn)單,window.onscroll=function(){};
對(duì)于滾動(dòng)條有兩個(gè)重要的屬性scrollLeft與scrollTop.
scrollLeft屬性是設(shè)置或獲取位于滾動(dòng)條對(duì)象左邊界和窗口中目前可見(jiàn)內(nèi)容的最左端
之間的距離。
scrollTop屬性是設(shè)置或獲取位于滾動(dòng)條對(duì)象最頂端和窗口中可見(jiàn)內(nèi)容的最頂端之間
的距離。
各瀏覽器下scrollTop的差異
IE6/7/8:
對(duì)于沒(méi)有doctype聲明的頁(yè)面里可以使用document.body.scrollTop來(lái)獲取
scrollTop高度;
又寸于有doctype聲明的頁(yè)面貝U可以使用document.documentElement.scrollTop;
Safari:
safari匕戢特別,有自己獲取scrollTop的函數(shù):window.pageYOffset;
Firefox:
火狐等等相對(duì)標(biāo)準(zhǔn)些的瀏覽器就省心多了,直接用
document.document^lement.scrollTop;
綜上情況,完美獲取scrollTop的賦值短語(yǔ)是:
varscrollTop=document.documentElement.scrollTop||window.pageYOffset||
document.body.scrollTop;
scrollTop到底是什么,下面我們用實(shí)例來(lái)說(shuō)明。
有些情況下,“元素中內(nèi)容”的高度會(huì)超過(guò)“元素本身”的高度,下面的演示中,外層元素的
高度值是200px,內(nèi)層元素的高度值是300px。很明顯,“外層元素中的內(nèi)容”高過(guò)了“外層元
素”本身.當(dāng)向下拖動(dòng)滾動(dòng)條時(shí),有部分內(nèi)容會(huì)隱沒(méi)在“外層元素的上邊界”之外,scrollTop就
等于這部分“不可見(jiàn)的內(nèi)容”的高度。
<!DOCTYPEHTML>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/htmI;charset=utf-8">
無(wú)標(biāo)題文檔
</head>
<body>
<divstyle="width:200px;height:200px;background-color:#999999;overflow:auto;"id="
外層元素">
<divstyle="width:100px;height:300px;background-color:#FFFF00;"id="內(nèi)層元素
,>>
這些文字顯示在內(nèi)層元素中。
</div>
</div>
</body>
</html>
解釋?zhuān)簝?nèi)層元素的高度值300px>外層元素的高度值200Px,因此“外層元素的內(nèi)容”(也
就是“內(nèi)層元素”)無(wú)法完全顯示,而外層元素把overflow設(shè)置為aut。,因此外層元素的右側(cè)
會(huì)出現(xiàn)一個(gè)上下方向的滑動(dòng)條。
初始狀態(tài)下,“內(nèi)層元素的上邊界”和“外層元素的上邊界”重合,沒(méi)有任何內(nèi)容超過(guò)“外層
元素的上邊界”,此時(shí)scrollTop屬性的值為0。
當(dāng)向下拖動(dòng)滾動(dòng)條時(shí),超過(guò)“外層元素的上邊界”的內(nèi)容會(huì)逐漸增多,scrollTop值就等于
這些超出的部分。當(dāng)拖動(dòng)滾動(dòng)條到最底部時(shí),“內(nèi)層元素的下邊界”和“外層元素的下邊界”
重合,超過(guò)“外層元素的上邊界”的內(nèi)容的高度=300px-200Px=100px,這也就是此時(shí)的
scrollTop值。
注意:scrollTop的使用方式是element.scrollTop,而不是element.style.scrollTop
在下面的演示實(shí)例中,拖動(dòng)滾動(dòng)條的過(guò)程中,會(huì)讀取此時(shí)的scrollTop的值,并在下方
文字中顯示出來(lái):
<!DOCTYPEHTML>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/htmI;charset=utf-8">
無(wú)標(biāo)題文檔
</head>
<body>
<divstyle="width:200px;height:200px;background-color:#999999;overflow:auto;"
id="outer">
<divstyle="width:100px;height:300px;background-color:#FFFF00;nid=,,insideu>
這些文字顯示在內(nèi)層元素中。
</div>
</div>
<p>scrollTop值是:<spanid="spa"x/spanx/p>
<scripttype="text/javascript">
varouterdiv=document.getElementByld("outer");
outerdiv.onscroll=readScr;
〃〃注冊(cè)。nscroll事件處理函數(shù)。當(dāng)拖動(dòng)滾動(dòng)條時(shí),會(huì)產(chǎn)生onscroll事件
varoSpa=document.getElementByld("spa");
//onscroll事件的處理函數(shù)
functionreadScr()
(
oSpa.innerHTML=outerdiv.scrollTop;
〃讀取“外層元素”此時(shí)的scrollTop的值并顯示出來(lái)
)
readScr();
〃頁(yè)面加載完成后,執(zhí)行一次此函數(shù)。顯示最初的scrollTop值,此時(shí)的值為0
</script>
</body>
</html>
這些文字顯示
在內(nèi)層元素
中O
scrollTop值是:0scrollTop值是:100
解釋?zhuān)寒?dāng)拖動(dòng)“外層元素的滾動(dòng)條”時(shí),會(huì)產(chǎn)生onscroll事件。為這個(gè)事件注冊(cè)一個(gè)名為
readScr的處理函數(shù),在readScr這個(gè)事件處理函數(shù)中,通過(guò)outerdiv.scrollTop得到"外層元
素”當(dāng)時(shí)的scrollTop的值,并顯示在頁(yè)面上。
(2)關(guān)于clientHeight>offsetHeight>scrollHeight
我們這里說(shuō)說(shuō)四種瀏覽器對(duì)document.body的clientHeight>offsetHeight和
scrollHeight的解釋。
這四種瀏覽器分別為IE(InternetExplorer)、NS(Netscape)、Opera>FF(FireFox)o
clientHeight
大家對(duì)clientHeight都沒(méi)有什么異議,都認(rèn)為是內(nèi)容可視區(qū)域的高度,也就是說(shuō)頁(yè)面瀏
覽器中可以看到內(nèi)容的這個(gè)區(qū)域的高度,一般是最后一個(gè)工具條以下到狀態(tài)欄以上的這個(gè)區(qū)
域,與頁(yè)面內(nèi)容無(wú)關(guān)。
offsetHeight
IE>Opera認(rèn)為offsetHeight=clientHeight+滾動(dòng)條+邊框。
NS、FF認(rèn)為offsetHeight是網(wǎng)頁(yè)內(nèi)容實(shí)際高度,可以小于clientHeighto
scrollHeight
IE>Opera認(rèn)為scrollHeight是網(wǎng)頁(yè)內(nèi)容實(shí)際高度,可以小于clientHeighto
NS>FF認(rèn)為scrollHeight是網(wǎng)頁(yè)內(nèi)容高度,不過(guò)最小值是clientHeighto
簡(jiǎn)單地說(shuō)clientHeight就是透過(guò)瀏覽器看內(nèi)容的這個(gè)區(qū)域高度。
NS>FF認(rèn)為offsetHeight和scrollHeight都是網(wǎng)頁(yè)內(nèi)容高度,只不過(guò)當(dāng)網(wǎng)頁(yè)內(nèi)容高度
小于等于clientHeight時(shí),scrollHeight的值是clientHeight,而offsetHeight可以小于
clientHeighto
IE、Opera認(rèn)為offsetHeight是可視區(qū)域clientHeight滾動(dòng)條加邊框。scrollHeight則是
網(wǎng)頁(yè)內(nèi)容實(shí)際高度。
RSclientwidth>offsetwidth和scrollwidth的解釋與上面相同,只是把高度換成寬度
即可。
clientHeight與offsetHeight的區(qū)別
許多文章已經(jīng)介紹了clientHeight和offsetHeight的區(qū)別,就是clientHeight的值不包括
scrollbar的高度,而offsetHeight的值包括了scrollbar的高度。然而,clientHeight和offsetHeight
的值到底由什么組成的呢?如何計(jì)算這兩個(gè)數(shù)的值?
pbody.clientTop
div.clientLeft
div.offsetLeft
body.dientLeft
div.style.left
div.style.padding
div.style.border
body.style.padding
body.style.border
IE中:
document.body.clientWidth==>BODY對(duì)象寬度
document.body.clientHeight==>BODY對(duì)象高度
document.documentElement.clientwidth==>可見(jiàn)區(qū)域?qū)挾?/p>
document.documentElement.clientHeight==>可見(jiàn)區(qū)域高度
FireFox中:
document.body.clientWidth==>BODY對(duì)象寬度
document.body.clientHeight==>BODY對(duì)象高度
document.documentElement.clientwidth==>可見(jiàn)區(qū)域?qū)挾?/p>
document.documentElement.clientHeight==>可見(jiàn)區(qū)域高度
Opera中:
document.body.clientWidth==>可見(jiàn)區(qū)域?qū)挾?/p>
document.body.clientHeight==>可見(jiàn)區(qū)域高度
document.documentElement.clientWidth==>頁(yè)面對(duì)象寬度(即BODY對(duì)象寬度加上
Margin寬)
document.document日ement.clientHeight==>頁(yè)面對(duì)象高度(即BODY對(duì)象高度加上
Margin高)
沒(méi)有定義W3c的標(biāo)準(zhǔn),則
IE為:
document.documentElement.clientWidth==>0
document.documentElement.clientHeight==>0
FireFox為:
document.documentElement.clientWidth==>頁(yè)面對(duì)象寬度(即BODY對(duì)象寬度加上
Margin寬)
document.documentElement.clientHeight==>頁(yè)面對(duì)象高度(即BODY對(duì)象高度加上
Margin高)
Opera為:
document.documentElement.clientWidth==>頁(yè)面對(duì)象寬度(即BODY對(duì)象寬度加上
Margin寬)
document.documentElement.clientHeight==>頁(yè)面對(duì)象高度(即BODY對(duì)象高度加上
Margin高)
網(wǎng)頁(yè)可見(jiàn)區(qū)域?qū)挘篸ocument.body.clientWidth
網(wǎng)頁(yè)可見(jiàn)區(qū)域高:document.body.clientHeight
網(wǎng)頁(yè)可見(jiàn)區(qū)域?qū)挘篸ocument.body.offsetWidth(包括邊線的寬)
網(wǎng)頁(yè)可見(jiàn)區(qū)域高:document.body.offsetHeight(包括邊線的高)
網(wǎng)頁(yè)正文全文寬:document.body.scrollWidth
網(wǎng)頁(yè)正文全文高:document.body.scrollHeight
網(wǎng)頁(yè)被卷去的高:document.body.scrollTop
網(wǎng)頁(yè)被卷去的左:document.body.scrollLeft
網(wǎng)頁(yè)正文部分上:window.screenTop
網(wǎng)頁(yè)正文部分左:window.screenLeft
屏幕分辨率的高:window.screen.height
屏幕分辨率的寬:window.screen.width
屏幕可用工作區(qū)高度:window.screen.availHeight
屏幕可用工作區(qū)寬度:window.screen.availwidth
HTML精確定位:scrollLeftscrollWidth>clientWidth>offsetwidth
scrollwidth==>獲取對(duì)象的滾動(dòng)寬度
scrollHeight==>獲取對(duì)象的滾動(dòng)高度
scrollLeft==>設(shè)置或獲取位于對(duì)象左邊界和窗口中目前可見(jiàn)內(nèi)容的最左端之間的距離
(被卷去的左)
scrollTop==>設(shè)置或獲取位于對(duì)象最頂端和窗口中可見(jiàn)內(nèi)容的最頂端之間的距離(被
卷去的高)
offsetLe代==>獲取對(duì)象相對(duì)于版面或由offsetparent屬性指定的父坐標(biāo)的計(jì)算左側(cè)位
置
offsetTop==>獲取對(duì)象相對(duì)于版面或由offsetTop屬性指定的父坐標(biāo)的計(jì)算頂端位置
offsetHeight==>獲取對(duì)象相對(duì)于版面或由父坐標(biāo)offsetParent屬性指定的父坐標(biāo)的高
度
event.clientX==>相對(duì)文檔的水平座標(biāo)
event.clientY==>相對(duì)文檔的垂直座標(biāo)
event.offsetX==>相對(duì)容器的水平坐標(biāo)
event.offsetY==>相對(duì)容器的垂直坐標(biāo)
document.documentElement.scrollTop==>垂直方向滾動(dòng)的值
event.clientX+document.documentElement.scrollTop==>相對(duì)文檔的水平座標(biāo)+垂直方向
滾動(dòng)的量
以上這些繁雜的內(nèi)容,僅供參考。我們重點(diǎn)掌握將要用到的dientHeight與scrollTop。
(3)右側(cè)懸浮框
如上圖,拖動(dòng)滾動(dòng)條時(shí),紅色塊始終懸浮在窗口的右下角。
<!DOCTYPEHTML>
<html>
<head>
<metacharset="utf-8">
無(wú)標(biāo)題文檔</title>
<style>
#divl{width:100px;height:150px;background:red;position:absolute;right:O;bottom:0;}
</style>
<script>
window.onscroll=function()
varoDiv=document.get日ementByld('divl');
varscrollTop=document.documentElement.scrollTop||document.body.scrollTop;
oDiv.style.top=document.document日ement.clientHeight-oDiv.offsetHeight+scrollTop+'px';
);
</script>
</head>
<bodystyle="height:2000px;">
<divid="divl"x/div>
</body>
</html>
首先在布局時(shí)就給body一個(gè)行間樣式設(shè)其高度為2000px:<bodystyle="height:2000px;">
這樣網(wǎng)頁(yè)面右邊會(huì)出現(xiàn)滾動(dòng)條。
要懸浮在右下角,必須設(shè)置其定位屬性
divposition:absoluteo
window.onscroll二function(){}是為窗口添力口的滾動(dòng)事件,當(dāng)我們拖動(dòng)滾動(dòng)條時(shí)會(huì)觸發(fā)此
事件執(zhí)行函數(shù)里的代碼。
varoDiv=document.getElementByld('div:T);這句是獲取div元素。
varscrollTop=document.documentElement.scrollTop11document.body.scrollTop;是獲得
scrollTop值。
oDiv.style.top=document.documentElement.clientHeight-oDiv.offsetHeight+scrollTop+'px';ii
句中的document.documentElement.clientHeight是頁(yè)面可視區(qū)的高度,oDiv.offsetHeight是
div的高度,scrollTop頁(yè)面上
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 走進(jìn)小學(xué)活動(dòng)方案樣本(3篇)
- 二零二五年度二手房交易稅費(fèi)計(jì)算合同樣本3篇
- 二零二五年度辦公大樓智能化系統(tǒng)運(yùn)維合同2篇
- 2025年度涂料涂料工程招標(biāo)代理服務(wù)合同范本3篇
- 2025年三年級(jí)上學(xué)期英語(yǔ)教師工作總結(jié)范文(2篇)
- 煤礦綜掘綜合防塵管理制度(3篇)
- 自學(xué)書(shū)法系統(tǒng)課程設(shè)計(jì)
- 輪形課程設(shè)計(jì)
- 二零二五年度個(gè)人住房裝修貸款保證合同3篇
- 2025年高一班級(jí)工作計(jì)劃(二篇)
- 七年級(jí)數(shù)學(xué)家長(zhǎng)會(huì)課件
- 智能座艙市場(chǎng)與技術(shù)發(fā)展趨勢(shì)研究白皮書(shū)課件
- 2022年公司出納個(gè)人年度工作總結(jié)
- 四年級(jí)北京版數(shù)學(xué)上學(xué)期應(yīng)用題專(zhuān)項(xiàng)針對(duì)練習(xí)
- 職業(yè)安全健康現(xiàn)場(chǎng)檢查記錄表參考范本
- 雨水、排水管道工程質(zhì)量保證措施
- 荒誕派戲劇演示
- 公園景觀改造工程施工組織設(shè)計(jì)方案
- 全國(guó)書(shū)法作品展投稿登記表
- 鏈條功率選用
- 年產(chǎn)30萬(wàn)噸合成氨脫碳工段工藝設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論