CSS Expression Reloaded

2008.10.2621:17

CSS Expression,动态 CSS 属性,IE 私有,自 5.0 开始引入(IE8 将不再支持),参考 MSDN

这东西的优点:

  • 使 CSS 属性动态生成,所以基本 js 能干的它都能干
  • 使用 CSS 选择符,比 js 遍历到某个特定元素要方便得多

这东西的缺点:

  • expression 会反复执行,有严重的效率问题。它的触发似乎不是通过事件,而是通过 interval 一类的机制。
  • 别的浏览器不支持,IE8 也将不再支持

那现在翻出来干嘛呢?因为我发现,第一个缺点是可以解决的。方法就是,在 expression 语句体里面,将触发该 expression 的 css 属性重置。比如 body{ zoom: expression(function(ele){ele.style.zoom = "1"; alert("xx");}(this));},执行这段 CSS 会发现,alert 只跑了一次。具体可以看我上一个关于解决背景闪烁问题的帖子

所以,解决了 expression 的效率问题,就完全可以在实战中用上了。使用时只要用一个无关紧要的 CSS 属性做触发,比如 zoom, 比如 letter-spacing,比如 unicode-bidi,等等等等,触发完了重置回默认值。可以玩的很多,我来写几个实际应用中经常会遇到的问题:

给不同 type 的 input 赋予不同的样式

