TAT.dorsywang 【PowerfulJS】1~使用 JS 操作 HTML 文档
In 未分类 on 2013年12月06日 by view: 8,487
3

做为一个刚吃过肉的人,看过大海,思考过人生,决定还是要静下心做点总结。

最近在做 Web 工具,做为一个在 Web 中运行的工具,想要做强大的事情,在不依赖于 Server 端的支持、不依赖插件下,还要完成这些事情,有时候想想,确实是一件很难的事情。取决于

浏览器是服务端的代码运行于客户端,出于安全性的考虑,做了很多限制。浏览器是一个相对封闭的环境,说白了,能力有限。

但是,想想人生,虽然很艰难,还是要快乐的走下去。

比如

  • 把对 JS 对 DOM 修改保存到文档中,JS 只能望洋兴叹
  • 比如一个很好的图片,保存到本地指定路径,JS 也只能泪水满地

因为

  • 浏览器的 JS 运行在一个封闭的环境

但想想做了这么多年的前端,JS 还是蛮强大的,它的封闭或许会给我们一些其他的解决方案。

使用 JS 来操作 CSS

现在的需求是,我要做一个类似 F12 的工具,查看当前元素被应用上 CSS 规则并可以修改它,然后实时生效这些规则,并且给出在相应文档中做出的修改。

这个需求有两个难点,

  1. 要把 CSS 文档中命中的规则找出来(甚至告诉我们它在哪个 CSS 文档的第几行代码做的定义)。
  2. 要给出修改后的整齐的文档

所幸依赖于 Chrome 这样的老爸,JS 也变的很有能力。

命中 CSS 的规则只需要使用挂载在 Window 上的全局函数 getMatchedCSSRules 就能拿到通过命中的 CSS 规则,getMatchedCSSRules 函数接受一个 dom 元素做为参数,返回一个 CSSRuleList 集合

返回的 CSSRuleList 类似 [CSSStyleRule, CSSStyleRule, ....]
而 CSSStyleRule 定义如下

其实拿到 cssText,我们可以做一些简单的解析

css 上下文无关文法是
cssBlockDefition -> selectorText{styleDefition}cssBlockDefition | 空串
styleDefition -> name:value;styleDefition | 空串
......

其中,斜体是非终结符
这里只列我们关心的串定义,可见还是很简单的,由于使用 JS,正则已经把我们写好,而且命中的规则都是通过语法检查的,所以直接用正则去匹配就可以了,根据上述文法,简单写一个 demo 如下

OK,通过解析 CSS String,我们可以拿到我们想要的东西,但问题并非要走这条路,其实对于 CSSStyleRule 中,style 是标准的 CSSStyleDeclaration 对象,直接可以拿到命中规则的 styleDefition,这时候你可以选择去解析 styleDefition 字符串,或者选择直接用 CSSStyleDeclaration 对象中有值属性来显示出来。

拿到命中的 CSS 的规则后,通过修改相应的 CSS 规则,要使规则应用到文档中,直接可以使用 CSSStyleDeclaration 对象的 setProperty 方法来设置修改属性,设置完成后通常文档还不会立即生效,这时候就需要触发文档的 layout 使应用生效,示例代码如下

这时候就完成了对 CSS 文档的读取与修改

但请注意

  • getMatchedCSSRules 同样受限于同源安全限制(跨域限制),对于跨域的文档的 CSS 会返回 null
  • getMatchedCSSRules 并没有将内联 style 算在内,所以还要考虑内联 Style 的定义,但这个相对读取与修改比较简单

任务并没有完成,遗留的问题

  • 对于定位文档的中 CSS 修改代码的位置,可能通过 ajax 请求 css 文档搜寻更改位置
  • 对于 ie 系的几个倔强大哥们,都不支持 getMatchedCSSRules 方法,鉴于 CSS 语法的简单性,可以尝试通过 ajax 请求文档 CSS 文档来进行解析 CSS 语法,然后拿到对应的命中规则。

肉消化的差不多,CSS 篇也写完了,有问题还请指教~

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2013/12/powerfuljs-1-to-operate-an-html-document-using-js/

  1. t 2013 年 12 月 22 日

    document.styleSheets[0].cssRules
    // Works in Internet Explorer.
    IE 11 does not yet support getMatchedCSSRules method.

  2. ajiao5198 2013 年 12 月 16 日

    不错,很酷!

发表评论