牢骚:扎堆的聊天工具

作为一个现代的网民,一个每天接触电脑及网络超过14个小时的IT业网民来说,聊天工具会变成一个很头大的问题。任务栏一角蹲着好几位大仙,还各有各的用处,让我们先请出这几位大仙。

1 通天教主 非QQ莫属。

QQ

2 西方教阿弥陀佛 MSN大教主

live msn 图标

3 西方教准提 Skype二教主

skype图标

4 互联网业界的Jesus  Gtalk大当家

google gtalk 图标

5 玉虚宫的元始天尊 飞信

飞信fetion图标

6 多宝道人 阿里旺旺 

阿里旺旺图标

多年以来,各种IM评测比较无数,比来比去,也没见到谁真的能一统天下。而聊天工具不同于其他软件,他是直接对应到人的。为了联系人,你就得多开一个IM。公司里还非塞我个内部IM,IBM的Sametime。也许很多人会说,什么标准要统一,大家都要支持同一种协议,互联互通。除了那些市场后来者,抑或是Google这样的仅将其作为战略一角的厂商,谁愿意在用户粘度那么高的市场里高唱“我家大门常打开,开怀容纳天下”。这不是什么公益事业,只是生意而已。

撇开所谓细分市场,撇开所谓用户层次,仅从一个软件业工作人员的角度看,我最想用的软件还是QQ,毕竟功能只有他很少会让你因为没有一个功能而觉得不爽,比如在msn里为了让客户现场发个截图回来,一般都是要自己打电话的。话说回来,这几位大仙里,数QQ最倒霉,想那碧游宫门人遍天下,就国内来说,几乎是拿下大部分的市场份额,而且几乎覆盖了除高端市场以外的所有用户层。话说回来,门人多了,难免有部分不修功德之辈。于是乎,大家都说他是“披毛带角,湿生卵化之辈”。又因有其下门人孔宣,背后的红钻、绿钻、黄钻五色神光刷尽天下法宝,云霄,碧霄,琼霄手上的q秀,q宠出尽风头,遭来一片围剿之音。沾上了层次低的原罪,导致在高端市场上吃不开,我的公司索性把qq.com封掉,想上QQ还得自己翻墙。(不过比起上一家公司已经好多了,上一家连去射手网下个字幕都算暴力网站,呵呵。)

各个公司对IM的态度也是直接导致IM混乱的重要因素,导致有的人只能用gtalk,有的只能用msn,于是大家为了能互通,也只好开上一排IM,否则话,我相信起码在国内,QQ+MSN的组合绰绰有余了。就是被这帮装B外企搞坏的。唉,这话说的,把自己也骂进去了。别的公司不清楚,就IT开发类的公司,你禁了工作效率也肯定不会什么显著提高,除了boss,谁都知道项目慢在哪里。

希望梦道友的onsite生涯早点结束,免得我们都跟着开那个牛弱智的Skype。咱还是白天msn晚上qq的路子比较正。

CSS3中的伪类概览

CSS的目标,或者说是革命纲领就是:“将样式与内容分离”,这个目标能否实现,很大程度上依赖于CSS访问内容的能力。在CSS3中,这个任务得到了有力支持,强大的结构伪类Structural pseudo-classes出现了。提供了非常丰富的查询方式,让CSS选择器变得如此和蔼可亲了。让我们来快速概览一下,同时期待着浏览器整体换代的来到,毕竟只有最新的浏览器才支持CSS3选择器及其他特性。 支持浏览器:Firefox 3.1+, IE8+ (only in IE8 standards mode), and Safari 3.1+

CSS结构伪类

Method Description
E:root 选择文档的根结点,在HTML文档中也就是HTML节点
E:first-child 选择该节点的第一个子节点。
E:last-child 选择该节点的最后一个子节点。
E:nth-child(n) 选择指定节点的第N个子节点。
示例:

li:nth-child(1) /*选择Li元素的第一个节点*/

