ppk谈JavaScript style属性

事实上,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。显然浏览器认为右边框的颜色在设置整个边框颜色时被设置,这也是合逻辑的。

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

(0)

相关推荐

  • ppk谈JavaScript style属性

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

  • PPK 谈 JavaScript 的 this 关键字 [翻译]

    下面先讲如何在event handling(事件处理)中用它,再接着是讲 this 的其他用法. 自己本身 先来看看函数 doSomething() 里的 this 到底是指向(refer to)了什么? function doSomething() { this.style.color = '#cc0000'; } JavaScript的 this 总指向所运行的函数"自己本身".也就是说,它是一种指向函数对象的方法.在页面中定义 doSomething() 函数,自己本身是指页面.

  • 浅谈javascript 函数属性和方法

    每个函数都包含两个属性:length 和 prototype         length:当前函数希望接受的命名参数的个数         prototype:是保存他们所有实力方法的真正所在 复制代码 代码如下: function sayName(name) {             alert(name);         }         function sum(num1, num2) {             return num1 + num2;         }     

  • 浅谈Javascript数据属性与访问器属性

    ES5中对象的属性可以分为'数据属性'和'访问器属性'两种. 数据属性一般用于存储数据数值,访问器属性对应的是set/get操作,不能直接存储数据值. 数据属性特性:value.writable.enumerable.configurable. 解释:configurable:true/false,是否可以通过delete删除属性,能否修改属性的特性,能否把属性修改为访问器属性,默认false: enumerable:true/false,是否可以通过for in循环返回,默认false: wr

  • 浅谈JavaScript 数据属性和访问器属性

    在JavaScript中对象被定义为"无序属性的集合,其属性可以包含基本值.对象或函数."通俗点讲,我们可以把对象理解为一组一组的名值对,其中值可以是数据或函数. 创建自定义对象通常有两种方法,第一种就是创建一个Object的实例,然后再为其添加属性和方法,例如: var person = new Object(); person.name = "Scott"; person.age = 24; person.sayName = function(){ alert(

  • 浅谈JavaScript中的属性:如何遍历属性

    在JavaScript中,遍历一个对象的属性往往没有在其他语言中遍历一个哈希(有些语言称为字典)的键那么简单.这主要有两个方面的原因:一个是,JavaScript中的对象通常都处在某个原型链中,它会从一个或多个的上层原型上继承一些属性.第二个原因是,JavaScript中的属性不光有值,它还有一些除了值以外的其他特性,其中一个影响属性遍历的特性就是[[Enumerable]],如果该值为true,则称这个属性是可枚举的,否则反之. 知道了这些,我们就可以把属性的遍历分为四种情况. 注:示例代码中

  • 浅谈javascript属性onresize

    浅谈javascript属性onresize //获取屏幕宽度并动态赋值 var winWidth = 0; var winHeight = 0; function findDimensions() //函数:获取尺寸 { //获取窗口宽度 if (window.innerWidth) winWidth = window.innerWidth; else if ((document.body) && (document.body.clientWidth)) winWidth = docum

  • 浅谈JavaScript中你可能不知道URL构造函数的属性

    URL URL 是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址.互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它, 在 Web 开发中,有许多情况需要解析 URL,这篇主要学习如何使用 URL 对象实现这一点 例如,这里是这篇博客文章的路径: https://www.vipbic.com/thread.html?id=101 通常您需要访问 URL 的特定属性.这些可能是主机名(例如 vipbic

  • 浅谈JavaScript 中的延迟加载属性模式

    目录 一.前言 二.按需属性模式 三.凌乱的延迟加载属性模式 四.类的唯一自己的延迟加载属性模式 五.对象字面量的延迟加载属性模式 六.结论 一.前言 传统上,开发人员在 JavaScript 类中为实例中可能需要的任何数据创建属性.对于在构造函数中随时可用的小块数据来说,这不是问题.但是,如果在实例中可用之前需要计算某些数据,您可能不想预先支付该费用.例如,考虑这个类: class MyClass { constructor() { this.data = someExpensiveCompu

  • 浅谈JavaScript 浏览器对象

    window window对象不但充当全局作用域,而且表示浏览器窗口. window对象有innerWidth和innerHeight属性,可以获取浏览器窗口的内部宽度和高度.内部宽高是指除去菜单栏.工具栏.边框等占位元素后,用于显示网页的净宽高.还有一个outerWidth和outerHeight属性,可以获取浏览器窗口的整个宽高. 补充: 网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:

随机推荐