可置换风格:让样式表们轮流上阵

嗯,你已经建了个自己的网页,把它用结构化的 XHTML 标记好了。 作为一个能干的小小网页设计师,你还用样式表规划了文档的外观。你甚至还实现了一个小小的飞跃,做了好几个拿来替换的样式表,打算用它们来展示展示你的实力。

好极了。不过现在,你恐怕需要一个支持各种浏览器的方法来灵活的切换于这些样式表之间。

一、给你的站点置备样式

样式表可以与文档通过一个 link 元素的列表关联起来,这个列表放在文档的 head 部分。来自外部的样式表和文档可能有这么几种关系:永久的、首选的与可变的。

1. 永久的

这类样式表一直启用着 (也就是说,状态一直是"on"), 当然它们是与其他活动的样式表结合使用的。它们可以用来存放各种样式表均共享的那些规则。要使之永久启用,rel 属性得设为"stylesheet",而且不设置 title 属性。

比如说要让 paul.css 这个样式表永久启用,可以在 head 中包含如下 link 元素:

<link rel="stylesheet" type="text/css" href="paul.css" /> 


2. 首选的

这些页面是缺省启用的 (它们在页面载入时被设为"on")。 当用户选择了一个拿来替换的样式表时,它们就被禁用了。

要使一个样式表成为首选的,可以把 rel 属性设为"stylesheet",还得一并设置好 title 属性。

当然也能把不止一个的样式表放在一组里边,只要给它们相同的 title属性就行了。这些样式表将被成组的启用和禁用。如果定义了超过一组的样式表,第一组将优先。要使 paul.css 成为首选的, 得添上 title 属性,再给默认的样式一个名字。

<link rel="stylesheet" type="text/css" href="paul.css" title="bog standard" /> 


3. 可变的

这些样式表可以提供给访问者作为可选项来代替首选的样式表。它们能允许访问者选择他或她喜欢的方案,让这个站点个性化。它们还可以用于提高网站的亲和力。

要制定一个可置换的样式表,rel 属性可以被设置为"alternate stylesheet",title 属性也是不可少的。和"首选"的那类样式表一样,可变样式表也能通过设置同样的 title 属性来组织到一起。

还是用前面的例子吧,要使 paul.css 成为一个可变样式表,"alternate"必须加在 rel 属性上。

<link rel="alternate stylesheet" type="text/css" href="paul.css" title="wacky" /> 


注意,所有这些关系只对用 link 元素引入的外部样式表有效。

二、切换样式

一个文档刚被载入时,永久样式和首选样式都将被立即应用到文档上。而此后可变的样式表能够由用户自己选择。W3C 告诉我们,浏览器必须让我们自由选择喜欢的样式表,并建议它提供一个下拉菜单或者工具条来实现这个。

迄今为止,一切看起来都不错。我们有了几个样式表,访问者可以通过菜单选择自己喜欢的一个。但我们很快发现了一个问题,很大的问
题。Mozilla 在"view"菜单栏下提供了一个菜单来让选择想要的样式表。但 Microsoft Internet Explorer (MSIE) 却没提供这样的菜单,所以就算我们有很多样式表,却没法在 MSIE 中用到它们。

这里有一小段 JavaScript,通过 DOM 来提供一种 MSIE 和 Mozilla用户通用的样式表选择方式。用户们的偏好还能存入 cookie 中。同时因为我们照 W3C 的嘱咐使用的 link 标记,所以这个 JavaScript并不影响 Mozilla菜单的可用性,所以这可以认为是一种适度的"向下兼容"。

三、这个脚本

首先我们这个脚本必须能够区分上面三种不同的样式表类型。相对来说这还是挺简单的,毕竟我们只需要检查每个 link 元素的两个属性
而已。

这是否一个到样式表的链接?

HTMLLinkElement.getAttribute("rel").indexOf("style") != -1 


有没有设置 title 属性?

HTMLListElement.getAttribute("title") 


rel 属性是否包含了"alternate"关键词?

HTMLLinkElement.getAttribute("rel").indexOf("alt") != -1 


注意,我们只检查"alt"字符串, 因为有些浏览器里,接受的用于标示可选样式表的关键字是"alternative"而非"alternate"。

我们可以写一个函数,运用这三个检查来进行样式表的切换。它致力于遍历文档中的每个 link 元素,禁用掉所有我们不希望启用的首选和可变样式表,同时启用所有我们打算启用的首选和可变样式表。

还要注意的是, 只有首选和可变的样式表 link 元素才有 title 属性。

于是,这个切换函数大致就像这个样子:

引用内容: 

function setActiveStyleSheet(title) {
var i, a, main;
for(i=0; (a = document.getElementsByTagName("link")); i++) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}

 


四、Cookie

