08的小结

2009年1月3日 – 00:48

08过去了,09来了,本来这个小结应该前几天写的,但总因为种种事情而耽搁了,现在补回来。
细数这个博客开张马上就满一年了。最开始用了pjblog现在换成了wordpress
中间又断了将近半年事件。
说是以前端为主,但其实发现关于HTML和CSS内容很少,基本上都是jQuery为主。
即将到来的2009年里,这里可能会有新的内容,涉及正则表达式,Flex,Python,PHP也可能有EditPlus和VIM。而HTML和CSS以及JS、jQuery内容依然会跟进。服务器我也打算搬到国内来。Godaddy的实在太慢,我用不下去了……
一不小心小结变成了展望,罪过罪过。总之,过去一年多谢各位的支持,将来一年请继续支持!

我的卓越亚马逊和当当购书经历

2008年12月25日 – 17:28

Story
这两家在国内可以说是走在风口浪尖上的两家B2C公司,也都逐步从之卖书到了什么都卖的大百货转型。
这回我从我前几天想买的一本《精通正则表达式:第3版》。不要问我为什么不从china-pub买,只因为我对价格比较敏感。而不在乎书谁先出来。
各位也都可以从上面豆瓣链结里看到两个店的价格是一样的,都是55.9,蔚蓝在豆瓣页面里写是55.5,实际点进去是37.5 见:这里 。(我才发现……书已经到手……不退了……其他同学有兴趣的赶紧下手……机会难得……不过最好先问清版本。)
事情是这样的,很早就眼馋这本超越语言界限的圣经级别的《精通正则表达式》了,年初的时候想买,但看到了勘误表之后慌了,这么多错误,我买回来自己一个一个对着勘误表现改一通可就累了,而且我也没有在书上写字习惯。所以就忍了。这几天看到了说第三版已经在卖了,就盘算着买了。
好了,罗嗦了这么久,正式开场

Act 1
跑到卓越当当上,都没有看到关于印次。而底下评论问第几次印刷的版本的,也不见有客服来回答。所以打算直接问客服了。
这局打平,两家都做的不好,当当上有“印次”和“印刷时间”的栏目,但没写,卓越压根就没有,只有“版本”这个栏目。

Act 2
先说卓越,在页面最下面“如您需要帮助或对我们的客服有疑问,请联系我们。”。OK,点进去后就有了一个界面,填写信息后,等回音了。
接着是当当,在页面里死活找不到售前服务的地方(除了那个没用的提问部分),只在页面最底下找到了”常见热点问题/找回密码/顾客建议/顾客投诉”

点哪个呢?肯定不是找回密码(这东西怎么放这里?放登录窗边上不就够了?),我也不想投诉也没有建议阿,想了半天,还是“常见热点问题”吧。进去,找了半天,什么新手指南,什么退款换货保修一应俱全,就是没有售前服务,只有一个“联系客服”,得这算是我要的了吧。进去一看,邮箱和400电话。OK,打开GMAIL,寄了邮件过去。

给卓越的客服留言:

这本《精通正则表达式(第三版)》

http://www.amazon.cn/dp/bkbk728354

我想确认一下是第几次印刷的版本。并且如果可以的话,请客服能顺便修改一下页面上的资料以方便其他读者。

给当当的邮件:

当当网的客服:
你好
我想买《精通正则表达式(第三版)》

http://product.dangdang.com/product.aspx?product_id=20028613

但我不能确定这是第几次印刷的(以及印刷时间)。所以发信来询问一下。并希望能够顺便更新一下页面资料,以方便其他读者。
谢谢

by Shawphy

这局,当当大败,浪费了我很多时间。到最后都要我用自己的邮箱给他们写信。

Act 3
2008年12月19号当天(周五),在我发邮件一两个小时后,卓越的客服先给我的邮件。下午两点就给我回信了。
而当当我晚上8点发的邮件,第二天凌晨2点给我邮件……
卓越我是白天发的邮件,当当我是半夜2点发的邮件。卓越我看不出来邮件服务是不是24小时的,至少当当是24小时的。
当当小胜,当然也因为我的实验产生了一定的误差,所以本次实验信度不是很高,各位看官酌情取舍。

