ppk谈JavaScript style属性


Posted in Javascript onOctober 10, 2008

事实上,7个范例脚本都用到了某种形式的CSS修改。比如,“表单验证”改变出错的表单域的样式,“XMLHTTP速度测试计”使用动画(其实也就是在很短的时间内多次改变某个样式)来让用户注意到速度的数据(而且,老实讲这算是有些花哨的效果)。“下拉菜单”通过改变样式来显示和隐藏菜单项。这些变化都拥有同样的目的:把用户的注意力吸引到这些元素上。

JavaScript有如下4种修改CSS的方式:

l 修改元素的style属性(element.style.margin='10%');

l 改变元素的class或id(element.className='error'),浏览器将自动应用那些定义在新的class或id上的样式;

l 向文档中写入新的CSS指令(document.write('<style>.accessibility{display: none}</style>');

l 改变整个页面的样式表。

大多数的CSS改变脚本,都采用修改style属性或改变class或id的方式。document.write方法只适合用于某些特定的场合以增强页面的可访问性。最后,我们很少会改变整个样式表,因为并非所有的浏览器都支持这样做,而且通常你也只是想改变某些特定元素的样式。

不管怎么说,我在范例脚本中使用了所有4种方法。我们将在本章中逐个研究这些方法及它们适用的场合。

A style属性

最初也是最广为人知的修改CSS的方式就是通过所有HTML元素都拥有的style属性,并且访问它们的内联样式,style对象对每一个内联的CSS声明都包含一个对应的属性。如果你想设置一个元素的CSS属性margin,使用element.style.margin。如果你想要设置它的CSS属性color,就使用element.style.color。JavaScript属性总是拥有一个和CSS属性相似的名字。

内联样式

记住:HTML元素的style属性让我们得以访问该元素的内联样式。

让我们来回顾一些CSS的理论。CSS提供4种方式来给元素定义样式表。你可以使用内联样式,即直接把你的CSS写在HTML标签的style属性中。

<p style="margin: 10%">Text</p>

此外,你可以嵌入、链入或引入样式表。不管用何种方法,因为内联样式比其他任何形式的样式更为明确,内联样式能覆盖那些嵌入、链入或引入页面的样式表中定义的样式。因为style属性可以访问这些内联样式,所以它总是能覆盖其他的样式。这是这种方法的巨大优势。

然而,当你尝试读取样式时,可能遭遇问题。看这个例子:

<p id="test">Text</p>

p#test {

margin: 10%;

}

alert(document.getElementById('test').style.margin);

测试段落并没有包含任何内联样式,margin: 10%是被定义在一个嵌入的(或者链入,或者引入的)样式表中,而它是不可能从style属性中读出来的。弹出警告框显示为空。

在下一个例子中,弹出警告框将显示返回结果“10%”,因为margin现在被定义为内联样式:

<p style="margin: 10%" id="test">Text</p>

alert(document.getElementById('test').style.margin);

所以,style属性最适合于设置样式,而要获取它们时就没那么有用了。后面我们会讨论从嵌入页面的、链入的或者引入的样式表中获取样式的方法。

破折号

许多CSS属性的名字包含一个破折号,例如font-size。然而在JavaScript中,破折号表示相减(minus),因此它不能被用在属性名中。这将给出一个错误:

element.style.font-size = '120%';

这是要求浏览器从element.style.font里减去(未定义的)变量size吗?如果是= '120%'代表什么意义呢?作为替代,浏览器期望一个驼峰格式(camelCase)的属性名:

element.style.fontSize = '120%';

一般规则是从CSS属性名中移除所有的破折号,并且破折号后的字符变为大写。这样,margin-left变成了marginLeft,text-decoration变成了textDecoration,而border-left -style变成了borderLeftStyle。

单位

在JavaScript很多数值类型的值需要一个单位,就像它们在CSS中声明时那样。fontSize=120表示什么?120像素、还是120磅或者120%?浏览器可不知道这些,所以它不会做任何反应。为了阐明你的意图,单位是必须的。

以setWidth()函数为例,它是实现“XMLHTTP测速计”的动画效果的核心程序之一:

[XMLHTTP测速计,第70~73行]

function setWidth(width) {

if (width < 0) width = 0;

document.getElementById('meter').style.width = width + 'px';

}

