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中的高阶函数介绍
Mar 15 Javascript
javascript中callee与caller的区别分析
Apr 20 Javascript
JavaScript 消息框效果【实现代码】
Apr 27 Javascript
使用Script元素发送JSONP请求的方法
Jun 12 Javascript
js制作支付倒计时页面
Oct 21 Javascript
微信开发 使用picker封装省市区三级联动模板
Oct 28 Javascript
微信小程序 高德地图SDK详解及简单实例(源码下载)
Jan 11 Javascript
JS实现集合的交集、补集、差集、去重运算示例【ES5与ES6写法】
Feb 18 Javascript
layui异步加载table表中某一列数据的例子
Sep 16 Javascript
Vue3.0 响应式系统源码逐行分析讲解
Oct 14 Javascript
微信小程序仿淘宝热搜词在搜索框中轮播功能
Jan 21 Javascript
javascript中的with语句学习笔记及用法
Feb 17 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 socket(fsockopen)的应用实例分析
2013/06/02 PHP
php 表单提交大量数据发生丢失的解决方法
2014/03/03 PHP
PHP大神的十大优良习惯
2016/09/14 PHP
ThinkPHP5与单元测试PHPUnit使用详解
2020/02/23 PHP
深入了解javascript中的prototype与继承
2013/04/14 Javascript
js 固定悬浮效果实现思路代码
2013/08/02 Javascript
JS+CSS实现Div弹出窗口同时背景变暗的方法
2015/03/04 Javascript
jquery动态导航插件dynamicNav用法实例分析
2015/09/06 Javascript
smartcrop.js智能图片裁剪库
2015/10/14 Javascript
深入理解js函数的作用域与this指向
2016/05/28 Javascript
BOM系列第二篇之定时器requestAnimationFrame
2016/08/17 Javascript
EditPlus中的正则表达式 实战(2)
2016/12/15 Javascript
基于vue实现分页效果
2017/11/06 Javascript
Angular实现较为复杂的表格过滤,删除功能示例
2017/12/23 Javascript
React BootStrap用户体验框架快速上手
2018/03/06 Javascript
node实现的爬虫功能示例
2018/05/04 Javascript
学习jQuery中的noConflict()用法
2018/09/28 jQuery
bootstrap-table formatter 使用vue组件的方法
2019/05/09 Javascript
解决layer弹出层msg的文字不显示的问题
2019/09/11 Javascript
Vue+Openlayers自定义轨迹动画
2020/09/24 Javascript
[02:34]DOTA2亚洲邀请赛 BG战队出场宣传片
2015/03/09 DOTA
Python urllib、urllib2、httplib抓取网页代码实例
2015/05/09 Python
python生成随机密码或随机字符串的方法
2015/07/03 Python
python 第三方库的安装及pip的使用详解
2017/05/11 Python
python中ASCII码和字符的转换方法
2018/07/09 Python
对python打乱数据集中X,y标签对的方法详解
2018/12/14 Python
Python使用pydub库对mp3与wav格式进行互转的方法
2019/01/10 Python
详解小白之KMP算法及python实现
2019/04/04 Python
python pyinstaller打包exe报错的解决方法
2019/11/02 Python
Tensorflow tf.dynamic_partition矩阵拆分示例(Python3)
2020/02/07 Python
突袭HTML5之Javascript API扩展5—其他扩展(应用缓存/服务端消息/桌面通知)
2013/01/31 HTML / CSS
东南亚冒险旅行与活动:Adventoro
2019/10/16 全球购物
表决心的诗句大全
2014/03/11 职场文书
教师年度考核评语
2014/04/28 职场文书
大学生逃课检讨书
2015/05/04 职场文书
MySQL查看表和清空表的常用命令总结
2021/05/26 MySQL