`
hax
  • 浏览: 961280 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

document.enableStyleSheetsForSet() 的兼容

阅读更多
可能有不少同学已经了解 alternate stylesheet ,不过实际上author样式表可以被设定为三类:

1. persistent style sheet:总是应用的样式表
2. preferred style sheet:默认应用的样式表
3. alternate style sheet:其他可选的样式表

我们平时通常写的样式表都是第一类,即persistent style sheet。
第二类样式表就是有title属性的样式表,比如:

<link rel="stylesheet" title="人文主义" href="...">

第三类则是这样:

<link rel="alternate stylesheet" title="古典" href="...">
<link rel="alternate stylesheet" title="Geek风" href="...">

一些浏览器(FF和Opera)可以通过菜单切换到alternate stylesheet。Safari可能也有,Chrome默认没有,但是可安装extension。

注意,切换是依据title属性互斥的,相同title的样式表称为一个样式表集(style sheet set)。比如切换到“古典”之后,原先perferred的“人文主义”就被disable了。但是persistent style sheet仍然是起作用的。

问题是如何通过脚本来切换样式表集?CSSOM规范引入了一个新的API来达成这个目的:

[Supplemental] interface Document {
  readonly attribute StyleSheetList styleSheets;
  ...
  void enableStyleSheetsForSet(DOMString? name);
};

所以简单的:
document.enableStyleSheetsForSet('Geek风')
就可以切换到“Geek风”样式表集。

FF4已经支持该方法,不过较早的版本以及使用WebKit引擎的Safari、Chrome等怎么办呢?

一种想法是遍历document.styleSheets然后根据title来设定disabled值,因为标准所规定的行为就是如此。代码如下:

// 以下代码在当前WebKit下不能work!
document.enableStyleSheetsForSet = function(name) {
    if (name != null) for (var i = 0, n = this.styleSheets.length; i < n; i++) {
        var sheet = this.styleSheets[i]
        if (sheet.title) sheet.disabled = !(sheet.title == name)
    }
}


不幸的是,上述看似合理的代码在WebKit下不能work,因为WebKit的document.styleSheets集合里根本不包括所有alternate style sheet。

那么我们是否能自行取样式集合呢?比如通过 document.querySelectorAll("style, link[rel~='stylesheet']") 。实际也是不行的,因为WebKit根本就忽略了那些alternate样式表,即使你直接设置那些样式表的 disabled = false ,也不能启用样式表(实际上它们的disabled值原本就是false)。

难道除了抱怨WebKit在这个方面不合标准之外,我们就没辙了吗?


在放弃之前,我们应该把spec翻出来再好好读读。

直接上代码:
	if (!document.enableStyleSheetsForSet) document.enableStyleSheetsForSet = function(name) {
		if (name != null) {
			var meta = document.querySelector('meta[http-equiv="default-style"]')
			if (!meta) {
				meta = document.createElement('meta')
				meta.httpEquiv = 'default-style'
				document.head.appendChild(meta)
			}
			meta.content = name
		}
	}


非常简单的实现,一切皆源自于default-style这个被人遗忘的特性。以上代码在Chrome 10下测试通过。


PS. 在上述代码里,你可能注意到了“document.head”,这也是HTML5新增的属性,但是那些更早的浏览器并没有这个属性。类似的问题还有querySelector方法。这些就作为浏览器兼容性的练习题留给读者了。




1
0
分享到:
评论

相关推荐

    火狐、谷歌、IE关于document.body.scrollTop和document.documentElement.scrollTop 以及值为0的问题

    由于不同浏览器在处理`document.body.scrollTop`和`document.documentElement.scrollTop`上的差异,开发人员需要一种跨浏览器兼容的方法来准确获取滚动位置。一种常见的方法是编写一个函数,该函数检查当前浏览器的...

    JS中关于document.all的详解

    1. **兼容性问题**:`document.all` 主要在早期版本的IE浏览器中支持,对于现代浏览器来说,推荐使用标准的方法如 `getElementById`、`querySelector` 等。 2. **性能考虑**:虽然 `document.all` 能够快速访问文档...

    document.execCommand()的用法

    虽然`document.execCommand()`提供了快速操作文档的功能,但其兼容性和安全性问题使其不再推荐用于现代Web应用的开发。对于需要复杂文本编辑功能的应用,建议使用成熟的富文本编辑器库,如Quill、CKEditor、TinyMCE...

    document.body属性.document.body.scrollTop

    5. **浏览器兼容性**:虽然大部分现代浏览器都支持 `document.body.scrollTop`,但在一些老版本的IE浏览器中可能需要使用 `document.documentElement.scrollTop` 来兼容。 6. **CSS替代方案**:有时候,为了避免...

    document.body.scrollTop用法

    - 在处理跨浏览器兼容性问题时,建议使用 `document.documentElement.scrollTop` 而不是 `document.body.scrollTop`。 - 使用 `window.scrollTo` 或 `window.scrollBy` 方法时,注意它们在不同浏览器中的兼容性差异...

    javascript document.compatMode兼容性

    JavaScript中的`document.compatMode`属性是用来检测浏览器当前的渲染模式,这对于处理跨浏览器的兼容性问题至关重要。在网页开发中,浏览器对HTML文档的解析方式有两种:Quirks Mode(怪异模式)和Standards Mode...

    document.all[]详解

    - **兼容性问题**:`document.all[]` 主要是在早期版本的 Internet Explorer 中可用,而其他现代浏览器则不支持。这意味着在跨浏览器开发时,应该避免使用该属性。 - **性能问题**:由于 `document.all[]` 包含了...

    document.frames在非IE浏览器中的解决办法

    针对`document.frames`在非IE浏览器中的兼容性问题,一个通用且被广泛采用的解决方案是使用`window.frames`。`window.frames`是所有现代浏览器都支持的标准API,它可以用来获取当前窗口中的所有iframe或frameset。 ...

    javascript里的document.all用法

    虽然`document.all`提供了一种强大且简单的方法来访问和操作页面上的所有元素,但由于其有限的兼容性,现代Web开发中并不推荐过度依赖该属性。开发者应转向使用更为标准化和广泛支持的DOM操作方法,以确保代码的跨...

    各浏览器对document.getElementById等方法的实现差异解析

    本文主要讨论的是`document.getElementById`这个常用方法在不同浏览器之间的实现区别,以及如何处理这些差异。 `document.getElementById`是一个JavaScript内置方法,用于根据指定的ID从文档中获取元素。在大部分...

    html中的内容直接下载到excel中,替换 document.execCommand(‘saveAs’)方法

    总结,HTML中的内容直接下载到Excel,不再依赖`document.execCommand('saveAs')`,而是利用`a`标签的`download`属性和Blob对象,可以实现兼容更多浏览器的导出功能。对于更高级的需求,可以考虑引入第三方库,如`...

    JS:document.all的用法

    然而,需要注意的是,`document.all`在标准浏览器中可能不受支持,因此在实际项目中,更推荐使用`document.getElementById`、`document.getElementsByName`等标准方法来访问DOM元素,以确保代码的兼容性和可维护性。

    document.all Firefox不支持

    `document.all`的使用在现代Web开发中已经非常罕见,因为它的非标准性质和浏览器兼容性问题。现代浏览器如Firefox、Chrome、Safari以及Edge等都遵循W3C的标准,推荐使用`document.getElementById`、`document....

    深入探讨:JavaScript中的`document.head`与`document.body`属性

    本文将详细探讨document.head与document.body的区别、它们的用途以及如何在实际开发中正确使用它们。 document.head和document.body是JavaScript中用于访问和操作HTML文档头部和主体的重要属性。它们在Web开发中的...

    document.layers(1) transcode.

    在上下文中,`document.layers(1) transcode`可能是尝试将旧的Netscape层转换为现代Web技术,以便与现代浏览器兼容。 `OpenLayers`是一个开源JavaScript库,专门用于创建交互式地图应用。它允许开发者在网页上轻松...

    document.getElementsByName()的用法

    ### document.getElementsByName() 的用法详解 在Web开发中,JavaScript提供了多种方法来选取HTML文档中的元素,以便开发者能够实现对页面动态操作的需求。其中`document.getElementsByName()`与`document....

    win7中vfp软件安装后出现 0: 找不到MSXML2.DOMDOCUMENT.4.0类定义

    win7中vfp软件安装后出现 0: 找不到MSXML2.DOMDOCUMENT.4.0类定义,此中是Dll文件下载,直接放在c:\windows\system目录下即可!msxml4.cab

    关于document.cookie的使用

    关于`document.cookie`的使用,这是一个在Web开发中极为关键的概念,主要用于客户端存储少量的数据,以便网站能够识别用户,提供个性化服务,或是保存用户的偏好设置等。以下将深入解析`document.cookie`的特性、...

    深入解析:`document.documentElement` 与 `document.body` 的差异及其应用

    在JavaScript的DOM操作中,document.documentElement 和 document.body 是两个非常重要的属性,它们分别代表了文档的不同部分。理解这两者之间的区别对于前端开发者来说至关重要,尤其是在进行页面布局和滚动操作时...

    document.execCommand()解析

    总结,`document.execCommand()`是前端开发中处理文本编辑的重要工具,它允许我们模拟用户的文本操作,但同时也需要注意其兼容性和替代方案的选择。随着Web技术的进步,开发者应持续关注并适应这些变化,以提供更好...

Global site tag (gtag.js) - Google Analytics