该函数接手一个值,它将改变meter的宽度为这个新值。在经过一个安全检查以确保该值大于0之后,设置元素的style.width为这个新的宽度值。最后加上'px',因为不这样的话,浏览器可能不知道如何解释该数值,结果什么都不做。

不要忘了'px'

忘记在width或height之后附加一个'px'单位是一个常见的CSS修改错误。

在CSS的怪癖模式(quirks mode)里,加上'px'不是必须的,因为浏览器遵循旧的规则,把无单位的值视为像素值。本质上这不是一个问题,但很多Web开发人员因此养成了改变宽度或高度值后遗忘加上单位的习惯,当他们工作在CSS严格模式(strict mode)下时就遭遇到了问题。

获取样式

警告 以下所述内容有浏览器兼容性问题。

正如我们所看到的,style属性不能读取设置在嵌入、链入或引入页面的样式表中的样式。但是因为Web开发人员有时候需要读取这些样式,微软和W3C都提供了访问非内联样式的方式。微软的解决方案只能工作在Explorer下,而W3C标准可以工作在Mozilla和Opera下。

微软的解决方案就是currentStyle属性,它的工作方式像极了style属性,除了两件事情:

l 它可以访问所有样式,不仅仅是内联样式,所以它汇报的是实际应用在元素上的样式;

l 它是只读的,你不能通过它设置样式。

例如:

var x = document.getElementById('test');

alert(x.currentStyle.color);

现在弹出对话框显示元素当前的color样式,而不管它是在什么地方被定义的。

W3C的解决方案是window.getComputedStyle()方法,它以相似但语法更为复杂的方式工作:

var x = document.getElementById('test');

alert(window.getComputedStyle(x,null).color);

getComputedStyle()总是返回一个像素值,尽管原来的样式可能会是50em或11%。

同以前一样,当我们遭遇不兼容的情形时,需要一些代码分支来满足所有浏览器:

function getRealStyle(id,styleName) {

var element = document.getElementById(id);

var realStyle = null;

if (element.currentStyle)

realStyle = element.currentStyle[styleName];

else if (window.getComputedStyle)

realStyle = window.getComputedStyle(element,null)[styleName];

return realStyle;

}

你可以使用这个函数如下:

var textDecStyle = getRealStyle('test','textDecoration');

记住getComputedStyle()将总是返回一个像素值,而currentStyle保留原来定义在CSS中的单位。

简写样式

警告 以下所述内容有浏览器兼容性问题。

不管你是通过style属性获得内联样式,还是通过刚刚讨论的函数获取其他的样式,当你尝试读取简写样式时,都会遇到问题。

看这个边框(border)的定义

<p id="test" style="border: 1px solid #cc0000;">Text</p>

因为这是一个内联样式,你期望这行代码可以工作:

alert(document.getElementById('test').style.border);

不幸的是,它不能。不同浏览器在弹出对话框中显示的确切的值是不一致的。

l Explorer 6给出的是 #cc0000 1px solid。

l Mozilla 1.7.12给出的是1px solid rgb(204,0,0)。

l Opera 9给出的是1px solid #cc0000。

l Safari 1.3没有给出任何边框值。

问题出在border是一个简写形式的声明。它暗中包括了不少于12个样式:上(top)、左(left)、下(bottom)和右(right)边框的宽度(width)、风格(style)和颜色(color)。相似地,font声明是font-size、font-family、font-weight和line-height的简写形式,所以它也会展现相似的问题。

rgb()

注意Mozilla使用的特殊的color语法:rgb(204,0,0)。这是传统的#cc0000的有效的替代值。你可以在CSS和JavaScript中任意选择一个语法使用。

浏览器是如何处理这些简写形式的声明呢?上面的例子似乎过于直接;你的直觉应该是期望浏览器返回1px solid #cc0000,确保与内联样式所定义的一致。不幸的是,简写形式的属性比那还复杂的多。

考虑下面的情形:

p {

border: 1px solid #cc0000;

}

<p id="test" style="border-color: #00cc00;">Test</p>

alert(document.getElementById('test').style.borderRightColor);

所有浏览器都汇报正确的颜色,尽管内联样式中没有包含border-right-color而是声明了border-color。显然浏览器认为右边框的颜色在设置整个边框颜色时被设置,这也是合逻辑的。

正如你看到的,浏览器必须为这些异常情况制定规则,而且它们已经选择了略有不同的方式去处理简写形式的声明。在缺乏处理简写属性的明确规范的情况下,很难评判哪个浏览器是对还是错。

