4.1 修改内联 CSS

在接触漂亮的jQuery效果之前,有必要先简单地谈一谈CSS。在前几章中,为了修改文档的外观,我们都是先在单独的样式表中为类定义好样式,然后再通过jQuery来添加或者移除这些类。一般而言,这都是为HTML应用CSS的首选方式,因为这种方式不会影响样式表负责处理页面表现的角色。但是,在有些情况下,可能我们要使用的样式没有在样式表中定义,或者通过样式表定义不是那么容易。针对这种情况,jQuery提供了.css()方法。

这个方法集getter(获取方法)和setter(设置方法)于一身。为取得某个样式属性的值,可以为这个方法传递一个字符串形式的属性名,然后同样得到一个字符串形式的属性值。要取得多个样式属性的值,可以传入属性名的数组,得到的则是属性和值构成的对象。对于backgroundColor这样由多个单词构成的属性名,jQuery既可以解释连字符版的CSS表示法(如background-color),也可以解释驼峰大小写形式(camel-cased)的DOM表示法(如backgroundColor)。

  1. //取得单个属性的值
  2. .css('property')
  3. //返回"value"
  4. //取得多个属性的值
  5. .css(['property1', 'property-2'])
  6. //返回{"property1": "value1", "property-2": "value2"}

在设置样式属性时,.css()方法能够接受的参数有两种,一种是为它传递一个单独的样式属性和值,另一种是为它传递一个由属性—值对构成的对象

  1. //单个属性及其值
  2. .css('property', 'value')
  3. //属性-值对构成的对象
  4. .css({
  5. property1: 'value1',
  6. 'property-2': 'value2'
  7. })

这些键值的集合叫对象字面量,是在代码中直接创建的JavaScript对象。

 对象字面量

一般来说,数字值不需要加引号而字符串值需要加引号。由于属性名是字符串,所以属性通常是需要加引号的。但是,如果对象字面量中的属性名是有效的JavaScript标识符,比如使用驼峰大小写形式的DOM表示法时,则可以省略引号。

使用.css()的方式与前面使用.addClass()的方式相同——将它连缀到jQuery对象后面,这个jQuery对象包含一组DOM元素。为此,我们仍以第3章的样式转换器为例,但这次使用的HTML稍有不同:

  1. <div id="switcher">
  2. <div class="label">Text Size</div>
  3. <button id="switcher-default">Default</button>
  4. <button id="switcher-large">Bigger</button>
  5. <button id="switcher-small">Smaller</button>
  6. </div>
  7. <div class="speech">
  8. <p>Fourscore and seven years ago our fathers brought forth
  9. on this continent a new nation, conceived in liberty,
  10. and dedicated to the proposition that all men are created
  11. equal.</p>
  12. ...
  13. </div>

 下载代码示例

如同本书其他HTML、CSS以及JavaScript示例一样,上面的标记只是完整文档的一个片段。如果读者想试一试这些示例,可以从以下地址下载完整的示例代码:Packt Publishing 网站 http://www.packtpub.com/support ,或者本书网站 http://book.learningjquery.com/

在通过链接的样式表为这个文档添加了一些基本样式规则之后,初始的页面如图4-1所示。

4.1.1 设置计算的样式属性值 - 图1

图 4-1

有了这些代码之后,单击Bigger和Smaller按钮,会增大或缩小<div class="speech">中文本的字体大小,而单击Default按钮,则会把<div class="speech">中文本的字体重置为初始大小。

4.1.1 设置计算的样式属性值

如果每次都增大或减小为预定的值,那么仍然可以使用.addClass()方法。但是,这次假设我们希望每单击一次按钮,文本的字体大小就会持续地递增或递减。虽然为每次单击定义一个单独的类,然后迭代这些类也是可能的,但更简单明了的方法是每次都以当前字体大小为基础,按照一个设定的系数(例如40%)来递增字体大小。

同以前一样,我们的代码仍然是从$(document).ready()$('#switcher-large').click()事件处理程序开始,参见代码清单4-1。

代码清单4-1

  1. $(document).ready(function() {
  2. $('#switcher-large').click(function() {
  3. });
  4. });

接着,通过$('div.speech').css('fontSize')可以轻而易举地取得当前的字体大小。不过,由于返回的值中包含数字值及其单位(px),需要去掉单位部分才能执行计算。同样,在需要多次使用某个jQuery对象时,最好也把这个对象保存到一个变量中,从而达到缓存数据的目的。为此,就需要引入两个变量,参见代码清单4-2。

代码清单4-2

  1. $(document).ready(function() {
  2. var $speech = $('div.speech');
  3. $('#switcher-large').click(function() {
  4. var num = parseFloat($speech.css('fontSize'));
  5. });
  6. });

