版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
JavaScript基础知识到高级应用
Scsnbxjyjhf
JavaScript的资料很多,但从未从头到尾学完过。偶遇blue老师的被荣为“最经典的
JavaScrip视频教程”后,爱不释眼,笔记过程中奇想何不笔录下来,故有此教程。教程中夹
有个人的理解,由于水平有限,请以blue老师的讲解为准。
第八课JS运动基础
一、运动基础
运动不只是位置的变化,还可以是其它一些变化,如透明度的变化,我们都可以归为运
动。
1、让一个DIV动起来
让一个div动起来大体上需要两步:第一步,给div加绝对定位属性以及诸如left的定
位值,否则这个div是不能动起来的;第二步,开一个定时器,让定时器执行的函数不断改
变那个div的Ie代的值,这样这个div就会运动起来了。如下例:
<!DOCTYPEHTML>
<html>
<head>
<metacharset="utf-8">
无标题文档
<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="开始运动"onclick="startMove()"/>
<divid="divl">
</div>
</body>
</html>
定时器里的30,其单位是毫秒,即每隔30毫秒运行函数一次,为什么是30,这是一个
经验值,设为30时,其运行显得相对平滑一些,看起来合理一些。
为什么使用。ffsetLeft来给left赋值,以及为何还要加上'p*这样的单位字符,请参看第
五课定时器里第五节的无缝滚动课程内容。
开始运动
程序运行界面如上图所示,当我们单击一下“开始运动”按钮后,那个红色的div就会
一直往右边跑,即使运动到屏幕外也在跑(通过观察下边的滚动条变化可发现它仍在运行)。
如果我们想让它运动到某个位置如左边距为300Px时停下来,该怎样做呢?关闭定时器
就可达到此目的。
先定义一个变量用于存放定时器vartimer=null,开定时器就把定时器赋给这个变量
timer=setlnterval(function(){...},30),然后在定时器执行的函数里增加一判断语句,如果div
的左边距等于300时,就关闭定时器,其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>
经此一改,div确实能自动停下来了,但此程序有不完善的地方,当div停下来的时候,
我们再次单击“开始运动”按钮,div又会不断地向右边跑起来了。
我们可能是会想不通的,虽然再次单击“开始运动”按钮,定时器会重启,但
if(oDiv.offsetLeft==300)为真,紧接着就会关闭这个定时器的,为何还要动呢?
实际上定时器是先启动后关闭,在启动的过程中又要关闭时,它会把关闭动作推迟到下
一个时间段里去执行,现在这个时间段里的代码会照常执行一遍。按常理来讲好像也说得过
去,那就是如果定时器都未启动又何必谈关闭呢,所以它会先让定时器启动起来使定时器存
在,再去关闭。那么按此原理,oDiv.style.left=oDiv.offsetLeft+10+'px'这句照样执行,此时div
的left值就为310px了,那么在下一时间段里来执行关闭动作时,oDiv.offsetLeft==300就不
为真了,所以会动起来。
这是使用==判断所造成的,我们如果把oDiv.style.left=oDiv.offsetLeft+10+'px'中的10改成
7即oDiv.style.left=oDiv.offsetLeft+7+'px'再运行时,将发现div根本不会停下来。因为当第42
个30毫秒时,div的left值为294px,第43个30毫秒时,div的left值为301px,始终不会
等于300px,无条件成立的时候,所以它会一直动。
解决办法也很简单,只需将oDiv.offsetLeft==300这句改成oDiv.offsetLeft>=300即可。
经此一改,虽然div不会不停地运动了,但会出现另一个现象,每再单击一次“开始运
动”按钮,div总会向右挪动一点,这一点是7Px那么大。其原因就是上面所讲的定时器会
把其中的代码执行一遍所造成的。
完美的做法是,把移动div的这句oDiv.style.left=oDiv.offsetLeft+speed+'px'放到if的else
部分里,条件不满足时才会被执行,就避免了放在外边总会被执行至少一遍的弊端了:
</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>
这下前面所遇到的问题好像都解决了,似乎程序很完美了,其实不然,当我们开始运行
程序后,我们不断地单击“开始运动”按钮,将发现div的移动速度每单击一次就会增加一
些,单击的次数越多,其运动的速度就越快。
其原因是,每单击一次程序就开一个定时器,多个定时器叠加在一起,所以移动速度就
大了。解决办法也很简单,在开定时器之前,关闭原先的定时器,这样就保证只有一个定时
器了:
<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>
现在我们就有一套比较完整的运动代码了。
2、简单的运动框架
所谓框架就是一套完整的固定的流程,就像模板一样,直接套用即可。
上面程序的完善过程,就是运动框架的形成过程,其最终版就相当于一个框架。据此我
们总结出这个运动框架必须具备下列两点:
1、在开始运动时,关闭已有定时器
2、把运动和停止隔开(if/else)
二、运动框架应用实例
1、“分享到”侧边栏
如图,程序开始时只有“分享到”浮在左边,当鼠标移入后,原先处于屏幕外的绿
色div层向右运动,运动到刚好全部显示时停止。当鼠标移开时,绿色div层向左运动,待
刚刚全部移出屏幕时停止。
<!DOCTYPEHTML>
<html>
<head>
<metacharset="utf-8">
无标题文档
<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,其父级为body,所以它是相对于body
来定位的。“分享到”是一个span,其定位属性也为absolute,其结构上的父级是这个绿色
的div,而这个父级也设定了定位属性,那么这个父级就是span的定位父级,所以这个span
是相对于div来定位的。
div的宽度为150px,其left为-150px,相对于body定位下来,刚好处于屏幕外,其右
边缘与屏幕左边缘齐。
span的宽度为20px,其right为-20px,则它相对于div定位下来,就是刚好处于div外,
其左边缘与div的右边缘齐,在屏幕上就是它的左边缘刚好与屏幕的左边缘齐,好似浮在屏
幕的左边。整体效果如上图所示。
运动部分用JS完成。
鼠标移入div时,onmouseover激活,执行startMove函数,函数里首先关闭原有定时
器,开新定时器,定时器执行的函数里判断侧边栏的左边距是否为0,如为0,即侧边栏刚
好全部显示在屏幕上,关闭定时器,停止运行。如果不为0,执行else语句,每30毫秒把
侧边栏左边距加10px,侧边栏则会向右运动。
鼠标移出div时,onmouseout激活,执行startMove2函数,函数里首先关闭原有定时
器,开新定时器,定时器执行的函数里判断侧边栏的左边距是否为-150,如为-150,即侧边
栏刚好全部移出屏幕,关闭定时器,停止运行。如果不为-150,执行else语句,每30毫秒
把侧边栏左边距减10px,侧边栏则会向左运动。
功能己达到,运行时一切正常',但还没有完,一个程序设计的最后一步就是代码优化。
实际上在上面的程序中,函数startMove与startMove2有许多相同的地方,应该能合并成
一个函数的。
根据前面课程中所讲的原理,不同部分用参数代替的原则,那么startMove与
startMove2不同的是移动的目标位置点与移动的速度(大小、方向),将此两项用参数代替
合并后的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>
但这还不是最简代码,对于那个速度,两者在大小上是一样,只有方向不同,为正时表
示向右移动,为负时表示向左移动,然而这个方向可由传入的目标点的值与div自己的
offsetLeft值比较一下就可得知,因如果oDiv.offsetLeft>iTarget则其移动应该是向左的,故其
速度为・10,反之为+10,所以我们还可以只使用一个参数进一步简化:
<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>
也许你会认为这样做的结果反而因要判断移动方向而增加了代码字节,不能算是优化。
这是你把优化的标准只定为代码的字节数量上而也,实际上代码的优化不只体现在代码量减
少方面,更主要的是体现在让用户怎么以最简单的方式使用上,因传入的参数越少,而功能
又不变,用户就觉得越简单,这就是优化的目的。
2、图片淡入淡出
在火狐、谷歌中,可使用Opacity属性用来设置一个元素的透明度,取值范围是0~1之
间,不可为负值。opacity取值为1是完全不透明,取值为0是完全透明,视觉上看不见。
其语法如opacity:0.3,意为透明度为30%。IE9+才开始支持CSS3opacity,而对IE6-IE8我
们习惯使用filter滤镜属性来进行实现。IE从4.0版开始,就提供了一些内置的多媒体滤镜
特效,具体的使用方法是:
语法:filter:filters
参数:filters:要使用的滤镜效果。多个滤镜之间用空格隔开。
IE4.0以上版本,支持以下14种滤镜:
滤镜名说明
Alpha让HTML元件呈现出透明的渐进效果
Blur让HTML元件产生风吹模糊的效果
Chroma让图像中的某一颜色变成透明色
DropShadow让HTML元件有一个下落式的阴影
FlipH让HTML元件水平翻转
FlipV让HTML元件垂直翻转
Glow在元件的周围产生光晕而模糊的效果
Gray把一个彩色的图片变成黑白色
Invert产生图片的照片底片的效果
Light在HTML元件上放置一个光影
Mask利用另一个HTML元件在另一个元件上产生图像的遮罩
Shadow产生一个比较立体的阴影
Wave让HTML元件产生水平或是垂直方向上的波浪变形
XRay产生HTML元件的轮廓,就像是照X光一样
罗列出这么多来,目的是让大家有所了解,我们这里只管利用Alpha滤镜来控制透明度
实现淡入淡出即可,其语法为filter:alpha(opacity=sqlN)wJcfilter:alpha(opacity:sqlN),
sqIN取值从0到100,0表是完全透明,100表示完全不透明。
FF与IE这两大类浏览器对透明度的支持方式不同,假设我们要将ID为div1的透明度
设为30%,怎样做到兼容呢?
其实很简单,就是把两种写法均写出来,不支持的那种写法会被浏览器忽略,如:
ftdivl{width:200px;height:200px;background:red;filter:alpha(opacity:30);opacity:0.3;}
下面我们着手来实现淡入淡出功能。
如下图,div初始透明度为30%,当鼠标进入后,透明度值逐渐变为100%,鼠标移出后
逐渐还原为30%。
在JS里,运动不只是位置的变化,这种透明度的变化也可用我们前面介绍的运动框架
来完成,所以这也是一种运动。
在前边所做的“分享到”实例中,因在JS里有。ffsetLeft属性让我们能很方便地获得元
素的位置,所以实现运动功能就变得容易一些,而透明度,在JS里是没有。ffsetAlpha这属
性的,也就是说我们是不能像位置那样去直接获取与设置了。
在这里,我们应用了程序设计的一个重要思想,就是把一些要表现的东西,用一些变量
来存取,把要进行的操作转换成对变量的操作,从而达到控制的目的。
我们定义一个全局变量varalpha=3O;其初值为30,表示透明度,如果鼠标是移入,我们
让其值变大,然后赋给div;如果是鼠标移出,让其值变小,再赋给div。也就是通过一个中
间变量来模拟透明度,存取该变量的值从而操作透明度,其完整代码如下:
<(DOCTYPEHTML>
<html>
<head>
<metacharset="utf-8">
<title>无标题文档
<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>
三、缓冲运动
1、缓冲运动基本
前面所讲的运动是匀速运动,缓冲运动是变速运动,像拉伸或压缩的弹簧被释放后一样,
是先快后慢。弹簧产生这种运动是因弹簧的形变在改变,其弹力在不断变小,加速度不断变
小,所以会先快后慢。在JS里我们用一变化的变量来代替速度,让它先大后小,最后为零,
就模拟出缓冲了。
一个元素要从一个初始位置到一个目标位置,起初时的距离较远,我们让其速度较大,
随着距离越来越近,我们让其速度越来越小,到达目标位置时速度为零,这样展现出来的就
是缓冲运动了。
速度的大小跟距离有关,距离大速度就大,距离小速度就小,换句话说,速度与距离成
正比。
假设一个div要运动到300处,这个300就是目标位置,div在运动中的位置即当前位
置是在不断变化的,我们可用JS里。ffsetLeft来取得,假设div元素存储在oDiv变量里,那
么oDiv.offsetLeft就是这个div运动过程中的当前位置,表达式300-oDiv.offsetLeft的值就会
越来越小,能否就用它来当作速度呢:
<!DOCTYPEHTML>
<html>
<head>
<metacharset="utf-8">
无标题文档
<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="开始运动"onclick="startMove()"/>
<divid="divl">
</div>
</body>
</html>
运行程序,当我们一单击“开始运动”按钮,一瞬间,红色块就到达了目的地。
开始时,div的left值为0.oDiv.offsetLeft也就等于0,那么300-oDiv.offsetLeft就等于
300,即速度值就为其距离值,所以定时器一启动,在第一个30毫秒内就把它直接移到目标
位置了。
知道原因了,解决也就简单了,我们可以取这个差值的几分之几作为速度值即可解决这
个问题,比如将varspeed=300-oDiv.offsetLeft;这句改成varspeed=(300-oDiv.offsetLeft)/10;
经此一改后,再运行程序,运动缓冲起来了,达到我们的目的了。但程序设计不能到此
就完事了,我们还要看有没有bug。
我们布局上,增加一个div,位置在目标位置300处,其宽度为lpx,高度为300px,看
起来就是一条线:
#div2{width:lpx;height:300px;positiomabsolute;left:300px;top:0;background:black;}
开始运动
程序运行后如下图所示:
开始运动
那个红色块并没有到达300处。
如果我们在JS中增力「一句:document.title=oDiv.offsetLeft+/+speed;将红色块当前的左边
距、速度值作为文档的标题信息显示出来:
<!DOCTYPEHTML>
<html>
<head>
<metacharset=nutf-8">
无标题文档</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二”开始运动"onclick="startMove()"/>
<divid="divl"x/div>
<divid=,,div2"x/div>
</body>
</html>
上图为在chrome中运行情况,从标题文字信息可看出此时div的左边距为296,速度
为0.4。
上图为在IE中运行情况,从标题文字信息可看出此时div的左边距为291,速度为0.9。
虽然这两大类浏览器的计算结果不一致,但都没有准确地运动到300处。
下面我们以IE为例来探讨为什么会停在291处。
像素ipx,是屏幕显示时的最小单位。如果我们把样式写成left:291.9px,浏览器会直接
把后面的小数忽略掉定为291,也就是说,当div运行到291处时,它与目标点300之间的
距离为9,varspeed=(300-oDiv.offsetLeft)/10后的speed为0.9,紧接着执行下句:
oDiv.style.left=oDiv.offsetLeft+speed+'px',其left赋值后将为291.9,浏览器会把小数位直接
干掉,最终赋值为291,再到下一个30毫秒段时,程序也是这样处理的,所以它会停在291
处。
在JS里有一Math对象,里面集成了许多数学方法,其中有一对向上取整ceil。、向下
取整floor。的方法正好能用在这里,解决这个问题。
向上取整,就是取大于它的最小整数,如:
ceil(3.14)=4;ceil(-1.32)=-l;ceil(-0.998)=0o
向下取整,就是取小于它的最大整数,
$0floor(3.99)=3;floor(-1.32)=-2;floor(-0.998)=-lo
我们在上面的JS代码中增加一句:
<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>
再次运行,就可解决那个问题了:
・词收藏夹,电300,0
当speed=0.9时,speed=Math.ceil(speed)后speed=l,div将向前运动Ipx,左边距变为
292,下一循环时,speed=0.8,ceil后仍为1,div又向前移动lpx,左边距变为293,如此循
环直到300,速度为。时停止。
但这一改进,只适用于从左往右运动这种情况。如果我们把div的left的值由0变为600:
#divl{width:100px;height:100px;background:red;position:absolute;left:600px;top:50px;},其
它不变,再运行:
这是初始状态
这是程序运动后的结果
那个红色块又不能准确到达300位置。
因现在的初始位置在600处,比目标位置大,移动过程中的当前位置均比目标位置大,
由varspeed=(300-oDiv.offsetLeft)/10计算出来的速度值为负值,那么
oDiv.style」eft=oDiv.offsetLeft+speed+'px'将会使它的左边距值不断减小,即向左移动,然而在
这句之前的向上取整speed=Math.ceil(speed)会出现ceil(-0.9)=0,所以它会停在309处。此时
我们将speed=Math.ceil(speed)改成speed=Math.floor(speed);向下取整,使其floor(-0.9)=-l即
解决此问题。
我们在程序中使用一判断语句,如果速度为正,则向上取整,反之向下取整,那么我们
就可以用一套程序完成两套程序才能完成的事情,就可大大增强程序的通用性了:
<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、缓冲运动实例
(l)onscroll事件及scrollTop属性
html里面的事件中,onscroll是滚动条在滚动时触发的事件。
为窗口添加滚动条事件其实非常的简单,window.onscroll=function(){};
对于滚动条有两个重要的属性scrollLeft与scrollTop.
scrollLeft属性是设置或获取位于滚动条对象左边界和窗口中目前可见内容的最左端
之间的距离。
scrollTop属性是设置或获取位于滚动条对象最顶端和窗口中可见内容的最顶端之间
的距离。
各浏览器下scrollTop的差异
IE6/7/8:
对于没有doctype声明的页面里可以使用document.body.scrollTop来获取
scrollTop高度;
又寸于有doctype声明的页面贝U可以使用document.documentElement.scrollTop;
Safari:
safari匕戢特别,有自己获取scrollTop的函数:window.pageYOffset;
Firefox:
火狐等等相对标准些的浏览器就省心多了,直接用
document.document^lement.scrollTop;
综上情况,完美获取scrollTop的赋值短语是:
varscrollTop=document.documentElement.scrollTop||window.pageYOffset||
document.body.scrollTop;
scrollTop到底是什么,下面我们用实例来说明。
有些情况下,“元素中内容”的高度会超过“元素本身”的高度,下面的演示中,外层元素的
高度值是200px,内层元素的高度值是300px。很明显,“外层元素中的内容”高过了“外层元
素”本身.当向下拖动滚动条时,有部分内容会隐没在“外层元素的上边界”之外,scrollTop就
等于这部分“不可见的内容”的高度。
<!DOCTYPEHTML>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/htmI;charset=utf-8">
无标题文档
</head>
<body>
<divstyle="width:200px;height:200px;background-color:#999999;overflow:auto;"id="
外层元素">
<divstyle="width:100px;height:300px;background-color:#FFFF00;"id="内层元素
,>>
这些文字显示在内层元素中。
</div>
</div>
</body>
</html>
解释:内层元素的高度值300px>外层元素的高度值200Px,因此“外层元素的内容”(也
就是“内层元素”)无法完全显示,而外层元素把overflow设置为aut。,因此外层元素的右侧
会出现一个上下方向的滑动条。
初始状态下,“内层元素的上边界”和“外层元素的上边界”重合,没有任何内容超过“外层
元素的上边界”,此时scrollTop属性的值为0。
当向下拖动滚动条时,超过“外层元素的上边界”的内容会逐渐增多,scrollTop值就等于
这些超出的部分。当拖动滚动条到最底部时,“内层元素的下边界”和“外层元素的下边界”
重合,超过“外层元素的上边界”的内容的高度=300px-200Px=100px,这也就是此时的
scrollTop值。
注意:scrollTop的使用方式是element.scrollTop,而不是element.style.scrollTop
在下面的演示实例中,拖动滚动条的过程中,会读取此时的scrollTop的值,并在下方
文字中显示出来:
<!DOCTYPEHTML>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/htmI;charset=utf-8">
无标题文档
</head>
<body>
<divstyle="width:200px;height:200px;background-color:#999999;overflow:auto;"
id="outer">
<divstyle="width:100px;height:300px;background-color:#FFFF00;nid=,,insideu>
这些文字显示在内层元素中。
</div>
</div>
<p>scrollTop值是:<spanid="spa"x/spanx/p>
<scripttype="text/javascript">
varouterdiv=document.getElementByld("outer");
outerdiv.onscroll=readScr;
〃〃注册。nscroll事件处理函数。当拖动滚动条时,会产生onscroll事件
varoSpa=document.getElementByld("spa");
//onscroll事件的处理函数
functionreadScr()
(
oSpa.innerHTML=outerdiv.scrollTop;
〃读取“外层元素”此时的scrollTop的值并显示出来
)
readScr();
〃页面加载完成后,执行一次此函数。显示最初的scrollTop值,此时的值为0
</script>
</body>
</html>
这些文字显示
在内层元素
中O
scrollTop值是:0scrollTop值是:100
解释:当拖动“外层元素的滚动条”时,会产生onscroll事件。为这个事件注册一个名为
readScr的处理函数,在readScr这个事件处理函数中,通过outerdiv.scrollTop得到"外层元
素”当时的scrollTop的值,并显示在页面上。
(2)关于clientHeight>offsetHeight>scrollHeight
我们这里说说四种浏览器对document.body的clientHeight>offsetHeight和
scrollHeight的解释。
这四种浏览器分别为IE(InternetExplorer)、NS(Netscape)、Opera>FF(FireFox)o
clientHeight
大家对clientHeight都没有什么异议,都认为是内容可视区域的高度,也就是说页面浏
览器中可以看到内容的这个区域的高度,一般是最后一个工具条以下到状态栏以上的这个区
域,与页面内容无关。
offsetHeight
IE>Opera认为offsetHeight=clientHeight+滚动条+边框。
NS、FF认为offsetHeight是网页内容实际高度,可以小于clientHeighto
scrollHeight
IE>Opera认为scrollHeight是网页内容实际高度,可以小于clientHeighto
NS>FF认为scrollHeight是网页内容高度,不过最小值是clientHeighto
简单地说clientHeight就是透过浏览器看内容的这个区域高度。
NS>FF认为offsetHeight和scrollHeight都是网页内容高度,只不过当网页内容高度
小于等于clientHeight时,scrollHeight的值是clientHeight,而offsetHeight可以小于
clientHeighto
IE、Opera认为offsetHeight是可视区域clientHeight滚动条加边框。scrollHeight则是
网页内容实际高度。
RSclientwidth>offsetwidth和scrollwidth的解释与上面相同,只是把高度换成宽度
即可。
clientHeight与offsetHeight的区别
许多文章已经介绍了clientHeight和offsetHeight的区别,就是clientHeight的值不包括
scrollbar的高度,而offsetHeight的值包括了scrollbar的高度。然而,clientHeight和offsetHeight
的值到底由什么组成的呢?如何计算这两个数的值?
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对象宽度
document.body.clientHeight==>BODY对象高度
document.documentElement.clientwidth==>可见区域宽度
document.documentElement.clientHeight==>可见区域高度
FireFox中:
document.body.clientWidth==>BODY对象宽度
document.body.clientHeight==>BODY对象高度
document.documentElement.clientwidth==>可见区域宽度
document.documentElement.clientHeight==>可见区域高度
Opera中:
document.body.clientWidth==>可见区域宽度
document.body.clientHeight==>可见区域高度
document.documentElement.clientWidth==>页面对象宽度(即BODY对象宽度加上
Margin宽)
document.document日ement.clientHeight==>页面对象高度(即BODY对象高度加上
Margin高)
没有定义W3c的标准,则
IE为:
document.documentElement.clientWidth==>0
document.documentElement.clientHeight==>0
FireFox为:
document.documentElement.clientWidth==>页面对象宽度(即BODY对象宽度加上
Margin宽)
document.documentElement.clientHeight==>页面对象高度(即BODY对象高度加上
Margin高)
Opera为:
document.documentElement.clientWidth==>页面对象宽度(即BODY对象宽度加上
Margin宽)
document.documentElement.clientHeight==>页面对象高度(即BODY对象高度加上
Margin高)
网页可见区域宽:document.body.clientWidth
网页可见区域高:document.body.clientHeight
网页可见区域宽:document.body.offsetWidth(包括边线的宽)
网页可见区域高:document.body.offsetHeight(包括边线的高)
网页正文全文宽:document.body.scrollWidth
网页正文全文高:document.body.scrollHeight
网页被卷去的高:document.body.scrollTop
网页被卷去的左:document.body.scrollLeft
网页正文部分上:window.screenTop
网页正文部分左:window.screenLeft
屏幕分辨率的高:window.screen.height
屏幕分辨率的宽:window.screen.width
屏幕可用工作区高度:window.screen.availHeight
屏幕可用工作区宽度:window.screen.availwidth
HTML精确定位:scrollLeftscrollWidth>clientWidth>offsetwidth
scrollwidth==>获取对象的滚动宽度
scrollHeight==>获取对象的滚动高度
scrollLeft==>设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离
(被卷去的左)
scrollTop==>设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离(被
卷去的高)
offsetLe代==>获取对象相对于版面或由offsetparent属性指定的父坐标的计算左侧位
置
offsetTop==>获取对象相对于版面或由offsetTop属性指定的父坐标的计算顶端位置
offsetHeight==>获取对象相对于版面或由父坐标offsetParent属性指定的父坐标的高
度
event.clientX==>相对文档的水平座标
event.clientY==>相对文档的垂直座标
event.offsetX==>相对容器的水平坐标
event.offsetY==>相对容器的垂直坐标
document.documentElement.scrollTop==>垂直方向滚动的值
event.clientX+document.documentElement.scrollTop==>相对文档的水平座标+垂直方向
滚动的量
以上这些繁杂的内容,仅供参考。我们重点掌握将要用到的dientHeight与scrollTop。
(3)右侧悬浮框
如上图,拖动滚动条时,红色块始终悬浮在窗口的右下角。
<!DOCTYPEHTML>
<html>
<head>
<metacharset="utf-8">
无标题文档</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>
首先在布局时就给body一个行间样式设其高度为2000px:<bodystyle="height:2000px;">
这样网页面右边会出现滚动条。
要悬浮在右下角,必须设置其定位属性
divposition:absoluteo
window.onscroll二function(){}是为窗口添力口的滚动事件,当我们拖动滚动条时会触发此
事件执行函数里的代码。
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是页面可视区的高度,oDiv.offsetHeight是
div的高度,scrollTop页面上
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 辅导员聘用合同
- 安置房买卖合同范本 2篇
- 二零二四年度电子产品采购与技术支持合同
- 二零二四版保险代理合同
- 2024年度企业间借款合同范本:风险评估与控制
- 代开发APP软件保密协议(2024年度)
- 2024年度智能家居系统建设合同3篇
- 2024版装修工程工程量清单合同:某商业综合体装修2篇
- 二零二四年度版权转让合同变更协议
- 2024版特许经营合同范本includingareaexclusivityandroyaltypayments
- 2024届宜宾市普通高中2021级第一次诊断性测试理科综合试卷(含答案)
- 王阳明与心学
- 药品不良反应和医疗器械不良事件考核测试卷及答案
- 儿科常用H1抗组胺药处方审核专家共识(2023版)解读
- 教培机构如何玩转新媒体
- 保健医生工作及考核细则(1)规章制度
- (完整版)四宫格数独题目204道(可直接打印)及空表(一年级数独题练习)
- 移动机器人SLAM技术 课件 【ch04】移动机器人定位
- 考研数学(数学一)模拟试卷500(题后含答案及解析)
- 纯化水系统风险评估报告-1
- 数字化城市垃圾管理云平台垃圾云建设方案
评论
0/150
提交评论