Act 4
以下给出邮件主要部分(客套话就省了,虽然我不看,但他们得写)。
卓越给我的邮件:

亲爱的朋友:

您好!感谢您的email。

很抱歉,您询问的商品:《精通正则表达式(第三版)》,问题我们暂时不能确认,我们和相关部门确认后会尽快回复您,

并且会通知编辑人员更新页面信息。请您放心。

当当给我的邮件:

亲爱的顾客:

您好!非常感谢您对当当网的支持!非常抱歉,对于商品信息我们和您浏览的是同一个网页,我们看不到商品实物,如果您想了解商品更多的信息,您可以到商品单品页面提交评论,我们网站的编辑看到后会第一时间回复您。

我第二天周六10点半发现了这份回信,很日……回信曰:

当当的客服:
你好
非常感谢你能及时反馈
但遗憾的是问题并没有能解决。
实际上如果可以仔细看一下的话,我早在今年6月19日就在此商品单页中提出关于印刷版次的问题,但半年过去了,至今没有任何答复。
现如今我直接发邮件给客服,也没能得到满意的答复。
希望当当各部门间能够更协调办事,能尽早给我们顾客一个满意的答复,谢谢。

by Shawphy

50分钟后,回信曰:

亲爱的顾客:

您好!非常感谢您对当当网的支持!

经查询,此商品为第3次印刷,印刷时间为2007/07/01,详细信息建议您察看商品的单品页面。同时此商品的内容如与网页介绍不符,建议您将其不符之处告知,以便处理。

我再日,曰:

当当的客服:
你好
非常感谢及时能够回复邮件。
但遗憾的是依然没有能解答我的问题。
此书《精通正则表达式》”第3版”指的是 原书 第3版。
与第3次印刷不是一个概念。07年7月1日应该是第1次印刷。
此书据译者的博客上说,今年08年又有过两次印刷。并且修正了第一次印刷中的大部分错误。
所以我比较关心此书到底是第几次印刷版的。
也就是我比较关心当当页面上的”印次”和”印刷时间”这两项,而不是”版次”这一项。
希望能够进一步核实。
再次感谢辛勤的工作。

此后截止至本博文发表时,尚未有进一步回音(我保证我垃圾箱里也看过了,确实没有回信了)。事实面前,各位看官心知肚明,不用我作过多评论了。

Act 5

23号星期二下午1点48分,受到了卓越的邮件:

亲爱的朋友:

您好!感谢您的email.

非常抱歉耽误您的时间了,关于您询问的精通正则表达式(第3版)问题,经与相关部门工作人员确认,此图书是第3次印刷的版本。

OK,看到邮件后,马上下单,此时是四点半左右。

Act 6
昨天收到邮件说出库了,今天中午收到书,确认是第三次印刷的版本。

=============================================
历时6天,卓越最终打出一个Good Ending,当当打出一个Bad Ending。
最后指出一个卓越的小瑕疵,我在邮件的反馈里提到,说希望尽快完成页面上的信息。但我书已经到了,页面上还没改。

jQuery 1.3更新的内容

2008年12月25日 – 01:59

前两天jQuery更新出了jQuery 1.3的beta版,今天有空看了看到底更新了点什么
看了下代码,选择器用上了新的引擎Sizzle咯。(Sizzle为何?见下面简介)
得益于新的引擎,选择器支持:not(div,p)这种了多重的not了
增加了一个closest方法,用来找最近的一个匹配选择器的父元素。
LiveQuery似乎也集成了,用$(elem).live(type,fn)就能注册事件了,新添加的元素也同样享受这个服务~无须重新帮定了。不想要的时候让他die()就行了。
更多的还没来得及看,不过看到了JavaEye上的文章,把这次的更新都说全了。可以移步去看看。Cloudream在两个月前就对jQuery 1.3的alpha有所阐述了,建议也可以看看。
这次刚刚升级的大版本Bug一般都会很多,所以请不要急着用于产品中,建议等到明年3、4月份的时候有没有新的修正版出来的时候再升级到1.3版。