现在我们可以变换样式表了,很好。就这样我们有了一个能够个性化的页面,非常好。但我们还是没有一个能够个性化的站点。因为这种对样式表的偏好仅被应用在当前页上,一旦离开了这个页面,偏好就丢失了。这个问题可以由 cookie 来矫正它。

我们需要一个新的函数来返回当前的样式表,以供存储到 cookie 中。同时我们还需要另外两个函数来读写 cookie。

只要寻找已启用的首选和可选型样式表、检查它们的 title看看是不是满足要求,就能返回当前样式表的 title 了。

具体来说,首先我们又一次的遍历文档中所有的 link 元素,检查 link 的是否一个样式表,如果是的话,再检查它是否有 title。 这就能判断出我们它是否首选的或可选的样式。

最后一步是检查这个样式表启用了没有。如果这三个检查都返回true,这一定就是当前的样式表,可以返回它的 title。

这个函数就像这样:

引用内容: 

function getActiveStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")); i++) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("title")
&& !a.disabled) return a.getAttribute("title");
}
return null;

 


由于本文是一篇关于样式的文章,而 cookie 却完全是另一个的话题,所以我不会在此解释下面这两个关于 cookie 的函数。当然我还是把它附于下边,以便你取用 (这些函数是由 ALA 的作者 Peter-Paul Koch写的)。

引用内容: 

function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca;
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;

 


我们必须给当前窗口添加 onload 和 onunload 事件监听器才能启用这些 cookie 函数。

1. onLoad

W3C 给对象规定了一个 DOM Level 2 属性,"disabled", 也就是说在样式表应用到文档时就将这个属性设为 false便可禁用掉那个样式表了。这个属性在 Mozilla 中正确实现了,但在 MSIE 中却没有。

可是 MSIE 却自己给 link 准备了一个也叫"disabled"的 HTML 属性,初始化时,所有的 link 元素的这个属性都被设为了 false。

我们可以把首选的样式表传给一个 setActiveStyleSheet() 函数,使得 MSIE 的 disabled 属性可以像 DOM Level 2 的 disabled 属性那样 (采用同样的方法) 设置。(实质上, 我们是把这两个属性都设置了一遍。)

要找出哪些才是首选的样式表,还得用到一个新的函数。因为这个函数和 getActiveStyleSheet() 太像了, 所以我想不需要解释什么,不过它大概就像这样:

引用内容: 

function getPreferredStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")); i++) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("rel").indexOf("alt") == -1
&& a.getAttribute("title")
) return a.getAttribute("title");
}
return null;

 


在 onload 函数中,我们首先设置好 title 变量, 这个变量的值要么是已经存进 cookie 里面的先前那个样式表的 title,要么cookie 里没有,就是我们首选的样式表的 title 了。 我们很自然地把这个cookie 命名为"style"。

下一步我们把 title 变量传给 setActiveStyleSheet() 函数。于是onload 函数就像这样:

引用内容: 

window.onload = function(e) {
var cookie = readCookie("style");
var title = cookie ? cookie : getPreferredStyleSheet();
setActiveStyleSheet(title);

 


注意,这个 onload 函数最好在 onload 事件之前调用,这才能使文档在一开始就按照我们的喜好用正确的样式表呈现出来。

如果你决定这么做的话,得确保这个函数在在其他函数和 link 元素都定义好以后才被调用。

2. onUnload

在 onunload 事件时保存 cookie 就简单得多了。我们只需要使用那个 getActiveStyleSheet() 函数来获取启用的样式表, 把它保存进cookie 中即可。因而这个函数是这样的:

引用内容: 

window.onunload = function(e) {
var title = getActiveStyleSheet();
createCookie("style", title, 365);

 


五、统统放在一起吧

你可以把这些函数包含于你的文档中,便能使你的网站更加性感了。如果希望一切从简的话,我已经把这些函数一齐放进了一个 JavaScript 文件中,你马上就可以下载下来,放进你的站点中。

下载 styleswitcher.js (../scripts/styleswitcher.js)

你可以在你的文档 head 部分中加入一个 script 元素来包含这个文件,但得确保它放在样式表的 link 元素下边。HTML 代码是这样的:

引用内容: 

<script type="text/javascript" 
src="/scripts/styleswitcher.js"></script> 
 


要让访问者改变启用的样式表,你可以使用 JavaScript 的 onClick事件。比如说要提供切换于以"default"和"paul"为 title 的两套样式表之间的选项,可以使用如下 HTML:

引用内容: 

<a href="#" 
οnclick="setActiveStyleSheet('default'); 
return false;">change style to default</a>

<a href="#" 
οnclick="setActiveStyleSheet('paul'); 
return false;">change style to paul</a> 
 


一旦访问者选择了一套样式表,它的 title 就被存放在了 cookie 中,如果你希望在整个站点都呈现同样的一套样式表的话,那这个站点的每个页面都必须在 head 部分包含相同的样式表和 JavaScript的链接。

http://www.zjwz.net/beyond/blogview.asp?logID=262
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值