E:nth-last-child(n) 和上面的伪类逆序,选择指定节点从最后一个子节点开始的第N个子节点示例:

li:nth-last-child(1) /*选择Li节点的最后一个子节点*/

E:nth-of-type(n) 选择父节点之下,所有指定类型的的节点中的第N个,有点晦涩的一句话。还是看示例比较清楚:

ul li:nth-of-type(1) /*选择当前页面上所有Ul之下的第一个Li节点,包含嵌套的Ul之下的第一个Li*/
p:nth-of-type(odd) /*选择所有的奇数项的P元素,一下子解决了表格的交替背景色问题*/

E:nth-last-of-type(n) 选择父节点之下,所有指定类型的节点中倒序的第N个节点,和上面的正好顺序相反

示例:

option:nth-last-of-type(2) /*选择所有的select下倒数第二个option节点*/
option:nth-last-of-type(-n+3) /*选择倒数3个option节点,是多重选择*/

E:first-of-type 和上面的两个伪类类似,不过这个简单版,就是取第一个或者是最后一个示例:

p>quote:first-of-type /*选在所有P节点下第一个quote节点*/

E:last-of-type 同上:

tr>td:last-of-type /*选择每一行的最后一个单元格*/

E:only-of-type 选择在父节点之下,符合所有子节点中只有一个该类型节点条件的节点。又是比较难懂的一句话,也就是说,在子节点集合中,该元素必须符合指定类型,同时仅含有一个的情况。示例:

div>p:only-of-type /*s选择Div之下,如果只含有一个P节点,选择该节点*/
input[type=”radio”]:only-of-type /*如果form中,只有一个input类型为radio的,选择该input节点*/

E:only-child 和上面类似,不过更加严格,仅当符合,该父节点下仅含有一个子节点的情况。示例:

div>p:only-child /*选择那些Div下只有一个p节点的p节点*/

E:empty 选择那些没有子节点的节点,也就是选择那些叶子节点(包含text节点). HTML注释不计入子节点数。来看一下具体例子:下面的都是空节点Empty Elements:

<p></p>
<p><!–Empty
paragraph</p>

以下都是非空节点Non Empty:

<p>Welcome to oncontextmenu=”return false;” id=KonaLink1
onmouseover=adlinkMouseOver(event,this,1);
style=”POSITION: static; TEXT-DECORATION: underline! important”
onclick=adlinkMouseClick(event,this,1); onmouseout=adlinkMouseOut(event,this,1);
href=”http://www.javascriptkit.com/dhtmltutors/structuralcss.shtml#” mce_href=”http://www.javascriptkit.com/dhtmltutors/structuralcss.shtml#”
target=_top>
style=”FONT-WEIGHT: 400; FONT-SIZE: 13px; COLOR: blue! important; FONT-FAMILY: Courier new; POSITION: static”
color=blue> style=”FONT-WEIGHT: 400; FONT-SIZE: 13px; COLOR: blue! important; FONT-FAMILY: Courier new; POSITION: relative”>JavaScript
Kit</p>
<p><b></b></p>

E:target 这是一个很玄妙的伪类,可以定位到当前页面url跳转位置。还是结合示例来看:当前页面的url:http://www.javascriptkit.com/dhtmltutors/structuralcss.shtml#该伪类可以选中跳转的anchor,在其前面加上一个箭头图标
<style
type=”text/css”>
*:target:before{
content: url(arrow.gif) /*adds an
image in front of the current active HTML
anchor*/
}
</style>
<body>
<a
href=”#whatsnew” mce_href=”#whatsnew”>Jump to what’s new</a>

<a
name=”whatsnew”></a><b>New content
1…</b>
</body>

Also see:
href=”http://www.javascriptkit.com/dhtmltutors/cssgenerate2.shtml” mce_href=”http://www.javascriptkit.com/dhtmltutors/cssgenerate2.shtml”>Added
Generated Content in CSS2.

