jQuery中queue和dequeue的用法

jQuery中的queue和dequeue是一组很有用的方法,他们对于一系列需要按次序运行的函数特别有用。特别animate动画,ajax,以及timeout等需要一定时间的函数

queue和dequeue的过程主要是:
1,用queue把函数加入队列(通常是函数数组)
2,用dequeue将函数数组中的第一个函数取出,并执行(用shift()方法取出并执行)

也就意味着当再次执行dequeue的时候,得到的是另一个函数了
同时也意味着,如果不执行dequeue,那么队列中的下一个函数永远不会执行

对于一个元素上执行animate方法加动画,jQuery内部也会将其加入名为 fx 的函数队列
而对于多个元素要依次执行动画,则必须我们手动设置队列进行了。

一个例子,要两个div依次向左移动,点击这里查看

div {
background:#aaa;
width:18px;
height:18px;
position:absolute;
top:10px;
}

如果只是轮流移动次数较少,可以使用animate的回调函数来做,一个动画放在另一个动画的回调里边
比如

$(“#block1″).animate({left:”+=100”},function() {
$(“#block2″).animate({left:”+=100”},function() {
$(“#block1″).animate({left:”+=100”},function() {
$(“#block2″).animate({left:”+=100”},function() {
$(“#block1″).animate({left:”+=100”},function(){
alert(“动画结束”);
});
});
});
});
});

但这种方法当动画较多的时候简直是残忍。

此时利用queue和dequeue则显得简单很多:

