JavaScript和CSS的交互是现代JavaScript程序设计的支柱。事实上对于所有的现代web应用程序来说,至少使用某些形式的动态交互是必须的。那么做过之后,用户可以更快地操作而更少地把时间浪费在等待页面加载上。将动态技术与第六章提出的事件方面的观念相结合,对于实现无缝而强大的用户体验是非常重要的。
层叠式样式表是用来对易用的、有吸引力的网页进行修饰和布局的事实标准,它在给用户提供最少的困难的同时为开发者提供最多的能力。当你将那一能力与JavaScript相结合时,你将能够构造强健的用户界面,包括动画、窗口部件(widgets),或动态显示等。
访问样式信息
JavaScript与CSS的结合全部是以表现作为结果的交互。理解什么对你是可用的,对于精确地达到你想要的交互非常重要。
用来设置和获取元素的CSS属性的主要工具是其style属性。比如说,如果想要取得一个元素的高度,你可以编写如下代码:elem.style.height。如果你想要设置元素的高度为某个特定值,你可以执行如下代码:ele.style.height="100px"。
当处理DOM元素的CSS属性时,有两个会碰到的问题,它们并不像一般人所期望的那样运作。首先,JavaScript要求你在设置任何空间尺度时指明单位(就像前面设置高度时所做的那样)。同时,任何空间属性也将返回一个代表元素属性的字符串而非数字(如"100px"而非100)。第二,如果一个元素高为100像素,而你试图获取它的当前高度,你期望从style属性里取得那个"100px",情况却未必会如你所愿。这是因为任何样式表文件或内联CSS预设的样式信息并不能可靠地反映到style属性上。
这一状况将我们引向JavaScript中处理CSS的一个重要函数:获取一个元素真正的当前样式属性的方法,给你一个预期的精确值。存在一组(来源于W3C和IE特有的变种)相当可靠的方法可以用来得到DOM元素的真正的计算后的样式属性。它们能顾及所有相关的样式表、元素特定属性以及JavaScript所作的修改。当需要得到你正操作的元素的精确视图信息时这些方法将会是极其有用的。
获取元素的计算后样式值时应该考虑到存在于不同的浏览器间的大量的差异。跟在大多数的情形一样,IE有它自己的方法,而其它所有的浏览器都使用W3C定义的方式来实现。
程序7-1给出了一个用来找出元素的计算后样式属性值的一个函数,7-2则给出了使用此函数的一个示例。
程序7-1. 用来得到元素的计算后的实际CSS样式值的一个函数
CODE:
//获取一个特定元素(elem)的样式属性(name)
function getStyle( elem, name ) {
//如果该属性存在于style[]中,则它最近被设置过(且就是当前的)
if (elem.style[name])
return elem.style[name];
//否则,尝试IE的方式
else if (elem.currentStyle)
return elem.currentStyle[name];
//或者W3C的方法,如果存在的话
else if (document.defaultView && document.defaultView.getComputedStyle) {
//它使用传统的"text-Align"风格的规则书写方式,而不是"textAlign"
name = name.replace(/([A-Z])/g,"-$1");
name = name.toLowerCase();
//获取style对象并取得属性的值(如果存在的话)
var s = document.defaultView.getComputedStyle(elem,"");
return s && s.getPropertyValue(name);
//否则,就是在使用其它的浏览器
} else
return null;
}
程序7-2. 元素的计算后的CSS样式值未必是style对象里可用值的一种情况
CODE:
<html>
<head>
<style>p { height: 100px; }</style>
<script>
window.onload = function(){
//找到欲检查高度的段落对象
var p = document.getElementsByTagName("p")[0];
//使用传统方式检查其高度
alert( p.style.height + " should be null" );
//检查计算后的高度值
alert( getStyle( p, "height" ) + " should be 100px" );
};
</script>
</head>
<body>
<p>I should be 100 pixels tall.</p>
</body>
</html>
程序7-2说明了怎样得到一个DOM元素的实际的CSS属性值。在这种情形里你得到的是元素的实际的像素高度,即使其高度是通过头部的CSS来设定的。应该注意的是,你的函数将会忽略度量的单位(比如使用的是百分比)。尽管这一解决方案并不是绝对安全的,它的确是一个良好的出发点。
动态的元素
动态元素的隐含的意思也就是使用JavaScript和CSS维护或创建的非静态的元素。简单的例子是指示你对时事通讯感兴趣的复选框和弹出式的e-mail输入域。
在最基本的层面上,有三个关键的属性可用来构造动态效果:位置、尺寸、可见性。使用这三个属性你可以在现代浏览器上模拟大多数常见的用户交互效果。
元素的位置
操作元素的位置是在页面中开发动态元素的一个重要构成部分。访问和修改CSS位置属性让你有效地模拟许多流行的动画和交互效果(比如拖放)。
知道CSS的定位系统是怎样工作是操作元素位置的一个重要步骤。在CSS中,元素使用偏移来定位,使用的度量是相对父元素的左上角的偏移量。图7-1是CSS中使用的坐标系统的一个例子。
[attach]37002[/attach]
图7-1. 使用CSS的网页里坐标系统示例
页面上的所有元素都有着某种形式的top(垂直坐标)和left(水平坐标)偏移。大体来说,多数元素简单地根据其周围的元素静态定位。依照CSS标准的提议,一个元素可以有几种不同的定位方案。为了正好地理解这一点,我们来看看程序7-3所示的一个简单的网页。
程序7-3. 演示使用不同的定位方案的一个网页
CODE:
<html>
<head>
<style>
p {
border: 3px solid red;
padding: 10px;
width: 400px;
background: #FFF;
}
p.odd {
/* Positioning information goes in here */
position: static;
top: 0px;
left: 0px;
}
</style>
</head>
<body>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam …p>
<p class='odd'>Phasellus dictum dignissim justo. Duis nec risus id nunc…p>
<p>Sed vel leo. Nulla iaculis, tortor non laoreet dictum, turpis diam …</p>
</body>
</html>
我们来看看在上面这个简单的HTML页面的情境里,改变第二个段落的定位方式将会产后怎样不同的布局:
静态定位: 这是元素定位的默认方式;它简单地遵从文档的自然流向。当一个元素静态定位时,top和left属性将不起作用。静态定位的一个例子见图7-2,其中用于定位的css为:position:static;top:0px;left:0px。
[attach]37003[/attach]
图7-2. 页面正常(static)布局流里的段落
相对定位: 这一定位方式与静态定位非常相似,因为元素仍然会遵循正常的文档流直到得到其它指示。但是,设置top或left属性将会导致元素相对它的原来的(静态的)位置发生偏移。相对定位的一个例子如图7-3所示,其中的CSS定位为position:relative;top:-50px;left:50px。
[attach]37004[/attach]
图7-3. 相对定位,元素被移位到了前一个元素上面,而不再遵循正常的文档流
绝对定位: 将一个元素完全从正常的页面布局流中抓出来。被绝对定位的元素将相对于其第一个非静态定位的父级元素来显示。如果不存在父元素,它将相对于整个文档被定位。绝对定位的一个例子见图7-4,其中用于定位的css为:position:absolute;top:20px;left:0px。
[attach]37005[/attach]
图7-4. 绝对定位,元素的位置与页面的左上角相关,显示在已经存在的元素之上
固定定位: 固定定位将一个元素相对于浏览器的窗口定位。设置一个元素的top和left为0相素,将会使得该元素显示在浏览器的左上角(只要用户还在那个页面上),完全忽略浏览器滚动条的任何动作。固定定位的一个例子见图7-5,其中用于定位的css为:position:fixed;top:20px;right:0px。
[attach]37006[/attach]
图7-5. 固定定位,元素被定位到页面的右上角,尽管浏览器窗口被向下滚动了。
取得位置
元素被定位在何处依赖于它的css参数以及与其邻接的内容而不同。访问CSS属性或计算后的实际值都没有提供的一个能力是,获取元素在页面中或者仅在其它元素中的确切位置。
首先,我们来看如何获取元素在页面中的位置。你拥有几个可支配的元素属性可用来找到这一信息。所有的现代浏览器都支持以下三个属性;当然它们各自是怎么处理的,又是另外一回事了:
offsetParent: 理论上,这是元素在其中定位的父级元素。但是在实际情况下,offsetParent引用的元素取决于浏览器(比如说,在FireFox中,它引用根节点,而在Opera中,则是直接父元素。
offsetLeft和offsetTop: 这些参数是元素在其offsetParent上下文中的水平和垂直偏移。在现代浏览器上,它总是精确的。
现在,问题在于寻求一种可以跨浏览器工作的用来判定方式元素位置的一致的办法。实现这一点的最一致的办法如程序7-4所示:使用offsetParent属性沿着DOM树上行,一路累加偏移值。
程序7-4. 计算元素相对于文档的x和y坐标的辅助函数
CODE:
//计算元素的X(水平,左)位置
function pageX(elem) {
//检查我们是否已经到了根元素
return elem.offsetParent ?
//如果我们还能往上,则将当前偏移与向上递归的值相加
elem.offsetLeft + pageX( elem.offsetParent ) :
//否则,取当前偏移
elem.offsetLeft;
}
//计算元素的Y(垂直,顶)位置
function pageY(elem) {
//检查我们是否已经到了根元素
return elem.offsetParent ?
//如果我们还能往上,则将当前偏移与向上递归的值相加
elem.offsetTop + pageY( elem.offsetParent ) :
//否则,取当前偏移
elem.offsetTop;
}
定位问题的另一部分是计算元素在其父元素中的偏移。需要注意的重要的一点是,简单地使用元素的style.left或style.top属性是不够的,因为你可能想要找出没有用Javascript或CSS定义样式的元素的位置。
使用元素相对于其父元素的位置,你可以向DOM添加额外的相对该父元素定位的元素。比如,这个值用来建造上下文相关的工具提示是非常理想的。
为了找到元素相对于其父元素的位置,你必须再一次求助于offsetParent属性。因为该属性并不能保证返回特定元素的实际的父元素,你不得不使用你的pageX和pageY函数来找到父元素与子元素之间的位置差异。在程序7-5所示的两个函数中,我试图首先使用offsetParent,如果它是当前元素的实际的父元素;否则,我将继续使用pageX和pageY方法沿DOM上行,以确定它的实际位置。
程序7-5. 用来确定元素相对于其父元素位置两个函数
CODE:
//查找元素在其父元素中的垂直位置
function parentX(elem) {
//如果offsetParent就是元素的parent,则提前返回
return elem.parentNode == elem.offsetParent ?
elem.offsetLeft :
//否则,我们需要找出两个元素相对整个页面的位置,计算差值
pageX( elem ) - pageX( elem.parentNode );
}
//查找元素在其父元素中的垂直位置
function parentY(elem) {
//如果offsetParent就是元素的parent,则提早返回
return elem.parentNode == elem.offsetParent ?
elem.offsetTop :
//否则,我们需要找出两个元素相对整个页面的位置,计算差值
pageY( elem ) - pageY( elem.parentNode );
}
定位问题的最后一方面是找出元素相对于其CSS容器的位置。如前面所讨论的,元素可能实际被包含在一个元素中而相对于另一个元素被定位(通过使用相对和绝对定位)。记住这一点,你可以回头利用getStyle函数来得出计算后的CSS偏移值,因为那正是等效的定位。
有两个可用的简单的包装函数可以处理这一点,如程序7-6所示。它们都只是简单调用getStyle函数,但同时也删除任何多余的(除非你不是使用基于像素的布局,它才是有用的)单位信息(比如说,100px将变成100)。
程序7-6. 找出元素的CSS定位的辅助函数
//得到元素的left位置
function posX(elem) {
//取得计算后样式并从中提取数字
return parseInt( getStyle( elem, "left" ) );
}
//得到元素的top位置
function posY(elem) {
//取得计算后的样式并从中提取数字
return parseInt( getStyle( elem, "top" ) );
}
设置元素位置 不同于取得元素的的位置,设置位置要少许多变数。但是联合使用各种方式的布局(absolut,relative,fixed)时,你将能得到相当的、可用的结果。 目前,调整元素位置的唯一的办法是通过修改它的CSS属性。为了保持方法上的一致性,你应该仅修改left和top属性,尽管存在着其它的属性(如bottom和top)。作为开端,你可以轻松地创建一对函数,如程序7-7所示,用来设置一个元素的位置,而不考虑其当前位置。 程序7-7. 不考虑其当前位置,设置元素的x和y位置的一对函数 [Copy to clipboard] [ - ] //设置元素垂直位置的一个函数 最终,你需要开发第二套函数,如程序7-8所示,你可以用它们来设置一个元素相对于其原来的位置的位置——比如,调整一个元素使其水平位置比当前值小5个像素。这一方法的使用直接与许多作为DHTML开发的支柱的动画效果相关。 程序7-8. 用来调整元素相对于基原来的位置的一对函数 [Copy to clipboard] [ - ] //用来把元素的水平位置增加几个像素的一个函数 现在我已经将处理元素位置的问题完全贯串了一遍。理解元素定位怎样工作和怎么设置及获取元素的精确位置是处理动态元素的一个基本的方面。你将看到的下一个侧面是元素的确切尺寸。 元素的尺寸 计算元素的高度和宽度可能是既无比简单又痛苦的一件事,这取决于具体的情况和你需要它做什么。许多情况下,你只需要使用getStyle函数的一个修改版本来得到元素的当前宽度和高度,如程序7-9所示。 程序7-9. 检索DOM元素的当前高度和宽度的两个函数 [Copy to clipboard] [ - ] //获取元素的实际高度(使用计算后的CSS) 当你试图做这两件事的时候麻烦就来了:第一,当你想要得到元素预定义的完整高度(比如说,你将一个动画从0px开始,但你需要知道该元素应该到达多高多宽),第二,当一个元素的display设为"none"时,你将取不到值。 程序7-10. 用来找出元素的潜在高度和宽度的两个函数,即使元素是隐藏的 [Copy to clipboard] [ - ] //找出元素完整的、可能的高度(不是实际的、当前的高度) 同时拥有了取得元素当前的和潜在的宽度与高度的能力,你可以使用这些值来开发出一些你能够达到的动画。但是,在我进入动画的细节之前,你还需要看看怎样修改元素的可见性。 元素的可见性 元素的可见性是可在JavaScript中用来创建从动画到快速模板效果的每一样东西的强大工具。然而,更重要的是,它也能用来从视图中快速地隐藏元素,提供一些基本的用户界面功能。 程序7-11. 使用CSS Display属性来切换元素的可见性的一组函数 [Copy to clipboard] [ - ] //用来(使用display)隐藏元素的一个函数 可见性的另一面是元素的透明度。调整元素透明度产生的结果与设置元素的visibility非常相似,但是了对元素有多可见的更好的控制。这意味着你可以使一个元素50%可见,使得你可以看到在它下面的元素。所有的现代浏览器都在一定程度上支持透明度,IE和W3C兼容的浏览器再一次在实现方式上有着不同。为了解决这一问题,你可以建创一个标准的函数用来维护元素的透明度,如7-12所示。level为0表示着元素是完全透明的,而level为100表示完全不透明。 程序7-12. 调整元素的透明度级别的一个函数 [Copy to clipboard] [ - ] //设置元素的透明度级别(level是0-100的数字) 掌握了调整元素的位置、大小、及可见性的方法,是时候开始探索你联合使用这些能力做一些有意思的事情了。 [ 本帖最后由 mozart0 于 2007-5-25 15:42 编辑 ] |
one by one |
[广告] 网站博客卖广告推荐:阿里妈妈 |
mozart0 [楼主] 匪徒田老大 版主 帖子 2326 |
|
mozart0 [楼主] 匪徒田老大 版主 帖子 2326 |
|
mozart0 [楼主] 匪徒田老大 版主 帖子 2326 |
|
mozart0 [楼主] 匪徒田老大 版主 帖子 2326 |
|
mozart0 [楼主] 匪徒田老大 版主 帖子 2326 |
csf178 初级会员 帖子 86 |
|