补充内容:
Sizzle是jQuery作者John Resig新写的DOM选择器引擎。其速度号称业界第一……
不过简单看了一下,对于支持document.querySelectorAll的浏览器就主要用这个了(比如IE8),支持getElementsByClassName的也会优先用这个(Firefox等)。
也还有一些其他优化。
如果只想要用一个出色的选择器工具而不想要引入jQuery,可以考虑直接用Sizzle,超好用。压缩后才3、4K。完全可以基于此开发一套自己的脚本库。

Help Test jQuery 1.3 Beta 1

2008年12月23日 – 02:12

jQuery: » Help Test jQuery 1.3 Beta 1.

没啥说的,jQuery 1.3的beta 1发布了,

有能力的各位都测试一下,有问题的汇报一下

把引用脚本的地址改成

http://code.jquery.com/jquery-1.3b1.js

就行。不要用min或者pack版,不好定位问题

主要改了选择器引擎,DOM操作,offset()方法,事件命名空间和事件触发等部分的逻辑。尤其是事件触发的部分,现在会冒泡了,可能导致问题。

具体jQuery 1.3会预计在1月14日发布。

发现问题可以去jQuery bug tracker 提交问题。别忘了附上精简过的测试代码就行。

[推荐]jQuery 源码分析

2008年12月22日 – 13:18

不得不承认,我看到这个帖子晚了好几个月。
但幸运的是,我在年末的时候看到了。Better late than never.
就当作圣诞礼物送给我自己吧。
也送给各位:
http://jljlpch.javaeye.com/blog/234218
非常全面得分析了jQuery 1.2.6
100多页的pdf文档,引用fins的话是,这是今年JavaEye上精华中的精华了。
没看过的请务必去看一下。

json2select

2008年12月20日 – 13:57

这是我之前为了ThinkSNS写的一个小工具。通过json生成无限联动的select。至少要求jQuery 1.2.3 以上,因为我用了data方法。
查看DEMO 源文件 min版

  1. //构建如下json,t为列表框的text,v为列表框的value,s表示子一级对象
  2. var json=[
  3.     {
  4.         t:"欧洲某地",
  5.         v:"欧洲"
  6.     },
  7.     {
  8.         t:"中国某地",
  9.         v:"中国",
  10.         s:[
  11.             {
  12.                 t:"上海",
  13.                 v:"上海"
  14.             },
  15.             {
  16.                 t:"云南某地",
  17.                 v:"云南",
  18.                 s:[
  19.                     {
  20.                         t:"大理",
  21.                         v:"大理"
  22.                     }
  23.                 ]
  24.             }
  25.         ]
  26.     },
  27.     {
  28.         t:"日本某地",
  29.         v:"日本",
  30.         s:[
  31.             {
  32.                 t:"东京",
  33.                 v:"东京"
  34.             },
  35.             {
  36.                 t:"北海道",
  37.                 v:"北海道",
  38.                 s:[
  39.                     {
  40.                         t:"北海道的某个地方",
  41.                         v:"北海道的某个地方"
  42.                     }
  43.                 ]
  44.             }
  45.         ]
  46.     }
  47. ];
  48. //调用即可
  49. $("#selectt").json2select(json,["中国","云南","大理"]);

另外,如果用1.2.1的也想用的话,可以手动提取1.2.6里的data方法,或者简单用下面的模拟一下即可

  1. (function($) {
  2.     $.fn.data=function(key,value) {
  3.         return $.data(this[0],key,value);
  4.     }
  5. })(jQuery);

update:
附: 全国城市数据
并且更新到了 1.0.1版。以前下载的同学可以重新下载一份。