var FUNC=[
function() {$(“#block1″).animate({left:”+=100”},aniCB);},
function() {$(“#block2″).animate({left:”+=100”},aniCB);},
function() {$(“#block1″).animate({left:”+=100”},aniCB);},
function() {$(“#block2″).animate({left:”+=100”},aniCB);},
function() {$(“#block1″).animate({left:”+=100”},aniCB);},
function(){alert(“动画结束”)}
];
var aniCB=function() {
$(document).dequeue(“myAnimation”);
}
$(document).queue(“myAnimation”,FUNC);
aniCB();

1,我首先建议建立了一个函数数组,里边是一些列需要依次执行的动画
2,然后我定义了一个回调函数,用dequeue方法用来执行队列中的下一个函数
3,接着把这个函数数组放到document上的myAnimation的队列中(可以选择任何元素,我只是为了方便而把这个队列放在document上)
4,最后我开始执行队列中的第一个函数

这样做的好处在于函数数组是线性展开,增减起来非常方便。
而且,当不要要继续进行接下来动画的时候(比如用户点了某个按钮),只需要清空那个队列即可。而要增加更多则只需要加入队列即可

//清空队列
$(document).queue(“myAnimation”,[]);
//加一个新的函数放在最后
$(document).queue(“myAnimation”,function(){alert(“动画真的结束了!”)});

以前发过一个wait插件,用于让动画之间可以暂停一段时间
http://shawphy.com/2008/07/enabling-settimout-within-chained-functions-in-jquery.html
可以看一下,他也就是利用了这个原理,默认在fx中插入一个timeout,放到队列中,直到timeout结束后才执行dequeue继续执行队列中的下一个函数。

这当然也可以用于ajax之类的方法,如果需要一系列ajax交互,每个ajax都希望在前一个结束之后开始,之前最原始的方法就是用回调函数,但这样太麻烦了。同样利用queue添加队列,每次ajax之后的回调中执行一次dequeue即可。

如果没有使用jQuey库,也可以自己写段简易代码来解决这个问题。见控制队列函数

当心多余的逗号

今天看到jQuery Blog更新了 THIS WEEK IN JQUERY, VOL. 1 。里边提到一个tip ,说道经常有人问为啥写的代码在IE中运行错误,在其他浏览器下都能跑,原因是因为:

var foo = {
bar: ‘ice cream’,
baz: ‘luhrmann’, // <-- get rid of that comma! }

对,就是多了个逗号。
我哑然一笑~
我昨天也正巧碰到了同样的情况,我firefox下运行一切正常,跑到同事的ie下就报错。回来查了半天才知道原来是多了个逗号。
有时候删除几个属性的时候就会忘了删除最后一个逗号了~~

BTW:我修复并保证在IE下正常运行后,同事的遨游下依然惊爆3个错误……我无视他了……罪过罪过……(遨游难道不是IE的马甲了么?)

限定字符长度,截断中文字符

今日遇到个麻烦事。input限定输入字节数是8,中文自然算两个字节。本来一路顺利,keyup keydown keypress事件挨个试过去,把中文用正则替换成两个英文字符,超过8的就return false。ie下表现超级完美。
这个时侯Firefox下麻烦事就开始了,ie下,中文输入法状态下他也是能捕获键盘事件的。但ff下却无法捕获输入法状态下的键盘事件,比如我搜狗,他只能识别到最后那次空格……一恼火,干脆换条思路,直接截断字符来解决。效果感觉还行,总比没有好,此方法也适用于复制进去的文本。


$(“input”).bind(“keyup”,function() {
var str=this.value;
while (str.replace(/[^\x00-\xFF]/g,”aa”).length>8) {
str=str.substr(0,str.length-1);
}
this.value=str;
});

代码很简单,也很安全。想封装成其他形式请自便。

我这里用的是减法,对于input这种很合适。因为不会多出去很多字符的。
这里我事后搜到一个做加法的,也不错,可以参考一下。只是不建议像他这样直接给原生对象做扩展,容易冲突。放到自己的私有对象下会比较好。

侧边栏的twitter

最近开始用twitter了(彻底放弃饭否,用饭否的同学别伤心啊~),顺便在侧边栏放了一个用于显示tw更新的小面板~常来看的同学可能已经发现了侧边栏的小变化了~~(哦?你是订RSS的?非常支持!那麻烦你点一下本文链接就能看到啦,哈)

跑到 http://twitter.com/badges一路next后得到了一串代码

    follow me on Twitter




    到wp后台建了两个小文本,一个用于存放上面的ul,另一个用于放js,由于twitter的js加载速度实在糟糕,我不得不分开放,把js放在侧边栏最底下的地方,这样好不影响页面加载。(其实还是影响到了footer,但我都不在乎,你在乎么? XD)

    ok,你玩twitter么?玩的话follow me~

    jQuery 1.2.6和jQuery 1.3.1的特殊字符选择器极限测试

    心血来潮,把键盘上能按出来的特殊字符都按了个遍
    依次是:
    ~`!@#$%^&*()_+{}|”:?><,./;'[]\ 其中<和"不能放到id里,页面显示不全之外其他都可以哦~ 分别放在中间,结尾和开头,比如te[st、te[、[st这种。 好孩子不要学哦~ 附W3C规定

    ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens (“-“), underscores (“_”), colons (“:”), and periods (“.”).

    ID和NAME必须由字母([A-Za-z]) 开头,之后可以跟任意数量的字母、数字([0-9])、短横(“-“)、下划线(“_”)、冒号(“:”)和点(“.”)。

    实验结果表明,jQuery 1.3.1的选择器对于这些BT的特殊字符没有jQuery 1.2.6强劲,jQuery 1.2.6基本上是getElementById能搞定的他都能搞定,而1.3.1中的Sizzle选择器却没这么强悍,当然这纯属测试而已,同时提醒各位同学,一定要尊崇标准啊……不要随便乱来……我知道某些会输出诸如foo[bar]之类的ID,不可取啊,不符合标准的啊……虽然#foo\\[bar\\]是能成功匹配的,但#foo\\[bar就不行。总之注意别用这些离奇的符号做ID就差不多不会有问题了。

    测试页面在这里:
    http://shawphy.com/demo/selector/jQuery-1-2-6-selector-test.html
    http://shawphy.com/demo/selector/jQuery-1-3-1-selector-test.html

    测试结果,
    1.2.6:三个失败

    te\st
    te\
    \st

    1.3.1:一坨……

    te~st
    te(st
    te+st
    te[st
    te\st
    te>st
    te,st
    te~
    te(
    te+
    te[
    te\
    te>
    te,
    ~st
    (st
    +st
    [st
    \st
    >st
    ,st
    ================
    dev maillist发了邮件,John大回复说似乎可以解决,期待一下吧。

    ================
    这个bug已经在1.3.2中修复,1.4.2中也通过了测试。
    http://shawphy.com/demo/selector/jQuery-1-3-2-selector-test.html

    jQuery 中文文档XML版以及CHM版发布

    我相信很多人在等待CHM版的发布。
    这次发布采用了XML版生成分散的文件。由于花了点时间在原先的HTML转XML上,以及一揪回家等因素,这次的CHM版姗姗来迟。但值得庆祝的是,以后的CHM版会很轻松地发布~

    如果有兴趣看我如何把jQuery文档从HTML转成XML的,可以看这个jqapi2xml
    需要Firefox 1.5以上或者使用Mozilla Gecko 1.8以上引擎的浏览器或者其他直接支持E4X的浏览器才能使用。

    新的XML版文档可以点击查看XML版。我简单写了一个XSL。其他同学如果有需要可以自行拿这个XML写其他的XSL。
    这里是英文的XML版文档。使用了同一个XSL,只是语言不同而已。可以发现这回不再是双语版了,对双语版有爱的同学我只能说对不起了,由于精力有限,无法同时维护中文版以及双语版中的英文部分。如果实在有爱,可以写脚本把上述英文版XML中说明加入中文的XML之中,并自行修改XSL。

    最后,CHM版可以直接从Google Code下载:
    http://code.google.com/p/jquery-api-zh-cn/downloads/list

    CHM版和XML版均提供查找更新功能~
    HTML版今日(2009-1-29)发布最后一版,增加2个函数以及修正些小问题。也可以从上面的地址下载。以后不再更新,请同学将收藏夹中的地址改成上述的XML版地址。

    另,据测试下来,可能有些同学会出现点击任何页面都出现下载的情况。如果这样请先使用HTML版。如果情况比较多,下一版将会采用XML+XSLT转HTML后再编译成CHM格式。据网友汇报,确认下HKEY_CLASSES_ROOT\.xml 下的Content Type是否是text/xml 再试试找到文件夹选项,文件类型里的XML处,点”还原”,可以解决这个问题

    关于jQuery xml版英文文档的一些事

    其实去年年底,jQuery 1.3尚未发布的时候就已经盘算着将中文文档以xml的形式发布了。这样有个好处,就是页面结构可以用xsl随便换。各位同学想做不同的发行版可以随便换着玩~实际上我现在愈发觉得css的局限性了,很多时候所谓的css为了后期维护方便,可以任意修改布局而无需动页面结构之类的话语已经觉得难以置信了。我就不信有多少同学遇到过改版的时候只改css而不改html的。当然也有可能是我的局限性而非css的局限性。

    所谓的圣杯布局双飞翼布局确实在很大程度上能解决布局(Layout)上的问题,但别忘了,开发工作可不只是布局,还有排版(Typography),数据结构和页面表现结构交织在一起的时候,想崩溃都觉得老板会从地域里拖你起来。

    xml+xslt这种手段其实我几年前就看到过,当时也曾为之心动,无奈当时技术水平有限无法体会其中精妙。然借此jQuery 1.3文档大改之际便又萌发了尝试的冲动。

    xml+xslt好吗?很好!居然ie 5就开始支持了,ie 6支持的程度也很不错,基本上没有遇到什么兼容性问题,比起万恶的ie6对css的支持度好多了。目前我除了发现document()函数在ie中表现的跟其他浏览器不一致之外,以及Firefox居然不支持disable-output-escaping=”yes”,并且争论长达7年多尚未有解决的迹象。除此之外似乎没发现更多问题。

    实际上让一部分处理页面的逻辑放到了前端来做,后台只负责输出数据,这种数据(XML),结构(XSLT),表现(CSS),行为(JS)4者相对分离的状态是十分有利于这个前端产业工业化发展的。随着前端工种的进一步细分,我觉得这里大有可挖。好处显而易见,如果要大面积改版(即便是小范围),由于后台只负责输出数据而没有HTML格式,高度分离的情况下,基本上只需要前端小组改一下即可。即便是对后台语言完全不了解都可以(我承认这不好)。
    此外,xslt支持include/import等语句,包括上面提到的document(),可以很方便的实现页面各个部分的模块化。

    但随之带来的问题也显而易见,数据过于结构化,页面内容轻易被人抓取而后分析(都不用分析……直接解析……)
    此外,很多pda,手机之类的可能对xslt无法解析,但我估计屏幕阅读器应该没问题,因为很多屏幕阅读器都是基于现有浏览器的,也就是说现有浏览器支持,他也就支持。
    还有上面提到的模块化问题,一不小心就可能导致连接数过多。每个模块的粒度得把握好。

    解决这些问题的一个简单途径是,xml+xslt在服务器端解析生成。服务器端可以通过检测浏览器来判断直接输出xml+xslt还是输出生成的页面。这对于pda和手机之类的能提高很大兼容性。而对于一般浏览器又无需消耗服务器资源。
    网上有篇流传甚广的文章XML在B/S架构开发中的应用,正是描述了此类情景。我考据下来可能是原著地址(我找到个更早的地址但上面的写的作者也是他,请宽恕我的网络考古情结)。

    其中也提到了http://xml.apache.org/cocoon/ 似乎可以直接使用,没深究。

    好了,得回到正题了。jQuer现在弄了个专门是放api的地址:http://api.jquery.com。说实话,我一直很不喜欢他现在弄的样子,当我需要在不同的方法之间切换的时候很不方便。有喜欢的可以自己尝试。另外,分析代码发现原来这个api也是从wiki里扣出来的xml进行解析得来的。另有air版,喜欢的可以自己下。扣的程序是Python 2.4写的,遗憾我这里只有Py3k环境,执行失败,且自己道行过浅,无法改成3.0版以供自己用。忘有此能力的同学能帮我改一下,可直接从jq的svn里拿到,点击下载。没有达人帮忙其实也没事,见到还有地址可以在线生成,前面在线生成的地址如果不加参数则可以直接查看这个生成器的文档。用urllib.request.urlretrieve(url,path)直接下载真的是很惬意的事情,Python真的是很强悍啊……
    我随便写了个xslt,可以直接浏览jQuery 的英文文档。暂不提供下载,喜欢的就自己另存为吧……不喜欢的就自己写一套吧……
    暂时计划是将中文文档转换成xml(这步已经在前天完成,转的我残念……请原谅我能力有限只能用这么离奇的办法转格式……)。不过之前写这个的时候还没有看到上面那个wiki2xml生成器(其实早就见过了,被我无视了而已……),所以对应的标签以及格式还不是很对上号。改天整整。另外,单个xml拆分成散件的xml的py脚本也写完了,实验成功,现在生成chm版的文档只差单文件xml的校对和chm文件的目录以及索引之类的编辑工作了。不用太期待……一揪回家了……新年饭局又多……饿……大半夜的吐槽可真不好……睡去了……

    我为什么使用Google CDN

    自从之前jQuery 1.3版起,就已经没有提供pack版了,而我也十分赞成使用Google CDN进行代码托管。

    这样做有以下几个好处:
    1,更小下载量。
    都知道jQuery 1.3 pack后有38k之多,如果当然可以删除版权注释以获得更小的代码,遗憾的是这不仅无耻且只节约1个k都不到。而同样利用Google APIs 提供的GZip过的Min版,只有18k,对用户来说下载量更小。

    2,减轻服务器压力。
    虽然现代浏览器都有了缓存,但以前我看到过资料说某大型网站发现他们70%的访客缓存都是空的(哪位同学能帮忙找到资料请下面留言,不胜感激~)。所以,让Google为我们提供服务,而不用自己操心自己的流量~少个库可以少个连接数,何乐而不为。

    3,多个网站共享缓存。

    如果用户访问的多家网站都使用Google提供的jQuery,那么对于用户来说,只需要缓存一次后即可只读取缓存中的数据!而不是每个网站都要重新下载一份。对此进一步加快用户访问速度。

    4,更快执行速度。
    jQuery 1.3.1发布的发布信息中,为jQuery不提供pack版给出了官方的解释。除了不易debug,在Adobe AIR和Caja-capable等环境下无法使用之外,更重要的是因为执行速度问题。随着jQuery逐渐变“胖”,用pack压缩后在浏览器端“解压缩”所需要的资源越来越大。想象一个超大的字符串多次replace后再eval的情景……这不比直接读取一个不需要解压缩的min版来得快。John给出了一些数据,有兴趣的同学可以看看。

    反对的声音:
    “不安全”、“没安全感”、“放别人的机器太危险了”、“他们服务器倒了呢?”、“以前刚开始的时候就down过”

    我认为(晕……怎么我觉得我在写四六级作文……)Google服务器down的几率与我们自己服务器down的几率不会有显著性差异(抱歉,我又空口无凭说话了……不过如果哪位同学能给出数据来拒绝我的零假设,认可备选假设的,欢迎提供,再次不胜感激~)。所以就放他们那边吧,挺安全的。

    另外我还听到关于不能让整个世界为着Google转,Google阴谋论,Google威胁论的声音。实际上Google确实正朝这个方向发展,让整个互联网围着他转。可以看他提供的一些服务,什么云计算,什么App Engine之类的,都企图让人们的应用都建立在Google至上,当Google成为了空气的时候,他已经无处不在了。这点来说,值得担忧。

    万恶的弹窗广告

    或许是我孤陋寡闻,但我在国内第一次看到弹窗的复兴是从淘宝开始的。在各大浏览器纷纷将未经用户交互而弹出的广告封杀的时候,淘宝采用了给document绑定click事件的方式调用window.open来弹出广告。

    当然,淘宝还算文明,弹窗放到了后头,并且似乎一天只弹一次。我这里也不是为了谴责淘宝的前端们,也能理解他们也实属无奈。

    自从那时起,神州大地便四处开花。各个网站的站长似乎找到了救命稻草,弹窗广告又活了!大有“我胡汉三又回来啦”的气势。我见过最离谱的是直接给document的mousemove事件帮上弹窗广告,你鼠标只要移到页面内就会弹窗!而不像淘宝那样等你点击了才弹窗。

    注意,我写此文的并非告诉各位同学新式弹窗的秘诀。相信各位同学也都是非常反感弹窗的。如果哪位擅自将上述秘籍用于实际项目必将遭受广大群众的谴责!请三思。

    此问真正的缘由是:近日我经常光顾一些垃圾站点,弹窗之猖獗实属罕见,一怒之下写了脚本将window.open劫持,看谁还敢弹广告~嗯哼~

    继续阅读万恶的弹窗广告