:not(s) 这个被称为逆伪类(很不准确的翻译,还是看原文吧)negation pseudo-class, “:not(s)
选择不是指定类型的节点,节点类型由参数传入(不含伪类元素本身)示例:

:not(p) /*选择所有不是P的节点*/
input:not([type=”submit”]) /*选择所有不是submit按钮的input元素*/
option:not([selected=”selected”]) /*选择所有不是默认选中的option*/

E:enabled 选择enabled节点。示例:

input[type=”text”]:enabled  /*选择所有enabled的text节点*/
input [type=”submit”]:enabled /*选择所有类型为submit,且enabled的节点*/

E:disabled 选择diabled节点。示例:

input[type=”text”]:disabled /* /*selects text boxes that
are disabled*/
input[type=”submit”]:disabled /*selects submit buttons that
are disabled*/

E:checked 选择checked节点。通常为checkbox和radiobox元素。示例:

input:checked /*selects radio or checkbox elements that are
currently checked*/
input[type=”radio”]:checked /*selects radio buttons that
are currently checked*/

CSS结构伪类中的表达式

在伪类“E:nth-child(n)” 和 “E:nth-of-type(n)”中,都支持参数传入,前面的例子中,我们只是简单的传入数字,选择指定位置的节点,其实这里的参数有着非常玄妙的表达式。我们来看一下:

首先他的表达式结构,或者说这个序列的通式为:

an+b

  • n n为该类型元素本身或者指定数字(大于等于0的整数)位置的元素。这是一个基数。
  • a 为n的系数。
  • b 偏移量。

单看公式是比较难以理解的,具体看些例子好了。

p:nth-of-type(n+1) /*选择所有第一个子节点之后的子节点,含第一个,等价于全部子节点,p:nth-of-type(n),其实是一个效果*/
p:nth-of-type(n+5) /*选择所有第五个子节点之后的节点,含第五个*/
p:nth-of-type(3n+2) /*选择,第二个,第五个,第八个节点,是一个数列,表达式即为通式。*/

tr:nth-of-type(-n+5) /*数学游戏,其实就是前五行,因为负数不具意义,所以当表达式结果为负数时,停止求值*/
tr:nth-last-child(-n+5) /*同上*/

所以原来可能让我们觉得很麻烦的交替显示,只需要这样:

option:nth-of-type(even) /*even OPTIONs in a SELECT*/
option:nth-of-type(2n) /*same as proceeding*/

option:nth-of-type(odd) /*odd OPTIONs in a SELECT*/
option:nth-of-type(2n+1) /*same as proceeding*/

大概的内容就这些了,剩下就是无尽的等待了。看他们什么时候开完会,有的时候也不只是中国人开会慢。

测试驱动之于网页设计开发

这是一篇译文,其中涉及了不少比较专业的概念,我将用一系列文章来介绍这些概念,这些文章对于网页设计进行了更加深入的探讨,也许在我们看来有些学究气了,但是通过这种探讨,我们从中应该看到一些好的方法论和更多的用户体验关怀。 

Progressive Enhancement(逐步增强)开发模式正逐步成为基于标准设计的最佳实践。从简洁,语义化的HTML标记开始,通过Javascript和CSS层层渐进式增强,我们试图为任何受众创建可用的体验,对于那些功能不那么强大的设备和浏览器能获得一个相对简单但是功能完整的用户体验,而其他那些功能齐备的则将获得剩下的附加特性和体验。

这是就是PE(Progressive Enhancement 以下缩写为PE)的基本理论。但是在实践过程中,这些增强仍然被推送给了绝大多数设备,其中包括大量不支持这些特性的对象,比如较低版本的浏览器或者是功能受限的移动客户端。这些设备一开始的确获得简单但功能完整的页面,但随后被“增强”到了乱糟糟的页面。这显然是和PE理论背道而驰的。