$(document).ready()中的第一行代码把<div class="speech">保存到一个变量中。注意变量名$speech中的$。由于$是JavaScript变量中合法的字符,因此可以利用它来提醒自己该变量中保存着一个jQuery对象。与PHP等编程语言不同,$符号在jQuery或者说JavaScript中没有特殊的含义。

.click处理程序中,通过parseFloat()函数只取得字体大小属性中的数值部分。parseFloat()函数会在一个字符串中从左到右地查找一个浮点(十进制)数。例如,它会将字符串'12'转换成数字12。另外,它还会去掉末尾的非数字字符,因此'12px'就变成了12。如果字符串本身以一个非数字开头,那么parseFloat()会返回NaN,即Not a Number(非数字)。

至此,所剩的就是修改解析后的数值并根据新值来重设字号大小了。在这个例子中,我们要在每次按钮被单击时把字号增大40%。为此,可以将num乘以1.4,然后再连接num'px'来设置字体大小,参见代码清单4-3。

代码清单4-3

  1. $(document).ready(function() {
  2. var $speech = $('div.speech');
  3. $('#switcher-large').click(function() {
  4. var num = parseFloat($speech.css('fontSize'));
  5. num *= 1.4;
  6. $speech.css('fontSize', num + 'px');
  7. });
  8. });

现在,当用户单击Bigger按钮时,文本会变大,再次单击,会继续变大,如图4-2所示。

4.1.1 设置计算的样式属性值 - 图2

图 4-2

要通过单击Smaller按钮减小字体大小,应该使用除法而不是乘法,即num /= 1.4。同样,更好的方案是把对这两个按钮的单击操作,通过<div id="switcher">中的<button>元素组合到一个.click()处理程序中。在查找到数值后,再根据用户单击的按钮ID来决定使用乘法还是除法,如代码清单4-4。

代码清单4-4

  1. $(document).ready(function() {
  2. var $speech = $('div.speech');
  3. $('#switcher button').click(function() {
  4. var num = parseFloat($speech.css('fontSize'));
  5. if (this.id== 'switcher-large') {
  6. num *= 1.4;
  7. } else if (this.id== 'switcher-small') {
  8. num /= 1.4;
  9. }
  10. $speech.css('fontSize', num + 'px');
  11. });
  12. });

根据第3章学习的内容,我们知道可以访问由this引用的DOM元素的id属性,因而就有了ifelse if语句中的代码。这里,如果仅测试属性的值,使用this显然要比创建jQuery对象更有效。

如果提供一种方式能够返回字体大小的初始值当然更好了。为了做到这一点,可以在DOM就绪后立即把字体大小保存在一个变量中。然后,当用户单击Default按钮时,再使用这个变量的值。虽然可以通过再添加一个else if语句来处理这次单击,但此时改用switch语句应该更合适,参见代码清单4-5。

代码清单4-5

  1. $(document).ready(function() {
  2. var $speech = $('div.speech');
  3. var defaultSize = $speech.css('fontSize');
  4. $('#switcher button').click(function() {
  5. var num = parseFloat($speech.css('fontSize'));
  6. switch (this.id) {
  7. case 'switcher-large':
  8. num *= 1.4;
  9. break;
  10. case 'switcher-small':
  11. num /= 1.4;
  12. break;
  13. default:
  14. num = parseFloat(defaultSize);
  15. }
  16. $speech.css('fontSize', num + 'px');
  17. });
  18. });

在此,仍然是检查this.id的值并据以改变字体大小,但如果它的值既不是'switcherlarge'也不是'switcher-small',那么就应该使用默认的初始字体大小。

4.1.2 带厂商前缀的样式属性

浏览器厂商在引入试验性的样式属性时,通常会在实现达到CSS规范要求之前,在属性名前面添加一个前缀。等到实现和规范都稳定之后,这些属性的前缀就会被去掉,让开发人员使用标准的名称。因此,我们经常会在样式表里看到一些类似下面这样的CSS声明:

  1. -webkit-property-name: value;
  2. -moz-property-name: value;
  3. -ms-property-name: value;
  4. -o-property-name: value;
  5. property-name: value;

如果想在 JavaScript 中设置这些属性,需要提前检测它们在DOM中是否存在,从propertNameWebkitPropertyName,再到msPropertyName……都要检测。但在jQuery中,我们可以直接使用标准的属性名,比如:.css('propertyName', 'value')。如果样式对象中不存在这个属性,jQuery就会依次检测所有带前缀(WebkitOMozms)的属性,然后使用第一个找到的那个属性。