FireUnit:基于Firebug的JavaScript单元测试扩展

2008年12月18日 – 16:43

John Resig最近在他的博客中发表文章John Resig – FireUnit: JavaScript Unit Testing Extension.发布了他与Jan Odvarko合作开发的一款基于Firebug的扩展FireUnit。(Firebug真是越来越强大了……)
简单说来,FireUnit给Firebug增加了一个标签面板,并提供了一些简单的JavaScript API来记录和查看测试。
举例来说:

  1. // Simple true-like/false-like testing
  2. fireunit.ok( true, "I'm going to pass!" );
  3. fireunit.ok( false, "I'm going to fail!" );
  4.  
  5. // Compare two strings - shows a diff of the
  6. // results if they're different
  7. fireunit.compare(
  8.   "The lazy fox jumped over the log.",
  9.   "The lazy brown fox jumped the log.",
  10.   "Are these two strings the same?"
  11. );
  12.  
  13. // Compare a string using a regular expression
  14. fireunit.reCompare(
  15.   /The .* fox jumped the log./,
  16.   "The lazy brown fox jumped the log.",
  17.   "Compare a string using a RegExp."
  18. );
  19.  
  20. // Display the total results
  21. fireunit.testDone();

就可以在Firebug中的Test标签面板中看到下图:

fireunit测试

FireUnit还可以模拟触发原生浏览器事件:

  1. // You can also simulate browser events
  2. var input = document.getElementsByTagName("input")[0];
  3. fireunit.mouseDown( input );
  4. fireunit.click( input );
  5. fireunit.focus( input );
  6. fireunit.key( input, "a" );

此外,可以批量测试文件(每个文件都含有一些独立测试)

  1. // Or run multiple pages of tests:
  2. fireunit.runTests("test2.html", "test3.html");
  3.  
  4. // Place at the end of every test file in order to continue
  5. fireunit.testDone();

fireunit批量测试

推荐把测试代码包含在下面的if语句内

  1. if ( typeof fireunit === "object" ) {
  2.         //Your code for test
  3. }

如果感兴趣,可以访问Fireunit.org下载并测试(这个网站内就包含了测试代码,安装后即可看到第一张图的内容)
可以在Github上获取源码,得用git而不是svn
Jan也写了一篇文章,可以看看。

jQuery中不为人知的秘密之三——判断元素上是否绑定了事件

2008年12月17日 – 16:26

好久没写博客了,抱歉抱歉,最近半年很忙很忙。
正好群里 Q.Lee.lulu 问起怎样判断有没有绑定一个事件。
我研究了一下之后发现,jQuery都将事件缓存起来了,其实也是为了防止内存溢出以及页面unload的时候的速度,也包括多函数触发,方便管理等诸多好处,具体可以参考此文
jQuery会在window.unload的时候卸载所有绑定过的事件,释放内存的。

OK,言归正传。判断元素上是否绑定过事件用如下语句

  1. jQuery.data(elem,"events")[type]  //老版本也能用
  2. $(elem).data("events")[type]  //1.2.3以后才能用

返回值:
一个Object,可以用for in来遍历。或者undefined。
参数:
elem是一个DOM对象,type是事件类型。
举例:
判断id为foo的元素上是否绑定了click事件

  1. if( $("#foo").data("events")["click"] ){
  2.     //your code
  3. }

“另类”的阻止冒泡

2008年12月13日 – 01:58

论坛里有人问

HTML:
<div id=”b”>
<div>sssssssssssss</div>
<div>aaaaaaaaaaaa</div>
</div>

JQ;
$(‘div:contains(aaa)’).addClass(‘aa’);

如何才能让这个id=”b”的div不要被选择器匹配到呢?

底下讨论了老半天基本都是无解,只能回避这个问题,加入class之类的限定条件。

后来我仔细翻了翻API,发现还有filter这个方法可以用。

之后还不过瘾,写了个选择器插件,需要的同学可以拿去用。