那我们应该怎么做增强以确保所有的设备和浏览器获得正确的效果呢?测试,这时候我们需要的是通过逐级测试来确保这点。

兼容性测试

不久之前,我们发现可以使用很简单的Javascript代码来测试目标设备对于CSS的支持情况。让我们从一个很简单的盒模型测试开始,我们插入一个对象到当前Document中,然后设置一些样式属性,然后通过Javascript来校验是否被正确支持了。

function boxmodel(){
  var newDiv = document.createElement('div');
  document.body.appendChild(newDiv);
  newDiv.style.width = '20px';
  newDiv.style.padding = '10px';
  var divWidth = newDiv.offsetWidth;
  document.body.removeChild(newDiv);
  return divWidth == 40;
}

通过上面的TestCase,我们能很快的检查目标设备是否正确支持盒模型,然后我们也能采取对应的增强方式。

有了上面的这个主意,我们能类似的写出如下测试用例:

  • float
  • clear
  • position
  • overflow
  • line-height

当然仅通过CSS测试并不能覆盖到所有情况,幸运的是,我们还能通过Javascript测试来做其他兼容性测试。(译注,这可能是大家比较熟悉的浏览器检测了)。

  • document.createElement()
  • document.getElementById()
  • xmlHttpRequest()
  • window.onresize()
  • window.print()

通过上述测试,我们可以知道是否可以正确显示客户的应用。

我和我在Filament Group的同事开发了testUserDevice.js,来完整上述所有的测试。

利用这些测试结果

整合testUserDevice.js到一个页面上是相当简单的,讲JS文件包含进来,然后调用testUserDevice.init()方法就可以了。

为了更好的阐述这些概念,我们来看一个具体的例子,这是一个有一定复杂度的表单页面,让我们从最基本的HTML开始。

DEMO1

=== CSS增强

当目标设备通过了我们的测试代码,会对页面进行一系列的增强,默认情况下,会进行下列DOM更新:

  • 样式Class enhanced 被加到[BODY]元素上。
  •  (title="enhanced") 可选的样式表文件被启用。
  •  (title="not_enhanced") 与之相反的,所有这些非增强样式表文件被禁用。

这样的变化给你提供好几个契机去做层进式的增强,比如BODY标记上的样式增强。来看下例子:

body div.example { 
   margin: 1em 0;
}

如果用户的浏览器通过了测试,我们可以使用float布局来实现水平排列。

body.enhanced div.example { 
  float: left; 
  width: 30%; 
  margin: 0;
} 

来看一下示意图,

这只是一个很小的变化,当你要做一些比较复杂的增强的时候,使用选择器来实现就显得不怎么合适了,所以这个时候,你应该使用可选的样式表文件来替换原来的效果。

这虽然只是简单的样式表文件替换法,但重要的地方在于我们的增强只在能够正确解释的地方被应用了。让我们再来看一下前面的Demo页面,看看现在的增强后的效果。

Demo 2

尽管我们做的只是很简单的CSS增强,但是测试目标设备是否能够正确支持依然是十分有必要性的。(译注:术抑或是道,以何治天下)

Javascript增强

很多页面增强使用了Javascript。testUserDevice.js 允许你具体指定一些script来做增强。非常简单,你只需要将你的增强方法作为参数传给我们的方法就可以了。

testUserDevice.init( function(){
/* »fancy stuff goes here */
} );

就像你看到的这样,我们将一个匿名方法传给了init方法。如果测试通过,这个方法就会被调用执行。记住一点,这些动作有可能在DOM树构建完毕前触发,所以DOM相关的方法仍然应该放在DOM树构建完毕之后,比如jQuery的ready事件或者是body.onload事件之后。

