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 相关文章推荐
Node.js 的异步 IO 性能探讨
Oct 08 Javascript
js实现屏幕自适应局部代码分享
Jan 30 Javascript
jQuery实现单击弹出Div层窗口效果(可关闭可拖动)
Sep 19 Javascript
纯js代码制作的网页时钟特效【附实例】
Mar 30 Javascript
基于JavaScript实现活动倒计时效果
Apr 20 Javascript
JS设置手机验证码60s等待实现代码
Jun 14 Javascript
浅谈webpack编译vue项目生成的代码探索
Dec 11 Javascript
JS防抖和节流实例解析
Sep 24 Javascript
Vue.directive 实现元素scroll逻辑复用
Nov 29 Javascript
javascript贪吃蛇游戏设计与实现
Sep 17 Javascript
利用Vue实现简易播放器的完整代码
Dec 30 Vue.js
关于Javascript闭包与应用的详解
Apr 22 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
CPU步进是什么意思?i3-9100F B0步进和U0步进区别知识科普
2020/03/17 数码科技
如何开始收听短波广播
2021/03/01 无线电
php 小乘法表实现代码
2009/07/16 PHP
PHP使用array_fill定义多维数组的方法
2015/03/18 PHP
浅析Yii2 GridView实现下拉搜索教程
2016/04/22 PHP
PHP从零开始打造自己的MVC框架之路由类实现方法分析
2019/06/03 PHP
javascript+css 网页每次加载不同样式的实现方法
2009/12/27 Javascript
jquery 1.4.2发布!主要是性能与API
2010/02/25 Javascript
Javascript技巧之不要用for in语句对数组进行遍历
2010/10/20 Javascript
jQuery源码分析-03构造jQuery对象-源码结构和核心函数
2011/11/14 Javascript
javascript的解析执行顺序在各个浏览器中的不同
2014/03/17 Javascript
Ext GridPanel加载完数据后进行操作示例代码
2014/06/17 Javascript
escape函数解决js中ajax传递中文出现乱码问题
2014/10/30 Javascript
node.js中的dns.getServers方法使用说明
2014/12/08 Javascript
js实现向右横向滑出的二级菜单效果
2015/08/27 Javascript
javascript学习小结之prototype
2015/12/03 Javascript
jQuery动画效果实现图片无缝连续滚动
2016/01/12 Javascript
AngularJs Managing Service Dependencies详解
2016/09/02 Javascript
Vue 2.0 侦听器 watch属性代码详解
2019/06/19 Javascript
Node.js 实现抢票小工具 &amp; 短信通知提醒功能
2019/10/22 Javascript
Vue关于组件化开发知识点详解
2020/05/13 Javascript
vue3.0 项目搭建和使用流程
2021/03/04 Vue.js
Python获取Linux系统下的本机IP地址代码分享
2014/11/07 Python
python自定义类并使用的方法
2015/05/07 Python
python返回昨天日期的方法
2015/05/13 Python
Python3操作SQL Server数据库(实例讲解)
2017/10/21 Python
Python实现的HMacMD5加密算法示例
2018/04/03 Python
德国购买健身器材:AsVIVA
2017/08/09 全球购物
医大实习自我鉴定
2013/12/07 职场文书
一年级语文教学反思
2014/02/13 职场文书
公司寄语大全
2014/04/10 职场文书
家长高考寄语
2015/02/27 职场文书
Pandas||过滤缺失数据||pd.dropna()函数的用法说明
2021/05/14 Python
详解PHP服务器如何在有限的资源里最大提升并发能力
2021/05/25 PHP
MySQL中出现乱码问题的终极解决宝典
2021/05/26 MySQL
python中if和elif的区别介绍
2021/11/07 Python