直接上代码了,写的不好,有能力的帮忙优化一下,毕竟选择器函数属于运算密集型函数。
filter方法:

  1. $('div:contains(aaa)').filter(function() {
  2.       return $(this).children().length == 0;
  3. });

选择器插件:

  1. <div>
  2.         <div>shawphy</div>
  3.         <div>this is a demo -- shawphy</div>
  4.         <div>test</div>
  5.         <div>test</div>
  6. </div>
  1. /*
  2.         Shawphy:用于查找不含子元素的元素(可以包含文本,不同于:empty选择器)
  3. */
  4.         ;(function($) {
  5.                 $.extend($.expr[":"], {
  6.                         nochild : function( a ) {
  7.                                 return $(a).children().length == 0; //Shawphy:子元素数量为0的元素会被保留
  8.                         }
  9.                 });
  10.         })(jQuery);
  11.         //Shawphy:测试是否能查到所需要的东西
  12.         alert($('div:contains(shawphy):nochild').length)

jQuery中不为人知的秘密之二

2008年8月10日 – 19:13

又开始写jQuery的秘密了~
这里写的基本上都是没啥用的东西,大家随便看看好了,有用的都放在文档里了~

这回先说选择器,
两个特殊的选择器,没有在文档里列出来。有可能只是选择器正则匹配的失误,也可能是故意的,但我源码中看不出来。望各位看官指点。注意,下面两个特殊选择器,随时可能在以后版本中消失,慎用。本文涉及的是1.2.6,经测试1.2.3也可使用。

创建一个空jQuery对象:

  1. $(" ");   //切记,引号中间至少有_一个_空格

这段简易的代码即可创建一个空的jQuery对象。这就类似创建一个代码片段。但由于是空的,所以无法append进任何东西。但你可以用add将你要的东西添加进去。

获取document,有时候需要写一些关于document的事件,比如keypress之类的,或者其他的,就可以用

  1. $("");   //切记,引号中间_没有_空格

这一定程度上可以用于混淆代码,比如将$(document).ready()写成$(“”).ready(),不知道的人就看不懂了。当然,要看过本文的人就都知道了~~(笑~)

顺便一说,前端加密是没有可能的,混淆也是有限度的。有jQuery的操作是链式操作,没有中间变量,同时通常绑定函数也是匿名函数,所以对于jQuery代码的混淆更是没有太大用处。除非,不再使用匿名函数,每次都外部定义一个。同时不再使用链式操作,用next,parent之类操作的时候,统统再定义一个中间变量。这样你的jQuery代码已经没有jQuery风格了,对混淆会稍微有点点帮助。注意,以上所有混淆操作,只防君子不防小人!切记,前端开发不可能加密!所以一切都做好开源的准备!了解GPL、MIT之类的都是有必要的!

如果你要用中间变量,像前面说的为了混淆,有时候你可能需要用到之前的一个对象,就好像在链式写法中用end()的效果,那就可以用prevObject属性,end()就是返回这个属性。

  1. $("#id").prevObject;   //切记,最后没有括号,这个是属性不是方法

下面说的这个其实不是很秘密,但值得一提
attr是很伟大的方法,以下这些都是可以执行的,你就可以通过这些来进行一些简单的判断,比如这个元素的标签名啦之类的。

  1. $("body").attr("tagName");
  2. $("body").attr("nodeName");
  3. $("body").attr("nodeType");

还有个相关的,他返回的是布尔值true/false

  1. jQuery.nodeName( elem, nodeName )

第一个参数是一个DOM对象,不是jQuery对象,第二个就是节点名称(标签名)了,大小写无关。返回true/false
有人问,为什么我不直接使用elem.nodeName==nodeName呢,爱用写这么麻烦呢?
看一下jQuery的源码就知道了

  1. nodeName: function( elem, name ) {
  2.     return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
  3. },

明白了么?浏览器兼容性问题,某些浏览器中的nodeName是大写,有些是小写,够恶心吧?
兼容一下总是好的~~