来看一下我们的最终Demo页面,有了如下增强

  • 生日输入框有了日历供选择日期。
  • 有了滑块选项。 
  • 宠物那栏也是根据用户输入,动态展示一下输入框。
  • 有了自动完成功能。
  • 使用了Ajax提交方式。
  • Demo 3

    一次测试,终身受用

    在完成测试之后,testUserDevice.js 会留下一个cookie记录这次的测试结果,这样也能带来性能上的好处。我们通过PHP代码也能非常方便的去处理这些增强动作:

    <?php
    //check for cookie (enhanced=pass), and set the »
    //stylesheet rel depending on its value
    $cssRel = ($_COOKIE['enhanced'] == "pass") ? »
    "stylesheet" : "alternate stylesheet";
    
    echo '<link rel="' . $cssRel . '" »
    type="text/css" href="css/enhanced.css" mce_href="css/enhanced.css" »
    title="enhanced" />';
    ?>
    

    同样的,testUserDevice.js 支持你加入更多的自定义测试。下面就为大家介绍下,如何编写自定义的测试用例,并且加入到testUserDevice.js 中去。
    (译注:此处并未全文译出,我想程序员间的交流代码足够了,代码是无国界的,说多了也没什么用处。)
    1

    testUserDevice.init([ 
           { testName: 'ajaxCapable',
            pass: ['ajax'],
            scripting: function(){ useAjax(); }   
    
           }
    ]);

    2

    testUserDevice.add( 'confirm', function(){ 
       if(window.confirm){return true;} 
       else {return false;}   
    
    });

    3

    testUserDevice.add( 'confirm', function(){ 
         return (window.confirm) ? true : false;});
    

    原文地址:http://alistapart.com/articles/testdriven
    Reprinted with the permission of A List Apart and the author[s]

    //====================================================
    译者:
    这里说的测试驱动,并不是我们平日里程序开发中的测试驱动。当然两者的理念其实某种角度上来说是一样的,只做确信正确的改动。我平日里工作中,说实话没有过这样的思考。如何适应各种不同的目标客户端,我想到的第一个是尽可能的去兼容,但是PE这种理念从另一个角度提出解决方案。给不同的人不同的,但必须是完整且正确的体验。这点值得我们进行更深一步的讨论。

    SmashingMagazine 十月壁纸赏

    十月壁纸赏,每个月换换壁纸,也换换心情。有道是加班无岁月,但是日子还是得知道的,要不一会哪天发饷都不记得了。

    十月壁纸 墙纸 森林 精灵

    森林中的精灵,你知道会幻化成什么样子,是你心中哪位女神的样子。

    摩天轮的幸福 十月墙纸 壁纸

     都说在摩天轮上能看到幸福,也许说的是幸福就在那一圈圈的轮回之中吧。

    哈利波特 十月壁纸 墙纸

    原来奔月的不只有嫦娥,还有徐静蕾

    迷一般的梦幻

    你看到了什么?

    海豚 墙纸 壁纸

    最聪明的海中精灵吧。

     想要下载这些漂亮的壁纸:http://www.smashingmagazine.com/2008/09/29/desktop-wallpaper-calendar-october-2008/

    不可思议的Google PageRank

    今天,准确的说是昨天了,突然发现Google又一次更新了PageRank。

    http://www.1×3x.net/blog   PR3

     http://www.youxi247.cn     PR6

     如果说这个Blog,PR3的水平让我觉得很正常的话,那youxi247的PR6评分就有点不可思议了,毕竟这个Blog从上线到现在还不到一个月时间,有点儿意外,不过网站人气还是不行,最近好几个项目都赶着Release,时间上也不允许我花很多时间在这个上面。国庆假期要好好搞一下。也算对得起这分数。

    什么是Google PageRank
    大家可能听说过,Google 革命性的发明是它名为 “Page Rank” 的网页排名算法,这项技术彻底解决了搜索结果排序的问题。其实最先试图给互联网上的众多网站排序的并不是 Google。Yahoo! 公司最初第一个用目录分类的方式让用户通过互联网检索信息,但由于当时计算机容量和速度的限制,当时的 Yahoo! 和同时代的其它搜索引擎都存在一个共同的问题: 收录的网页太少,而且只能对网页中常见内容相关的实际用词进行索引。那时,用户很难找到很相关信息。我记得 1999 年以前查找一篇论文,要换好几个搜索引擎。后来 DEC 公司开发了 AltaVista 搜索引擎,只用一台 ALPHA 服务器,却收录了比以往引擎都多的网页,而且对里面的每个词进行索引。AltaVista 虽然让用户搜索到大量结果,但大部分结果却与查询不太相关,有时找想看的网页需要翻好几页。所以最初的 AltaVista 在一定程度上解决了覆盖率的问题,但不能很好地对结果进行排序。

    Microsoft IE8 CSS3扩展支持

    众所周知,所有的浏览器都有一些关于CSS功能的额外扩展,例如(-ms-interpolation-mode),这些通常来自于那些未在CSS标准中明确完整的定义的特性和功能或者是在标准中已经完整定义但浏览器只是部分支持。CSS2.1标准中规定,以上这些不完全合乎标准的特性都必须使用一个供应商前缀(Vendor Prefix '-ms-' for Microsoft, '-moz-' for Mozilla, '-o-' for Opera)。

    下面介绍一下IE8下的这些额外扩展,当然我们的目的不是把那些IE Only的特性带入下一代的页面中,而是能够在浏览器支持的前提下,运用一些属于CSS3的特性,丰富一下创作思路。

    Property Type W3C Status
    -ms-accelerator Extension
    -ms-background-position-x CSS3 Working Draft
    -ms-background-position-y CSS3 Working Draft
    -ms-behavior Extension
    -ms-block-progression CSS3 Editor’s Draft
    -ms-filter Extension
    -ms-ime-mode Extension
    -ms-layout-grid CSS3 Editor’s Draft
    -ms-layout-grid-char CSS3 Editor’s Draft
    -ms-layout-grid-line CSS3 Editor’s Draft
    -ms-layout-grid-mode CSS3 Editor’s Draft
    -ms-layout-grid-type CSS3 Editor’s Draft
    -ms-line-break CSS3 Working Draft
    -ms-line-grid-mode CSS3 Editor’s Draft
    -ms-interpolation-mode Extension
    -ms-overflow-x CSS3 Working Draft
    -ms-overflow-y CSS3 Working Draft
    -ms-scrollbar-3dlight-color Extension
    -ms-scrollbar-arrow-color Extension
    -ms-scrollbar-base-color Extension
    -ms-scrollbar-darkshadow-color Extension
    -ms-scrollbar-face-color Extension
    -ms-scrollbar-highlight-color Extension
    -ms-scrollbar-shadow-color Extension
    -ms-scrollbar-track-color Extension
    -ms-text-align-last CSS3 Working Draft
    -ms-text-autospace CSS3 Working Draft
    -ms-text-justify CSS3 Working Draft
    -ms-text-kashida-space CSS3 Working Draft
    -ms-text-overflow CSS3 Working Draft
    -ms-text-underline-position Extension
    -ms-word-break CSS3 Working Draft
    -ms-word-wrap CSS3 Working Draft
    -ms-writing-mode CSS3 Editor’s Draft
    -ms-zoom Extension

    在IE7中,没有使用这样的前缀,所以如果用户在IE8中选择兼容模式的话,这些带有前缀的属性将不被识别。不过在IE8模式中,为了向下兼容,将接受带前缀和不带前缀两种格式。

    有一个要注意的地方:

    #transparentDiv {
           -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
           filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
           opacity: .5;
    }

    原来的filter格式在标准中是不合法的,所以为了能够在ie7和ie8中都能达到该效果,请参考上述写法。(向下兼容真是沉重的包袱啊

    原文地址: http://blogs.msdn.com/ie/archive/2008/09/08/microsoft-css-vendor-extensions.aspx