支持 CSS2 选择符的可以使用属性选择符,IE 则可以用 expression 给 input 加上不同 type 对应的 class:(这个例子在经典贴过

input{
  zoom: expression(function(ele){
    ele.style.zoom = "1";
    (ele.className)?ele.className+=" "+ele.type:ele.className=ele.type;
  }(this));
}
input[type="text"]{ border: 1px solid red;}
input.text{border: 1px solid red;}
input[type="button"]{ border: 1px solid blue;}
input.button{border: 1px solid blue;}

演示 1,这个还可以再发散发散,比如加上 :checked,:disabled 等等,改表单样式不愁啦~

隔行换色(zebra lists)

支持 CSS3 选择符的可以直接上 nth-child(webkit,opera 都支持,马上要发布的 firefox3.1 也支持),IE 则可以通过 expression 加上 odd 或 even 的 class:

.test{
  unicode-bidi: expression(function(ele){
    ele.style.unicodeBidi = "normal";
    var childs = ele.getElementsByTagName("li");
    for(var i=0; i<childs.length; i++){
      (i % 2)?childs[i].className+=" even":childs[i].className+=" odd";
    }
  }(this));
}
.test li.odd{background: #CCC;}
.test li.even{background: #EEE;}
	
.test li:nth-child(odd){
  background: #CCC;
}
.test li:nth-child(even){
  background: #EEE;
}

演示 2 (IE5+,Opera,Safari,Chrome,Firefox 3.1)

模拟 :before 或者 :after

Firefox 3.1 之后,:before 或者 :after 出来的东西可控的 CSS 属性更多了,比如 position/float,又有的玩了,不像以前基本废柴,只拿来清除浮动……大材小用啊。

.test{
  letter-spacing: expression(function(ele){
    ele.style.letterSpacing = "0";
    var newchild = document.createElement("span");
    newchild.className="after";
    newchild.appendChild(document.createTextNode(" World!"));
    ele.appendChild(newchild);
  }(this));
}
.test:after{
  content: " World!";
  color: red;
}
.test .after{color: red;}

演示 3

还有什么好玩的可以玩?想起来再来补充。

再说 IE6 的背景闪烁

2008.01.0409:42

基本上 google 一下 IE6 flicker,第一页基本全是说这个问题,解决方法就是那个神奇的 document.execCommand("BackgroundImageCache",false,true),只不过是围绕着用 CSS expression 还是 JavaScript 的问题。JavsScript 最稳妥,不过有时候 JavaScript 未必方便改,而 CSS 虽然方便但是 expression 会反复执行,有严重的效率问题。最近的几个项目用的方法是这样的,在 expression 中把 CSS 中用来触发的属性重写一下:

body{
    zoom: expression(function(ele){
    document.execCommand('BackgroundImageCache', false, true);
    ele.style.zoom = '1';
    }(this));
}

这里用 zoom 触发,搞定之后把 zoom 写回 1(好像我很喜欢捣腾 zoom),这下就没效率问题了吧,嘿嘿。同理,其他针对 IE 的 hack,如果是只跑一次的 expression,其实都可以这样做,所谓兔死狗烹过河拆桥是也~ :D。

Scriptless Day

2007.04.1418:42

scriptless day

CSS 有裸体节,JS 也有哦,看这里:http://www.scriptlessday.com/

CSS 裸体节的目的是号召 web 开发者注重自己 HTML 的结构和语义,同时体现 CSS 的强大功能,那JS 的裸体节目的是啥?

个人觉得目的应该是考验网站 bulletproof 的代码风格,unobtrusive 的编程习惯,从可访问性角度审核网站的水平。没有了 JS,你的网站还有多少可访问性?

不过发起人好像不是抱着这个目的……他们似乎想通过这个活动证明 JavaScript 在现代 web 应用中的重要性……什么意思?在失去 JavaScript 的痛苦中反思它的重要地位?……有点怪怪的。

Opera URL encode bug

2007.04.1316:15

瀚海用 Opera 回复帖子,如果标题有中文会变乱码,发表文章和同主题阅读就没有问题,非常恼人,不知怎么回事。今天研究了一下,发现似乎是 Opera 的 bug:

  • Opera 似乎会通过 href 中是否有冒号(:)来选择不同的 URL encode 方式,没有冒号的使用当前页面编码,有冒号的使用 UTF8 编码。BBS 回复文章的时候会在标题前面加一个“Re: ”,所以出了问题。
  • 取消了工具-> 首选项 -> 用 UTF-8 给国际语言网址编码复选框,问题依旧。(这个选项是不是干这个事的?)

bug 演示页面在此,鼠标划过两个不同的 link,注意状态栏,会发现两个 URL 采用的 encode 方式不同,而其他浏览器正常。记得以前 Opera 好像不会这样,自从版本 9(还是8?)以后开始有这个问题,今天更新了最新的 9.20 final 依旧如此。

所以初步判断是个 bug,已经提交到 Opera 的 bug report 系统 ,不知道什么时候能有回应。

updated发现将冒号先 encode 成 %3A 可以解决这个问题,不过目前还属于知其然不知其所以然,补习一下 RFC:http://www.faqs.org/rfcs/rfc1738.html

updatedOpera 9.5已经没有这个问题了,good~

External API 在 IE 中有保留字

2007.04.1222:48

今天被这个郁闷了,原来 IE 中是有保留字的……

极其简单的一个 Flash 嵌入,Firefox 就一切正常,IE 死活报脚本错误,而且给出莫名其妙的行号和错误说明,对调试没有半点用处。

最后发现是 Flash 中的 ExternalInterfaceaddCallback 的时候用了一些保留字,我用的是 playstop,不知道还有没有别的,真是郁闷,要是都报错还好查一点,结果单单 IE 报错,ft。

猜想可能是和 IE 的 Flash ActiveX 对象自身提供的方法有命名冲突吧,记一笔,以后注意。

SWFObject 1.5

2007.03.0111:43

SWFObject 更新到 1.5,这可能也是最后一个版本了,因为这项目已经和 UFO 合并,新名字叫做 SWFFix。两个项目的作者有志将这个合作产物打造成 Flash 嵌入的事实标准,恩不错,统一了好啊统一了好,目前还在 alpha。

SWFObject 这个版本的具体更新内容看他们的 blog post

最近似乎对 Flash 的问题讨论的蛮多的,ALA 上也有两篇文章说到 Flash:
Semantic Flash: Slippery When Wet
Flash Embedding Cage Match

更新:AW 提供了 SWFObject 的中文版翻译,赞的。

百度收藏和QQ书签

2007.02.1215:15

网摘服务一直用 delicious,功能没的说,还在不断完善,这个谁用谁知道了,唯一可惜的是速度比较慢,可能是国外服务器的原因。

所以国内有类似服务的时候都喜欢去试试看,希望能找到替代品。最近作为走在国内互联网行业前列的百度和腾讯相继推出自己的收藏服务,当当当当~~,自然都要去试试看啦。

百度搜藏基本还是不错的,但是他们不记录 cookie,这就意味着每次收藏我都要登录一次,这个停顿是无法容忍的。去贴吧看了看发现有多人反映这个问题,我也吼了几次,结果百度由于种种原因似乎没有要改的意思。
无奈,卸载,放弃。

今天又收到了 QQ 收藏的公测邀请信,把早早就装上了的 Firefox 扩展 enable,玩了一把。嗯不错,记录 cookie,体验比较流畅。但是,在收藏网页的页面填写 tag 的时候,并没有像 delicious 或者百度那样出现 ajax 的实时提示……正在奇怪的时候低头一看,我的 firebug 已经报了十几个 ERROR 了……点之瞅瞅,老天,满眼的 window.event…… 彻底无语……QQ video的兼容性不是做得蛮好的么?怎么收藏会有这么低级的兼容性问题?好歹也开始公公公测了啊?
无奈,disable 扩展,放弃。

唉,百度腾讯你们慢慢公测,目前我还是先用回我的 delicious 吧。

FormTextResizer

2006.08.2515:56

平时上网的时候会遇到很多地方表单输入框过小的情况,而站点又没有提供改变大小的功能,输点东西要去拉细细的滚动条半天才能看全了,恼火得很哇,如果是单行的 input,那就更要郁闷死,要看全了还真不容易。这段 JavaScript 脚本就是用来动态改变网页上的输入框大小的,用法很简单,把下面的链接加到收藏夹里面就可以了,遇到不爽的网站,点一下,就可以通过鼠标拖动来改变输入区域大小了,很实用哦。

就是这个链接,右键加入收藏即可:FormTextResizer

IE 不那么好伺候,收藏这个链接吧(调用了作者网站上的 js):FormTextResizer

来自 The Man In Blue

FRC 0.2

2006.07.3014:37

FRC 0.2 :D

使用 CSS 加载图片、设置 scale9 grid 以及 blending mode。支持多 block 。

目前只能应用于普通的 block,复杂的比如 float, positioned 还不支持,嵌套 block 也有问题。Anyway, just for fun.

SWFObject 更新

2006.07.3005:34

SWFObject 更新至 1.4.3,修复了一个 bug,IE5 和 IE6 在用 SWFObject 嵌入多个 Flash 时,如果有某个 Flash 使用 ExternalAPI 添加了 callback 和 页面的 JavsScript 交互,那么会出一个 “Out of Memory” 的 bug,而且这个 bug 只出现在 flashplayer9 中。具体说明见这个 post

前两天写 FRC 的时候恰好遇到这个问题,本来页面里面是有多个 block 的,后来发现在 IE 里面多个 Flash 的时候有这么个严重的 bug,不知道怎么解决,就只放了一个。居然这么快就找到修复方法了,这下我的 FRC 可以小更新一把,嘿嘿。