Javascript 相关文章推荐
javascript学习笔记(五) Array 数组类型介绍
Jun 19 Javascript
JS 实现Table相同行的单元格自动合并示例代码
Aug 27 Javascript
JavaScript给url网址进行encode编码的方法
Mar 18 Javascript
JS+CSS实现大气清新的滑动菜单效果代码
Oct 22 Javascript
jQuery插件之Tocify动态节点目录菜单生成器附源码下载
Jan 08 Javascript
HTML5 js实现拖拉上传文件功能
Nov 20 Javascript
利用JS实现文字的聚合动画效果
Jan 22 Javascript
js选项卡的制作方法
Jan 23 Javascript
js获取隐藏元素的宽高
Feb 24 Javascript
Vue的路由动态重定向和导航守卫实例
Mar 17 Javascript
Vue多系统切换实现方案
Jun 05 Javascript
原生JS实现汇率转换功能代码实例
May 13 Javascript
用javascript getComputedStyle获取和设置style的原理
Oct 10 #Javascript
执行iframe中的javascript方法
Oct 07 #Javascript
JS版网站风格切换实例代码
Oct 06 #Javascript
判断JavaScript对象是否可用的最正确方法分析
Oct 03 #Javascript
IE与firefox之jquery用法区别
Oct 03 #Javascript
jquery的颜色选择插件实例代码
Oct 02 #Javascript
初学JavaScript_03(ExtJs Grid的简单使用)
Oct 02 #Javascript
You might like
用PHP制作静态网站的模板框架(一)
2006/10/09 PHP
PHP中4个加速、缓存扩展的区别和选用建议
2014/03/12 PHP
PHP 5.3和PHP 5.4出现FastCGI Error解决方法
2015/02/12 PHP
Yii控制器中filter过滤器用法分析
2016/07/15 PHP
一键生成各种尺寸Icon的php脚本(实例)
2017/02/08 PHP
PHP类的自动加载与命名空间用法实例分析
2020/06/05 PHP
JS面向对象、prototype、call()、apply()
2009/05/14 Javascript
prototype 学习笔记整理
2009/07/17 Javascript
JavaScript mapreduce工作原理简析
2012/11/25 Javascript
jquery时间下拉框小例子
2013/04/15 Javascript
点击按钮自动加关注的代码(sina微博/QQ空间/人人网/腾讯微博)
2014/01/02 Javascript
编程语言JavaScript简介
2014/10/16 Javascript
判断字符串的长度(优化版)中文占两个字符
2014/10/30 Javascript
javascript实现禁止复制网页内容
2014/12/16 Javascript
延时加载JavaScript代码提高速度
2015/12/27 Javascript
javascript 删除数组元素和清空数组的简单方法
2017/02/24 Javascript
ActiveX控件的使用-js实现打印超市小票功能代码详解
2017/11/22 Javascript
微信小程序收藏功能的实现代码
2018/06/12 Javascript
js实现3D旋转效果
2020/08/18 Javascript
[03:39]DOTA2英雄梦之声_第05期_幽鬼
2014/06/23 DOTA
[45:15]Optic vs VP 2018国际邀请赛淘汰赛BO3 第一场 8.24
2018/08/25 DOTA
[03:01]完美盛典趣味短片 DOTA2年度最佳&拉胯英雄
2019/12/07 DOTA
[01:11:21]DOTA2-DPC中国联赛 正赛 VG vs Elephant BO3 第一场 3月6日
2021/03/11 DOTA
python+mysql实现简单的web程序
2014/09/11 Python
wxPython窗口的继承机制实例分析
2014/09/28 Python
使用Python编写简单网络爬虫抓取视频下载资源
2014/11/04 Python
Flask框架响应、调度方法和蓝图操作实例分析
2018/07/24 Python
攻击者是如何将PHP Phar包伪装成图像以绕过文件类型检测的(推荐)
2018/10/11 Python
详解Python并发编程之从性能角度来初探并发编程
2019/08/23 Python
新年福利来一波之Python轻松集齐五福(demo)
2020/01/20 Python
python 如何实现遗传算法
2020/09/22 Python
JDBC操作数据库的基本流程是什么
2014/10/28 面试题
建筑工程技术应届生求职信
2013/11/17 职场文书
小学科学教学反思
2014/01/26 职场文书
2014年教师节寄语
2014/04/03 职场文书
数据保密承诺书
2014/06/03 职场文书