<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>幼学笔记</title>
	<atom:link href="http://www.oncoding.cn/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.oncoding.cn</link>
	<description>追寻简单生活</description>
	<lastBuildDate>Sun, 29 May 2011 14:03:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>小记JavaScript享元模式</title>
		<link>http://www.oncoding.cn/2011/javascript-flyweight/</link>
		<comments>http://www.oncoding.cn/2011/javascript-flyweight/#comments</comments>
		<pubDate>Sun, 29 May 2011 12:18:19 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[扯淡]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=875</guid>
		<description><![CDATA[最下面是周五懒懒分享的PPT，不得不承认，强大如斯的keynote，也能让我做出这么丑的PPT。。 09年就买了《JavaScript设计模式》，前后看了几次（是“次”，不是“遍”），刚开始看没什么收获，后来随着编码经验、遇到的问题越来越多，看这本书也越来越觉得好。现在都快当成了工具书，遇到难题就去翻翻，常看常新。 设计模式是编码的最佳实践，它应用在两个层次：解决特定编码问题、设计程序架构。 简单记录一下“享元模式”及其在解决特定问题上的应用。 应用场景 1. 页面存在大量资源密集型对象； 2. 这些对象具备一定的共性，可以抽离出公用的操作和数据。 场景举例 例1. 倒计时 具备校准功能的倒计时组件，校准、定时操作耗费大量的系统资源。如果页面中存在多个倒计时对象，显然要考虑把校准、定时抽离出来，统一控制所有的实例对象。 例2. 弹层交互 页面中多处的按钮、链接、Ajax操作可能触发相同的弹层，虽然触发方式各异，但同时只存在一个弹层且样式相近。这时可以考虑把创造、弹出弹层的操作从各处抽离出来统一管理。 例3. 数据交互 页面存在多种类似的数据交互，每个交互作为独立的对象，可以把数据发送、接收、处理、显示等相同的操作抽离出来形成“享元”。 组成部分 “享元”：抽离出来的外部操作和数据； “工厂”：创造对象的工厂； “存储器”：存储实例对象的对象或数组，供“享元”来统一控制和管理。 关键 1. 合理划分内部和外部数据。 既要保持每个对象的模块性、保证享元的独立、可维护，又要尽可能多的抽离外部数据。 如何权衡？极限编程中有个YAGNI原则 —— you ain&#8217;t gonna need it，放在这里即是说，设计系统时，把精力放在最需要的地方，而忽略一些无关紧要的细节。一个优美的系统，完全可以遮盖其中一些小hack带来的瑕疵。不多说了，重在权衡。 2. 管理所有实例 既然抽离出了外部数据和操作，那享元就必须可以访问和控制实例对象。在JavaScript这种动态语言中，这个需求是很容易实现的：我们可以把工厂生产出的对象简单的扔在一个数组中。为每个对象设计暴露给外部的方法，便于享元优雅的控制。 3. 享元的职责开关 例如倒计时的享元，如果页面中所有的倒计时都跑完了，所有的对象都已停止工作，那显然享元不应继续做这些高能耗的工作。使用一个外部标记变量，每个对象起始时都来设置这个标记，享元则通过这个标记来决定是否继续进行例行工作。 优点 1. 将能耗大的操作抽离成一个，在资源密集型系统中，可大大减少资源和内存占用； 2. 职责封装，这些操作独立修改和维护； 缺点 1. 增加了实现复杂度。 将原本由一个工厂方法实现的功能，修改为了一个享元+一个工厂+一个存储器。 2. 对象数量少的情况，可能会增大系统开销。 原因同上，权衡参照优点1。 实现 下面是一个带校准功能的倒计时组件的基本代码结构，该学学画图了。。 Keynote [...]]]></description>
			<content:encoded><![CDATA[<p>最下面是周五懒懒分享的PPT，不得不承认，强大如斯的keynote，也能让我做出这么丑的PPT。。</p>
<p>09年就买了《JavaScript设计模式》，前后看了几次（是“次”，不是“遍”），刚开始看没什么收获，后来随着编码经验、遇到的问题越来越多，看这本书也越来越觉得好。现在都快当成了工具书，遇到难题就去翻翻，常看常新。</p>
<p>设计模式是编码的最佳实践，它应用在<strong>两个层次：解决特定编码问题、设计程序架构</strong>。</p>
<p>简单记录一下“享元模式”及其在解决特定问题上的应用。</p>
<h3>应用场景</h3>
<p><span id="more-875"></span></p>
<p>1. 页面存在大量资源密集型对象；</p>
<p>2. 这些对象具备一定的共性，可以抽离出公用的操作和数据。</p>
<h3>场景举例</h3>
<h4>例1. 倒计时</h4>
<p>具备校准功能的倒计时组件，校准、定时操作耗费大量的系统资源。如果页面中存在多个倒计时对象，显然要考虑把校准、定时抽离出来，统一控制所有的实例对象。</p>
<h4>例2. 弹层交互</h4>
<p>页面中多处的按钮、链接、Ajax操作可能触发相同的弹层，虽然触发方式各异，但同时只存在一个弹层且样式相近。这时可以考虑把创造、弹出弹层的操作从各处抽离出来统一管理。</p>
<h4>例3. 数据交互</h4>
<p>页面存在多种类似的数据交互，每个交互作为独立的对象，可以把数据发送、接收、处理、显示等相同的操作抽离出来形成“享元”。</p>
<h3>组成部分</h3>
<p><strong>“享元”：</strong>抽离出来的外部操作和数据；</p>
<p><strong>“工厂”：</strong>创造对象的工厂；</p>
<p><strong>“存储器”：</strong>存储实例对象的对象或数组，供“享元”来统一控制和管理。</p>
<h3>关键</h3>
<h4>1. 合理划分内部和外部数据。</h4>
<p>既要保持每个对象的模块性、保证享元的独立、可维护，又要尽可能多的抽离外部数据。</p>
<p>如何权衡？极限编程中有个<strong>YAGNI</strong>原则 —— you ain&#8217;t gonna need it，放在这里即是说，设计系统时，把精力放在最需要的地方，而忽略一些无关紧要的细节。一个优美的系统，完全可以遮盖其中一些小hack带来的瑕疵。不多说了，重在权衡。</p>
<h4>2. 管理所有实例</h4>
<p>既然抽离出了外部数据和操作，那享元就必须可以访问和控制实例对象。在JavaScript这种动态语言中，这个需求是很容易实现的：我们可以把工厂生产出的对象简单的扔在一个数组中。为每个对象设计暴露给外部的方法，便于享元优雅的控制。</p>
<h4>3. 享元的职责开关</h4>
<p>例如倒计时的享元，如果页面中所有的倒计时都跑完了，所有的对象都已停止工作，那显然享元不应继续做这些高能耗的工作。使用一个外部标记变量，每个对象起始时都来设置这个标记，享元则通过这个标记来决定是否继续进行例行工作。</p>
<h3>优点</h3>
<p>1. 将能耗大的操作抽离成一个，在资源密集型系统中，可大大减少资源和内存占用；</p>
<p>2. 职责封装，这些操作独立修改和维护；</p>
<h3>缺点</h3>
<p>1. 增加了实现复杂度。</p>
<p>将原本由一个工厂方法实现的功能，修改为了一个享元+一个工厂+一个存储器。</p>
<p>2. 对象数量少的情况，可能会增大系统开销。</p>
<p>原因同上，权衡参照优点1。</p>
<h3>实现</h3>
<p>下面是一个带校准功能的倒计时组件的基本代码结构，该学学画图了。。</p>
<p><a href="http://www.oncoding.cn/wp-content/uploads/2011/05/图片1.png"><img class="aligncenter size-full wp-image-876" title="图片1" src="http://www.oncoding.cn/wp-content/uploads/2011/05/图片1.png" alt="" width="377" height="670" /></a></p>
<p>Keynote</p>
<div id="__ss_8141078" style="width: 425px;">
<p><strong style="display: block; margin: 12px 0 4px;"><a title="倒计时优化点滴" href="http://www.slideshare.net/j5726/ss-8141078">倒计时优化点滴</a></strong><object id="__sse8141078" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=newtimer-110529071406-phpapp02&amp;stripped_title=ss-8141078&amp;userName=j5726" /><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=newtimer-110529071406-phpapp02&amp;stripped_title=ss-8141078&amp;userName=j5726" name="__sse8141078" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="padding: 5px 0 12px;">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/j5726">j5726</a>.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2011/javascript-flyweight/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>HTML邮件编码禁忌</title>
		<link>http://www.oncoding.cn/2010/email-coding/</link>
		<comments>http://www.oncoding.cn/2010/email-coding/#comments</comments>
		<pubDate>Mon, 08 Nov 2010 13:25:56 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[邮件]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=860</guid>
		<description><![CDATA[今天做了两个HTML邮件模板，记录一下所得： 禁忌 1. 结构尽量简单，最好使用table布局 可以保证在CSS样式失效、或者html被禁用的情况下最大程度的还原布局和样式。 2. 不要使用&#60;head&#62;标签 一般会被过滤掉。 3. 不要使用JavaScript和Flash 正常情况下这个是绝对被过滤的。。 4. 使用内联CSS样式，不要引入外部CSS文件，不要使用&#60;style&#62;标签 Gmail等不支持style标签。 5. CSS禁忌：不要使用绝对定位，不要使用背景图片，不要使用半透明，不要使用IE滤镜和CSS表达式，不要使用CSS3属性…… 6. 图片要添加alt属性，保证在禁用图片的情况下传递有效信息 7. 图片添加宽高属性 8. 不要试图使用iframe引入外部页面 9. 尽量精简代码，减少图片数量和体积 10. 一般使用UTF-8编码 邮件客户端/服务商对CSS支持情况 转自baidu，来源未知，未完全验证。（这么看好不方便，博客该改成宽版了。。） 参考 一篇不错的文章：http://www.docin.com/p-32193901.html]]></description>
			<content:encoded><![CDATA[<p>今天做了两个HTML邮件模板，记录一下所得：</p>
<h3>禁忌</h3>
<p>1. 结构尽量简单，最好使用table布局</p>
<p>可以保证在CSS样式失效、或者html被禁用的情况下最大程度的还原布局和样式。</p>
<p>2. 不要使用&lt;head&gt;标签</p>
<p>一般会被过滤掉。</p>
<p>3. 不要使用JavaScript和Flash</p>
<p>正常情况下这个是绝对被过滤的。。</p>
<p>4. 使用内联CSS样式，不要引入外部CSS文件，不要使用&lt;style&gt;标签</p>
<p>Gmail等不支持style标签。</p>
<p>5. CSS禁忌：不要使用绝对定位，不要使用背景图片，不要使用半透明，不要使用IE滤镜和CSS表达式，不要使用CSS3属性……</p>
<p>6. 图片要添加alt属性，保证在禁用图片的情况下传递有效信息</p>
<p>7. 图片添加宽高属性</p>
<p>8. 不要试图使用iframe引入外部页面</p>
<p>9. 尽量精简代码，减少图片数量和体积</p>
<p>10. 一般使用UTF-8编码</p>
<h3>邮件客户端/服务商对CSS支持情况</h3>
<p><span id="more-860"></span></p>
<p>转自<a target="_blank" href="http://hi.baidu.com/qingsongkkk/blog/item/adc92502675cc48ae850cdd4.html/cmtid/accf14969de6ea10d31b7041" mce_href="http://hi.baidu.com/qingsongkkk/blog/item/adc92502675cc48ae850cdd4.html/cmtid/accf14969de6ea10d31b7041">baidu</a>，来源未知，未完全验证。（这么看好不方便，博客该改成宽版了。。）</p>
<p><a target="_blank" href="http://www.oncoding.cn/wp-content/uploads/2010/11/1.jpg" mce_href="http://www.oncoding.cn/wp-content/uploads/2010/11/1.jpg"><img src="http://www.oncoding.cn/wp-content/uploads/2010/11/1-300x228.jpg" mce_src="http://www.oncoding.cn/wp-content/uploads/2010/11/1-300x228.jpg" alt="" title="1" width="300" height="228" class="aligncenter size-medium wp-image-861" /></a></p>
<p><a target="_blank" href="http://www.oncoding.cn/wp-content/uploads/2010/11/2.jpg" mce_href="http://www.oncoding.cn/wp-content/uploads/2010/11/2.jpg"><img src="http://www.oncoding.cn/wp-content/uploads/2010/11/2-300x222.jpg" mce_src="http://www.oncoding.cn/wp-content/uploads/2010/11/2-300x222.jpg" alt="" title="2" width="300" height="222" class="aligncenter size-medium wp-image-862" /></a></p>
<p><a target="_blank" href="http://www.oncoding.cn/wp-content/uploads/2010/11/3.jpg" mce_href="http://www.oncoding.cn/wp-content/uploads/2010/11/3.jpg"><img src="http://www.oncoding.cn/wp-content/uploads/2010/11/3-300x212.jpg" mce_src="http://www.oncoding.cn/wp-content/uploads/2010/11/3-300x212.jpg" alt="" title="3" width="300" height="212" class="aligncenter size-medium wp-image-863" /></a></p>
<p><a target="_blank" href="http://www.oncoding.cn/wp-content/uploads/2010/11/4.jpg" mce_href="http://www.oncoding.cn/wp-content/uploads/2010/11/4.jpg"><img src="http://www.oncoding.cn/wp-content/uploads/2010/11/4-265x300.jpg" mce_src="http://www.oncoding.cn/wp-content/uploads/2010/11/4-265x300.jpg" alt="" title="4" width="265" height="300" class="aligncenter size-medium wp-image-864" /></a></p>
<p><a target="_blank" href="http://www.oncoding.cn/wp-content/uploads/2010/11/5.jpg" mce_href="http://www.oncoding.cn/wp-content/uploads/2010/11/5.jpg"><img src="http://www.oncoding.cn/wp-content/uploads/2010/11/5-300x140.jpg" mce_src="http://www.oncoding.cn/wp-content/uploads/2010/11/5-300x140.jpg" alt="" title="5" width="300" height="140" class="aligncenter size-medium wp-image-865" /></a></p>
<h3>参考</h3>
<p>一篇不错的文章：<a target="_blank" href="http://www.docin.com/p-32193901.html">http://www.docin.com/p-32193901.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/email-coding/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>再探JavaScript单元测试</title>
		<link>http://www.oncoding.cn/2010/javascript-unit-testing/</link>
		<comments>http://www.oncoding.cn/2010/javascript-unit-testing/#comments</comments>
		<pubDate>Fri, 22 Oct 2010 10:35:34 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[扯淡]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=854</guid>
		<description><![CDATA[javascript-unit-testing View more presentations from j5726. 参考： Understanding JavaScript Testing Agile JavaScript Testing JavaScript Unit Testing]]></description>
			<content:encoded><![CDATA[<div style="width:425px" id="__ss_5528420"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/j5726/javascriptunittesting" title="javascript-unit-testing">javascript-unit-testing</a></strong><object id="__sse5528420" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=random-101022054140-phpapp02&#038;stripped_title=javascriptunittesting&#038;userName=j5726" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse5528420" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=random-101022054140-phpapp02&#038;stripped_title=javascriptunittesting&#038;userName=j5726" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/j5726">j5726</a>.</div>
</div>
<p>参考：</p>
<p><a href="http://www.slideshare.net/kissyteam/understanding-javascript-testing-5450133">Understanding JavaScript Testing</a></p>
<p><a href="http://www.slideshare.net/joydivider/agile-javascript-testing">Agile JavaScript Testing</a></p>
<p><a href="http://www.slideshare.net/chrisjoha/javascript-unit-testing-3912063">JavaScript Unit Testing</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/javascript-unit-testing/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>使用OpenCV开发iOS图像处理应用(To be continued..)</title>
		<link>http://www.oncoding.cn/2010/opencv-ios-programming/</link>
		<comments>http://www.oncoding.cn/2010/opencv-ios-programming/#comments</comments>
		<pubDate>Thu, 07 Oct 2010 14:25:59 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[扯淡]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=826</guid>
		<description><![CDATA[呃，OpenCV(中文)是Intel主导的开源图像处理函数库，基于C语言编写，是图像处理领域居家旅行必备、男女老少咸宜的开发库。 上学的时候用OpenCV做过图像处理方面的开发，现在刚接触iOS，了解了一下OpenCV在iOS平台的配置和开发方法，配置过程和遇到的问题简单做一下记录。 环境配置 OpenCV src 首先把最新版本的OpenCV代码下载或co到本地，比如我把OpenCV-2.1.0.tar.bz2解压到本地目录/work/src/OpenCV。 Xcode工程配置 拿来主义，国外有人制作了适用于iPhone和iPad的OpenCV的iOS接口，他们提供了两个工程，可以直接下载使用。打开iPhone工程OpenCV-iPhone.xcodeproj，首先要进行几步简单的设置： 1. SDK版本 作者提供的工程SDK版本可能和你开发环境的不同（我下载到的是基于4.0的），需要设置成你使用的SDK版本：在Groups&#038;Files窗口的工程文件根目录右键-Get Info，在build栏的Base SDK一项中，改为你的SDK版本： 2. 链接标记 Other linker flags 本地的OpenCV库要链接进Xcode工程中，在Get Info的build项中，搜索 Other Linker Flags，添加相应的链接标记： iPhone真机调试： -lstdc++ -lz “$(SRCROOT)/OpenCV/lib/iPhoneOS/lib/libcv.a” “$(SRCROOT)/OpenCV/lib/iPhoneOS/lib/libcxcore.a” 模拟器调试： -lstdc++ -lz “$(SRCROOT)/OpenCV/lib/iPhoneSimulator/lib/libcv.a” “$(SRCROOT)/OpenCV/lib/iPhoneSimulator/lib/libcxcore.a” 3. 头文件搜索路径 Header search paths 为方便的调用OpenCV头文件，要设置头文件搜索路径，同样在build项中搜索Header search paths，添加相应的内容： iPhone真机调试： “$(SRCROOT)/OpenCV/lib/iPhoneOS/include/opencv/” “$(SRCROOT)/OpenCV/lib/iPhoneOS/include/” 模拟器调试： “$(SRCROOT)/OpenCV/lib/iPhoneSimulator/include/opencv/” “$(SRCROOT)/OpenCV/lib/iPhoneSimulator/include/” 4. Building OpenCV 有两种方式构建OpenCV，一种是转换到OpenCV target单独构建；一种是将OpenCV添加为主应用的依赖，构建主应用时一同构建。由于OpenCV的代码基本不需要修改，且构建进程很慢，所以建议对OpenCV进行单独构建。 在Groups &#038; Files窗口中的Targets栏中，双击OpenCV，点击Build [...]]]></description>
			<content:encoded><![CDATA[<p>呃，<a target="_blank" href="http://opencv.willowgarage.com/wiki/">OpenCV</a>(<a target="_blank" href="http://www.opencv.org.cn/index.php">中文</a>)是Intel主导的开源图像处理函数库，基于C语言编写，是图像处理领域居家旅行必备、男女老少咸宜的开发库。</p>
<p>上学的时候用OpenCV做过图像处理方面的开发，现在刚接触iOS，了解了一下OpenCV在iOS平台的配置和开发方法，配置过程和遇到的问题简单做一下记录。</p>
<h3>环境配置</h3>
<h4>OpenCV src</h4>
<p>首先把<a target="_blank" href="http://sourceforge.net/projects/opencvlibrary/">最新版本的OpenCV代码</a>下载或co到本地，比如我把OpenCV-2.1.0.tar.bz2解压到本地目录/work/src/OpenCV。</p>
<h4>Xcode工程配置</h4>
<p><span id="more-826"></span></p>
<p>拿来主义，国外有人制作了<a href="http://www.eosgarden.com/en/opensource/opencv-ios/overview/">适用于iPhone和iPad的OpenCV的iOS接口</a>，他们提供了两个工程，可以直接下载使用。打开iPhone工程OpenCV-iPhone.xcodeproj，首先要进行几步简单的设置：</p>
<p><strong>1. SDK版本</strong></p>
<p>作者提供的工程SDK版本可能和你开发环境的不同（我下载到的是基于4.0的），需要设置成你使用的SDK版本：在Groups&#038;Files窗口的工程文件根目录右键-Get Info，在build栏的Base SDK一项中，改为你的SDK版本：</p>
<p><a target="_blank" href="http://www.oncoding.cn/wp-content/uploads/2010/10/get-info.png"><img src="http://www.oncoding.cn/wp-content/uploads/2010/10/get-info-300x237.png" alt="" title="get-info" width="300" height="237" class="aligncenter size-medium wp-image-839" /></a></p>
<p><a target="_blank" href="http://www.oncoding.cn/wp-content/uploads/2010/10/sdk-version.png"><img src="http://www.oncoding.cn/wp-content/uploads/2010/10/sdk-version-300x168.png" alt="" title="sdk-version" width="300" height="168" class="aligncenter size-medium wp-image-840" /></a></p>
<p><strong>2. 链接标记 Other linker flags</strong></p>
<p>本地的OpenCV库要链接进Xcode工程中，在Get Info的build项中，搜索 Other Linker Flags，添加相应的链接标记：</p>
<blockquote><p>iPhone真机调试：<br />
 -lstdc++<br />
-lz<br />
“$(SRCROOT)/OpenCV/lib/iPhoneOS/lib/libcv.a”<br />
“$(SRCROOT)/OpenCV/lib/iPhoneOS/lib/libcxcore.a” </p></blockquote>
<blockquote><p>模拟器调试：<br />
 -lstdc++<br />
-lz<br />
“$(SRCROOT)/OpenCV/lib/iPhoneSimulator/lib/libcv.a”<br />
“$(SRCROOT)/OpenCV/lib/iPhoneSimulator/lib/libcxcore.a” </p></blockquote>
<p><a target="_blank"  href="http://www.oncoding.cn/wp-content/uploads/2010/10/other-linker-flags1.png"><img src="http://www.oncoding.cn/wp-content/uploads/2010/10/other-linker-flags1-300x125.png" alt="" title="other-linker-flags" width="300" height="125" class="aligncenter size-medium wp-image-850" /></a></p>
<p><strong>3. 头文件搜索路径 Header search paths</strong></p>
<p>为方便的调用OpenCV头文件，要设置头文件搜索路径，同样在build项中搜索Header search paths，添加相应的内容：</p>
<blockquote><p>
iPhone真机调试：<br />
 “$(SRCROOT)/OpenCV/lib/iPhoneOS/include/opencv/”<br />
“$(SRCROOT)/OpenCV/lib/iPhoneOS/include/” </p></blockquote>
<blockquote><p>模拟器调试：<br />
 “$(SRCROOT)/OpenCV/lib/iPhoneSimulator/include/opencv/”<br />
“$(SRCROOT)/OpenCV/lib/iPhoneSimulator/include/” </p></blockquote>
<p><a target="_blank" href="http://www.oncoding.cn/wp-content/uploads/2010/10/header-search-paths1.png"><img src="http://www.oncoding.cn/wp-content/uploads/2010/10/header-search-paths1-300x127.png" alt="" title="header-search-paths" width="300" height="127" class="aligncenter size-medium wp-image-852" /></a></p>
<p><strong>4. Building OpenCV</strong></p>
<p>有两种方式构建OpenCV，一种是转换到OpenCV target单独构建；一种是将OpenCV添加为主应用的依赖，构建主应用时一同构建。由于OpenCV的代码基本不需要修改，且构建进程很慢，所以建议对OpenCV进行单独构建。</p>
<p>在Groups &#038; Files窗口中的Targets栏中，双击OpenCV，点击Build and Run进行编译。过程比较慢，一般会报几个error和warning，不过基本可以无视。</p>
<p><a target="_blank" href="http://www.oncoding.cn/wp-content/uploads/2010/10/switch-target.png"><img src="http://www.oncoding.cn/wp-content/uploads/2010/10/switch-target-300x157.png" alt="" title="switch-target" width="300" height="157" class="aligncenter size-medium wp-image-843" /></a></p>
<p>进行了这些设置之后，主应用基本就可以正常编译运行了：</p>
<p><a target="_blank" href="http://www.oncoding.cn/wp-content/uploads/2010/10/build-successfully.png"><img src="http://www.oncoding.cn/wp-content/uploads/2010/10/build-successfully-166x300.png" alt="" title="build-successfully" width="166" height="300" class="aligncenter size-medium wp-image-844" /></a></p>
<h3>编程范例</h3>
<p>移植一个简单的OpenCV应用进Xcode中，对一张照片进行人脸识别，调用摄像头神马的，麻痹等买了授权能用真机调试再说吧。。</p>
<p>(To be continued..)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/opencv-ios-programming/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>“最被误解的语言”正焕发全新活力</title>
		<link>http://www.oncoding.cn/2010/javascript-new-journey/</link>
		<comments>http://www.oncoding.cn/2010/javascript-new-journey/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 15:10:00 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[扯淡]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=820</guid>
		<description><![CDATA[这些内容最早出自6月份的一次团队内分享，后来圆心推荐发表在了8月的《程序员》杂志上。遗憾的是编辑自行作了很多删改，原文发在这里。 Douglas Crockford曾称JavaScript是“世界上最被误解的语言”。确实，很长一段时间里，JavaScript都曾是泛滥的网页特效和弹窗广告的代名词。近些年来，随着Ajax应用的流行和前端框架的发展，JavaScript已经越来越严格和标准化。同时，在前端领域之外，JavaScript 也正被越来越广泛的使用。下面我们通过几个简单的JavaScript语句，一起来了解这些领域的应用。 这几句代码大体可以看出，它们的作用为：在本地的8080端口监听请求，返回浏览器响应──没错，这是基于JavaScript的服务器程序 node.js（ http://nodejs.org/）的一段控制语句。 node.js基于V8引擎（Chrome浏览器使用的JS解析器），它继承了 JavaScript的诸多特性，具备比Apache等传统服务端程序更好的性能和特性：I/O读写都经由V8引擎来处理，避免不良代码造成的死锁；更节省内存开支；处理并发请求效率更高；等等…… 这是一句简单的JavaScript专用数据格式——JSON语句，但确切的说，它一种基于JSON的数据库存储格式——BSON，是最近流行的NOSQL(非关系型数据库)的一种存储形式，非关系数据库多采用kay-value形式，具备比关系型数据库更强的扩展性和可操作性，并且在海量存储、高并发读写方面有绝佳的表现。 这句JavaScript语句的作用为：在以BSON存储的数据库中取得一条记录。它是著名的非关系数据库——MongoDB的一条查询语句。MongoDB基于C++开发，使用二进制格式存储BSON数据，可以对BSON中每个字段进行索引，具备极高的处理海量数据的能力。让人惊讶的是，它分别提供了基于十几种语言的查询语句和服务端、客户端，其中就包含对JavaScript的完美支持——MongoDB提供了基于Node.js的数据库服务器、基于SpiderMonkey的数据库客户端，以及JavaScript查询语句，并且提供了全功能的Web Shell。 JavaScript在这些领域的应用，已经不单单是停留在实验和玩票的性质，它们在国内外已经开始了大规模的使用。可以预见，在不久的将来，会出现这样的网站：它的前端使用JavaScript实现网页特效和交互，服务端运行的是基于JavaScript的Web服务器和数据库服务器，数据库使用JSON/BSON存储数据。 作为前端工作者，看到我们最熟悉的语言正在被这么多人、在这么多领域研究和使用，兴奋之余也倍感压力——越来越多的研究和关注，必然会促进这门语言更快的发展，同时也会变得更严格和严谨。这对前端工作者提出了更高的要求和挑战——与时俱进，不断超越！]]></description>
			<content:encoded><![CDATA[<blockquote><p>这些内容最早出自6月份的一次团队内分享，后来<a title="怿飞" href="http://www.planabc.net/" target="_blank">圆心</a>推荐发表在了8月的《程序员》杂志上。遗憾的是编辑自行作了很多删改，原文发在这里。</p></blockquote>
<p>Douglas Crockford曾称JavaScript是“世界上最被误解的语言”。确实，很长一段时间里，JavaScript都曾是泛滥的网页特效和弹窗广告的代名词。近些年来，随着Ajax应用的流行和前端框架的发展，JavaScript已经越来越严格和标准化。同时，在前端领域之外，JavaScript 也正被越来越广泛的使用。下面我们通过几个简单的JavaScript语句，一起来了解这些领域的应用。</p>
<pre class="brush: jscript; title: ; notranslate">
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(8080, &quot;127.0.0.1&quot;);
</pre>
<p>这几句代码大体可以看出，它们的作用为：在本地的8080端口监听请求，返回浏览器响应──没错，这是基于JavaScript的服务器程序 node.js（ http://nodejs.org/）的一段控制语句。<br />
node.js基于V8引擎（Chrome浏览器使用的JS解析器），它继承了 JavaScript的诸多特性，具备比Apache等传统服务端程序更好的性能和特性：I/O读写都经由V8引擎来处理，避免不良代码造成的死锁；更节省内存开支；处理并发请求效率更高；等等……</p>
<pre class="brush: jscript; title: ; notranslate">
{&quot;id&quot;: &quot;036378&quot;,  &quot;name&quot;: &quot;etai&quot;, &quot;job&quot;: &quot;F2E&quot; }
</pre>
<p>这是一句简单的JavaScript专用数据格式——JSON语句，但确切的说，它一种基于JSON的数据库存储格式——BSON，是最近流行的NOSQL(非关系型数据库)的一种存储形式，非关系数据库多采用kay-value形式，具备比关系型数据库更强的扩展性和可操作性，并且在海量存储、高并发读写方面有绝佳的表现。</p>
<pre class="brush: jscript; title: ; notranslate">
var t = db.things.findOne( { name : “etai” } );
</pre>
<p>这句JavaScript语句的作用为：在以BSON存储的数据库中取得一条记录。它是著名的非关系数据库——MongoDB的一条查询语句。MongoDB基于C++开发，使用二进制格式存储BSON数据，可以对BSON中每个字段进行索引，具备极高的处理海量数据的能力。让人惊讶的是，它分别提供了基于十几种语言的查询语句和服务端、客户端，其中就包含对JavaScript的完美支持——MongoDB提供了基于Node.js的数据库服务器、基于SpiderMonkey的数据库客户端，以及JavaScript查询语句，并且提供了全功能的Web Shell。</p>
<p>JavaScript在这些领域的应用，已经不单单是停留在实验和玩票的性质，它们在国内外已经开始了大规模的使用。可以预见，在不久的将来，会出现这样的网站：它的前端使用JavaScript实现网页特效和交互，服务端运行的是基于JavaScript的Web服务器和数据库服务器，数据库使用JSON/BSON存储数据。</p>
<p>作为前端工作者，看到我们最熟悉的语言正在被这么多人、在这么多领域研究和使用，兴奋之余也倍感压力——越来越多的研究和关注，必然会促进这门语言更快的发展，同时也会变得更严格和严谨。这对前端工作者提出了更高的要求和挑战——与时俱进，不断超越！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/javascript-new-journey/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>IE6的position:fixed</title>
		<link>http://www.oncoding.cn/2010/ie6-position-fixed/</link>
		<comments>http://www.oncoding.cn/2010/ie6-position-fixed/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 11:22:42 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[前端]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=813</guid>
		<description><![CDATA[手头一个项目中，要实现把一个浮层控制在浏览器窗口右下角，用”position:fixed”来控制最合适不过了。 但万恶的IE6不支持这个属性，之前采用过的方法有：将滚动条转移到body上，使用绝对定位控制浮层位置；使用JS实时判断滚动并设置浮层位置。 第一种方法局限性太大，页面中有其他绝对定位元素会受到影响；第二种方法需要在页面里加定时器，资源开销和时间成本都有点高。 后来在同事小卓的启发下，使用CSS表达式完成了IE6的兼容，代码如下： CSS表达式虽然方便，但浏览器资源损耗仍然很大，要根据具体应用场合决定，“一切皆权衡”，哈～]]></description>
			<content:encoded><![CDATA[<p>手头一个项目中，要实现把一个浮层控制在浏览器窗口右下角，用”position:fixed”来控制最合适不过了。</p>
<p>但万恶的IE6不支持这个属性，之前采用过的方法有：将滚动条转移到body上，使用绝对定位控制浮层位置；使用JS实时判断滚动并设置浮层位置。</p>
<p>第一种方法局限性太大，页面中有其他绝对定位元素会受到影响；第二种方法需要在页面里加定时器，资源开销和时间成本都有点高。</p>
<p>后来在同事小卓的启发下，使用CSS表达式完成了IE6的兼容，代码如下：</p>
<pre class="brush: css; title: ; notranslate">
_position:absolute;
_top:expression(document.documentElement.clientHeight - 213 + (e=document.documentElement.scrollTop) +'px');
/*
document.documentElement.clientHeight : 浏览器串口高度
200 : 浮层高度
(e=document.documentElement.scrollTop) : 滚动条高度
 */
</pre>
<p>CSS表达式虽然方便，但浏览器资源损耗仍然很大，要根据具体应用场合决定，“一切皆权衡”，哈～</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/ie6-position-fixed/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Google App Engine、Twitter API Proxy、Mixero搭建Twitter环境</title>
		<link>http://www.oncoding.cn/2010/twitter-mixero/</link>
		<comments>http://www.oncoding.cn/2010/twitter-mixero/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 06:37:03 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[扯淡]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[翻墙]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=796</guid>
		<description><![CDATA[以前用Twitter都是通过代理访问网页或者使用第三方网站，今天安装了一个桌面客户端──Mixero，使用Google App Engine架设了一个Twitter API代理，就可以在桌面上随时看推发推了。网上一些假设教程不大准确或已过期，这里记录一下自己的操作过程。这些操作都是在MacOS下进行的，在Windows和Linux下也都类似。 Mixero Mixero是一个优秀的Twitter客户端，基于Adobe Air，支持各种操作系统，并且有中文版本。 由于众所周知的原因，Mixero必须通过代理才能与Twitter连线，下面的繁琐的步骤都是拜GFW所赐，Let&#8217;s Fuck Them！ 架设Twitter API Proxy服务 Twitter API Proxy即Twitter API代理，通过代理使用Twitter API，可以实现Twitter的绝大部分功能。我们使用一个基于Google App Engine的开源项目birdnest来假设代理服务。 1. 申请和创建Google App Engine项目 用Gmail帐号登录Google App Engine，通过手机验证后，点击“Create an Applacation”，根据提示创建一个应用。 2. 下载Google App Engine SDK 通过SDK，我们可以方便的修改、测试和上传GAE项目。下载地址为：http://code.google.com/p/googleappengine/downloads/list，选择适合你操作系统的SDK并安装。启动后应该是这个样子： 3. 下载和修改birdnest birdnest的代码发布在Google code上，使用SVN检出代码，嫌麻烦的可以直接下载我打包的文件，解压到一个目录，可以跳到下一步了。 检出代码有两点需要注意： 1. 需要检出branches/gae目录下的代码 2. 目前最新的r102版本code.py有问题，需要检出r97版本 在终端下的操作代码为： 建立目录并检出代码： 4. 修改上传项目 打开birdnest目录，修改app.yaml文件，将第一行的nest改为你申请到的GAE项目ID。 打开刚才安装的GAE SDK，选择file-Add Existing Applacation，即导入存在的项目文件，选择刚才的birdnest目录。导入项目后，点击Deploy，填入Google帐号密码后，SDK就会将项目文件同步到GAE服务器。 5. 设置Mixero [...]]]></description>
			<content:encoded><![CDATA[<p>以前用Twitter都是通过代理访问网页或者使用第三方网站，今天安装了一个桌面客户端──Mixero，使用Google App Engine架设了一个Twitter API代理，就可以在桌面上随时看推发推了。网上一些假设教程不大准确或已过期，这里记录一下自己的操作过程。这些操作都是在MacOS下进行的，在Windows和Linux下也都类似。</p>
<h3>Mixero</h3>
<p><a href="http://www.mixero.com/" target="_blank">Mixero</a>是一个优秀的Twitter客户端，基于Adobe Air，支持各种操作系统，并且有中文版本。</p>
<p style="text-align: center;"><a title="新窗口查看原图" href="http://www.oncoding.cn/wp-content/uploads/2010/04/mixero-main.png" target="_blank"><img class="size-medium wp-image-798 aligncenter" title="mixero-main" src="http://www.oncoding.cn/wp-content/uploads/2010/04/mixero-main-300x215.png" alt="" width="300" height="215" /></a></p>
<p>由于众所周知的原因，Mixero必须通过代理才能与Twitter连线，下面的繁琐的步骤都是拜GFW所赐，Let&#8217;s Fuck Them！</p>
<p><span id="more-796"></span></p>
<h3>架设Twitter API Proxy服务</h3>
<p>Twitter API Proxy即Twitter API代理，通过代理使用Twitter API，可以实现Twitter的绝大部分功能。我们使用一个基于<a href="http://appengine.google.com/" target="_blank">Google App Engine</a>的开源项目<a href="http://code.google.com/p/birdnest/" target="_blank">birdnest</a>来假设代理服务。</p>
<p><strong>1. 申请和创建Google App Engine项目</strong></p>
<p>用Gmail帐号登录<a href="http://appengine.google.com/" target="_blank">Google App Engine</a>，通过手机验证后，点击“Create an Applacation”，根据提示创建一个应用。</p>
<p><strong>2. 下载Google App Engine SDK</strong></p>
<p>通过SDK，我们可以方便的修改、测试和上传GAE项目。下载地址为：<a href="http://code.google.com/p/googleappengine/downloads/list" target="_blank">http://code.google.com/p/googleappengine/downloads/list</a>，选择适合你操作系统的SDK并安装。启动后应该是这个样子：</p>
<p style="text-align: center;"><a title="新窗口查看原图" href="http://www.oncoding.cn/wp-content/uploads/2010/04/GAE-SDK.png"><img class="size-medium wp-image-800  aligncenter" title="GAE-SDK" src="http://www.oncoding.cn/wp-content/uploads/2010/04/GAE-SDK-299x219.png" alt="" width="299" height="219" /></a></p>
<p><strong>3. 下载和修改birdnest</strong></p>
<p><a href="http://code.google.com/p/birdnest/source/checkout" target="_blank">birdnest</a>的代码发布在Google code上，使用SVN检出代码，嫌麻烦的可以直接下载我<a href="http://www.oncoding.cn/wp-content/uploads/2010/04/birdnest.zip">打包的文件</a>，解压到一个目录，可以跳到下一步了。</p>
<p>检出代码有两点需要注意：</p>
<ul>
<li>1. 需要检出branches/gae目录下的代码</li>
<li>2. 目前最新的r102版本code.py有问题，需要检出r97版本</li>
</ul>
<p>在终端下的操作代码为：</p>
<p>建立目录并检出代码：</p>
<pre class="brush: bash; title: ; notranslate"># mkdir birdnest
# svn checkout http://birdnest.googlecode.com/svn/branches/gae birdnest/

# svn up -r 97 birdnest/code.py
</pre>
<p><strong>4. 修改上传项目</strong></p>
<p>打开birdnest目录，修改app.yaml文件，将第一行的nest改为你申请到的GAE项目ID。</p>
<p>打开刚才安装的GAE SDK，选择file-Add Existing Applacation，即导入存在的项目文件，选择刚才的birdnest目录。导入项目后，点击Deploy，填入Google帐号密码后，SDK就会将项目文件同步到GAE服务器。</p>
<p style="text-align: center;"><img class="size-full wp-image-802  aligncenter" title="GAE-DEPLOY" src="http://www.oncoding.cn/wp-content/uploads/2010/04/GAE-DEPLOY.png" alt="" width="329" height="342" /></p>
<p><strong>5. 设置Mixero</strong></p>
<p>现在需要做的工作就基本完成了，打开 http://你的ID.appspot.com/api/ 就应该看到了Twitter页面，如果不是，那就是有问题了。。</p>
<p>打开Mixero，填入帐号密码，点击右上角的齿轮，打开选项设置，在Twitter API一项中，填入上面的地址：</p>
<p style="text-align: center;"><a href="http://www.oncoding.cn/wp-content/uploads/2010/04/Mixero-Option.png"><img class="size-full wp-image-803  aligncenter" title="Mixero-Option" src="http://www.oncoding.cn/wp-content/uploads/2010/04/Mixero-Option.png" alt="" width="550" height="299" /></a></p>
<p>保存，刷新，就可以使用了。</p>
<p>最后，欢迎fo我：<a target="_blank" href="http://twitter.com/j5726">@j5726</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/twitter-mixero/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>我的淘宝花名</title>
		<link>http://www.oncoding.cn/2010/my-new-name/</link>
		<comments>http://www.oncoding.cn/2010/my-new-name/#comments</comments>
		<pubDate>Sun, 25 Apr 2010 07:44:07 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[扯淡]]></category>
		<category><![CDATA[淘宝]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=786</guid>
		<description><![CDATA[很早就听说过淘宝的花名传统，阿里的一些牛人也顶着花名扬名立万。今天，我也在释然师兄的帮助下选取了自己的花名，过程有些遗憾，结果更多的是兴奋和期待。 一直以来都没有一个固定的网名，QQ上叫虫子，很多朋友叫我啊花，自己还常用j5726等。 接到淘宝的offer后，就开始考虑花名的事情。最先想到的是鱼同，《书剑恩仇录》中的余鱼同，是一个很纠结的人物，潇洒但专情、任性却正义。同《卧虎藏龙》中的玉娇龙一样，是一个有血有肉，让人又恨又爱的形象。很幸运，这个名字没有被占用，但又很不幸，系统中存在同音字，所以拼音ID冲突，不能使用。。 接下来，又让师兄帮忙试了我熟悉的几个人物，都被占用了。群里的朋友也帮着我出谋划策，结果一个个闪亮的名号都被无情的扼杀。 最后的最后，从系统推荐的名字中选了这个 ── 当当当当，“额台”！ 速别额台，又称速不台，是成吉思汗时期蒙古的杰出军事家、战略家，曾攻陷莫斯科，占领匈牙利，戎马一生，直至老死在军营里。 八百年后的今天，在前端行业里也会出现这样一个“额台”，希望能像先人一样，矢志不渝，终生奋斗，在行业中留下自己的一笔。 以上自勉。]]></description>
			<content:encoded><![CDATA[<p>很早就听说过<a href="http://blog.1zsoft.com/node78392.html" target="_blank">淘宝的花名传统</a>，阿里的一些牛人也顶着花名扬名立万。今天，我也在释然师兄的帮助下选取了自己的花名，过程有些遗憾，结果更多的是兴奋和期待。</p>
<p>一直以来都没有一个固定的网名，QQ上叫<strong>虫子</strong>，很多朋友叫我<strong>啊花</strong>，自己还常用<strong>j5726</strong>等。</p>
<p>接到淘宝的offer后，就开始考虑花名的事情。最先想到的是<strong>鱼同</strong>，《书剑恩仇录》中的<a href="http://baike.baidu.com/view/28732.htm" target="_blank">余鱼同</a>，是一个很纠结的人物，潇洒但专情、任性却正义。同《卧虎藏龙》中的玉娇龙一样，是一个有血有肉，让人又恨又爱的形象。很幸运，这个名字没有被占用，但又很不幸，系统中存在同音字，所以拼音ID冲突，不能使用。。</p>
<p>接下来，又让师兄帮忙试了我熟悉的几个人物，都被占用了。群里的朋友也帮着我出谋划策，结果一个个闪亮的名号都被无情的扼杀。</p>
<p>最后的最后，从系统推荐的名字中选了这个 ── 当当当当，“<strong>额台</strong>”！</p>
<p><strong>速别额台</strong>，又称<a href="http://baike.baidu.com/view/67272.htm" target="_blank">速不台</a>，是成吉思汗时期蒙古的杰出军事家、战略家，曾攻陷莫斯科，占领匈牙利，戎马一生，直至老死在军营里。</p>
<p>八百年后的今天，在前端行业里也会出现这样一个“额台”，希望能像先人一样，矢志不渝，终生奋斗，在行业中留下自己的一笔。</p>
<p>以上自勉。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/my-new-name/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>豆瓣，可以成为值得我们尊敬的互联网公司吗？</title>
		<link>http://www.oncoding.cn/2010/douban-respect/</link>
		<comments>http://www.oncoding.cn/2010/douban-respect/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 04:59:37 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[扯淡]]></category>
		<category><![CDATA[web2.0]]></category>
		<category><![CDATA[豆瓣]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=780</guid>
		<description><![CDATA[按照某种不成文的惯例，在开始之前，我不得不要再次论述一下 什么是豆瓣。当然，如果你自信足够了解，可以跳过下面的一小段引用文字。 豆瓣网成立于2005年3月26日，是一个典型的Web 2.0 网站。它提供社交服务和在线的音乐、书籍和电影数据库。在2008年，它拥有将近 1,200,000 名用户，并被  Alexa Internet 列入中国百家最受欢迎的网站之一（排名第74名）。  豆瓣允许用户为电影、图书和音乐评级。它的用户评选出的最受欢迎的图书常常被中国的一些顶尖媒体引用。 ——引用自 kngine.com 一、写在前面 在众多的网络公司之中，大部分人都不得不提到其中一家最为著名、也是最为成功的公司—— Google 。没错，Google 作为最受欢迎的搜索引擎公司，它在其他领域的影响力也不可小视。当然，中国的互联网网站能够从它身上学到大量的东西。我个人认为， Google 成功的原因来自于以下三个方面：专注、开放、创新。 或许，各位会奇怪，这个被“腐女和 Gay 占领的网站”为什么更有可能变成一个让我们尊敬的公司，而不是那些家喻户晓的腾讯、新浪、搜狐等门户网站？下面，是我的理由。 二、理由 2.1 创新 或许，这个问题放在中国现在的互联网生态圈中是有些格格不入的。众所周知，国内的网站或多或少都“借鉴”（当然，也有抄袭，像××、×××、××××……）了国外网站的运营方式。然而，就豆瓣的创始人阿北所说，豆瓣网的整体创意是原创的，只是在界面、电子商务、SNS 三个方面借鉴了国外的网站。 说实话，我其实十分惊讶于阿北的坦诚。貌似现在已经很少有公司/网站愿意承认自己“借鉴”了其他的网站。 更难能可贵的是，从开始的创立豆瓣到后来的小组，乃至最近的豆瓣电台，豆瓣的创新的脚步似乎从来没有停止。 2.2 专注 或许，中国的互联网公司似乎都喜欢不断地向外延伸自己的服务范围。就像杀毒软件进军娱乐界，IM 服务供应商进军视频分享等等。我个人认为，大公司的扩张并不一定是盲目的，扩展服务范围的背后，一定代表着他已经有了成熟的运作模式或者很好的创意。但，如果一些小的公司也在不断扩张的话，结果就可能是被用户淘汰。毕竟，小公司的精力并不能和大公司相媲美，很多新兴的互联网公司似乎都有些缺乏必要的专注力——专注于用户体验和服务质量的提高上。 豆瓣服务的扩张则显得有些“缓慢”。因为，豆瓣的每一次扩张，都是建立在用户的意愿上。例如，豆瓣电影 的前身是一个名叫“我们都爱看电影”的小组。显然，这样的扩张看似缓慢，缺乏活力，但是，却能够充分保证用户能够得到始终如一的用户体验和服务质量。 2.3 开放 豆瓣的开放似乎来得有些晚（但也比那些有着将近10年历史，有着1亿用户的 IM 服务提供商死也不愿意第三方客户端登录它的服务好得多，不是吗？），但，豆瓣的开源的力度可能是最大的。 2007年，豆瓣正式开放 API 2009年，豆瓣正式以 New BSD 许可证开放了豆瓣的数据库—— BeansDB 豆瓣的这些动作，表现了作为一家互联网公司所具有的自信。（某 IM 公司会脸红吗） 我不知道互联网的未来是怎么样，但我知道，一项技术的开放，将推动该技术，甚至整个互联网，朝着更加完善、更加高效的方向发展。 三、结论 就像众多的互联网网站一样，豆瓣的成功也引来了诸多的模仿者，他们不断地仿照豆瓣的主页风格、排版布局，甚至，功能，但，这些网站就像众多的山寨网站一样，最终无法获得豆瓣用户的芳心。或许，豆瓣已经成为了许多人的一种生活方式，一种以更加轻松的方式和他人探讨自己感兴趣的话题的方式。 我想， [...]]]></description>
			<content:encoded><![CDATA[<p>按照某种不成文的惯例，在开始之前，我不得不要再次论述一下 什么是豆瓣。当然，如果你自信足够了解，可以跳过下面的一小段引用文字。</p>
<blockquote><p>豆瓣网成立于2005年3月26日，是一个典型的Web 2.0 网站。它提供社交服务和在线的音乐、书籍和电影数据库。在2008年，它拥有将近 1,200,000 名用户，并被  Alexa Internet 列入中国百家最受欢迎的网站之一（排名第74名）。  豆瓣允许用户为电影、图书和音乐评级。它的用户评选出的最受欢迎的图书常常被中国的一些顶尖媒体引用。</p>
<p>——<a title="单击以打开英文原版介绍" href="http://kngine.com/Search?q=Douban.com&amp;o=0" target="_blank">引用自 kngine.com</a></p></blockquote>
<h3>一、写在前面</h3>
<p>在众多的网络公司之中，大部分人都不得不提到其中一家最为著名、也是最为成功的公司—— Google 。没错，Google 作为最受欢迎的搜索引擎公司，它在其他领域的影响力也不可小视。当然，中国的互联网网站能够从它身上学到大量的东西。我个人认为， Google 成功的原因来自于以下三个方面：专注、开放、创新。</p>
<p><span id="more-780"></span></p>
<p>或许，各位会奇怪，这个被“腐女和 Gay 占领的网站”为什么更有可能变成一个让我们尊敬的公司，而不是那些家喻户晓的腾讯、新浪、搜狐等门户网站？下面，是我的理由。</p>
<h3>二、理由</h3>
<h4>2.1 创新</h4>
<p>或许，这个问题放在中国现在的互联网生态圈中是有些格格不入的。众所周知，国内的网站或多或少都“借鉴”（当然，也有抄袭，像××、×××、××××……）了国外网站的运营方式。然而，就豆瓣的创始人阿北所说，豆瓣网的整体创意是原创的，只是在界面、电子商务、SNS 三个方面借鉴了国外的网站。</p>
<p>说实话，我其实十分惊讶于阿北的坦诚。貌似现在已经很少有公司/网站愿意承认自己“借鉴”了其他的网站。</p>
<p>更难能可贵的是，从开始的创立豆瓣到后来的小组，乃至最近的豆瓣电台，豆瓣的创新的脚步似乎从来没有停止。</p>
<h4>2.2 专注</h4>
<p>或许，中国的互联网公司似乎都喜欢不断地向外延伸自己的服务范围。就像<a href="http://news.xinhuanet.com/it/2010-02/21/content_13018716.htm">杀毒软件进军娱乐界</a>，<a href="http://video.qq.com/">IM 服务供应商进军视频分享</a>等等。我个人认为，大公司的扩张并不一定是盲目的，扩展服务范围的背后，一定代表着他已经有了成熟的运作模式或者很好的创意。但，如果一些小的公司也在不断扩张的话，结果就可能是被用户淘汰。毕竟，小公司的精力并不能和大公司相媲美，很多新兴的互联网公司似乎都有些缺乏必要的专注力——专注于用户体验和服务质量的提高上。</p>
<p>豆瓣服务的扩张则显得有些“缓慢”。因为，豆瓣的每一次扩张，都是建立在用户的意愿上。例如，豆瓣电影 的前身是一个名叫“我们都爱看电影”的小组。显然，这样的扩张看似缓慢，缺乏活力，但是，却能够充分保证用户能够得到始终如一的用户体验和服务质量。</p>
<h4>2.3 开放</h4>
<p>豆瓣的开放似乎来得有些晚（但也比那些有着将近10年历史，有着1亿用户的 IM 服务提供商死也不愿意第三方客户端登录它的服务好得多，不是吗？），但，豆瓣的开源的力度可能是最大的。</p>
<blockquote><p><a href="http://www.douban.com/group/dbapi/">2007年，豆瓣正式开放 API </a></p>
<p><a href="http://www.douban.com/group/topic/9258122/">2009年，豆瓣正式以 New BSD 许可证开放了豆瓣的数据库—— BeansDB</a></p></blockquote>
<p>豆瓣的这些动作，表现了作为一家互联网公司所具有的自信。（某 IM 公司会脸红吗） 我不知道互联网的未来是怎么样，但我知道，一项技术的开放，将推动该技术，甚至整个互联网，朝着更加完善、更加高效的方向发展。</p>
<h3>三、结论</h3>
<p>就像众多的互联网网站一样，豆瓣的成功也引来了诸多的模仿者，他们不断地仿照豆瓣的主页风格、排版布局，甚至，功能，但，这些网站就像众多的山寨网站一样，最终无法获得豆瓣用户的芳心。或许，豆瓣已经成为了许多人的一种生活方式，一种以更加轻松的方式和他人探讨自己感兴趣的话题的方式。</p>
<p>我想， 豆瓣完全有可能成为一家和 Google 一样被国人尊敬的公司。或许，它并没有和 Google 那样提倡言论的自由和信息的自由流动，但，它的创新，它的开放，它的专注，能够帮助它在中国这片神奇的土地上继续发展下去。</p>
<p>总有一天，我期待，看到豆瓣成长成为一家真正的值得我们敬重的互联网公司。</p>
<p>我期待，这一天的到来。</p>
<p>你呢？</p>
<p>* 此文系本人自己的观点，如果当中有任何措辞，甚至常识上的错误，请不吝赐教，万分感谢。</p>
<h5>【参考的网站】</h5>
<p>1. 草根创业者杨勃：玩出来的”豆瓣”网  <a href="http://www.douban.com/group/topic/1058164/">www.douban.com/group/topic/1058164/</a></p>
<p><strong>原文链接：</strong><a href="http://www.techxav.cn/2010/04/18/can-douban-be-a-company-which-everyone-respects-for/">http://www.techxav.cn/2010/04/18/can-douban-be-a-company-which-everyone-respects-for/</a><br />
<strong>本文作者：</strong>@dunduncat</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/douban-respect/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>小白磨合 － 求职这些天的所思所得</title>
		<link>http://www.oncoding.cn/2010/hola-macbook/</link>
		<comments>http://www.oncoding.cn/2010/hola-macbook/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 14:57:06 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[扯淡]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=770</guid>
		<description><![CDATA[终于娶回了梦寐以求的小白，用上了传说中程序员必用的MacOS。 好久没写东西了，打点字，顺带磨合一下新机器。 出来找工作好多天了，交流中、面试中遇到的很多问题都是自己从未考虑过的，从中想到了不少，学到了不少。 关于视野与极限 2月底，在Tinyfool的文章中看到一句话： 我研究自己发展的过程中的瓶颈的时候，发现一切瓶颈都不来自能力，都来自视野，来自于给自己设置的愚蠢的极限。 当时的我，正处在心理、生理状态接近崩溃的边缘，被工作和生活压抑的喘不过气来，看到这句话，突然觉得豁然开朗。但当时的我，过多的把原因归咎于公司、领导，认为是我所处的环境遮挡了我的视野，是我做的工作限制了我发挥出的极限。 不久之后便提交了辞职报告。从辞职那晚和Chaosconst的促膝长谈，到今天在异乡的漫漫求职，我逐渐意识到，自己之前做的太少，学的太少。视野，并不应该被地域，甚至一个公司所限制；极限，更不应是别人设定给你的，是需要自己去挑战。 无畏多源于无知，狂妄总伴随孤陋。 不过，还是庆幸我选择了这一步。否则，可能永远看不到差距，看不到自己的无知。出来的这些天，没怎么写代码，但是在终日的思索中，发现的我的错误，我的不足，和我的优势，我的资本，都是比任何专业技能都宝贵的收获。 关于博客 写博客的目的是什么？我觉得最重要的是总结回顾，其次才是分享交流。回头看看自己之前的博客文章，好像大多是为写博而写博，开发中遇到的困难、心得体会却很少去总结。后来再遇到，或者被问起同样的问题，就无法快速的找回答案。 实践中发现的问题、得到的经验，才是最宝贵、最值得记录的。 工作以来的收获和提高 经常有人问，参加工作到现在，同大学时期相比，你最大的收获和提高在哪里。 我认为最重要的一点，就是责任心。大学里，可能我们被设置的目标就是 ── 考试不挂科，平时不违纪。没人去逼你，没有指标去催你。而工作之后，我们被委派一个或大或小的任务，这个任务可能直接影响到一个项目、一个产品、甚至一个公司战略的结果，这时候，就必须具备独当一面的魄力，勇于承担责任的勇气。从学生到合格工程师的转变，关键应该就在这里。 其次，是分析、解决问题的能力。工作之后遇到很多没见过，或者找不到参照的新需求、新功能，如何去分析问题、解决问题，最终形成可用的产品，这应该是有经验的工程师与新手之间的最大差别所在。 然后，是对互联网、对互联网项目开发的了解和理解。工作之后加入到互联网开发团队里，参与大型互联网项目的开发。中间学到的技能，开拓的视野，自然和单兵作战、作坊开发大为不同。 现在想想2008年的我，在大学校园里，不知道自己会什么，该做什么，出路在哪里。而现在，虽然还有些焦虑和无奈，但已是踌躇满志，期待做出一份新的事业和成绩。 父母 面试中多次被问起，跑这么远来求职，有没有考虑过父母的担心和挂念。 是的，虽然爸妈一直说支持我的决定，支持我做自己喜欢的事。但是，从他们一遍遍的叮咛嘱咐和嘘寒问暖中，我总能感觉到他们的不舍。当他们同事朋友的孩子都回到父母身边接班，过起安闲适意的生活，我却辞去工作，跑到千里之外去追逐自己的梦想。 总觉得自己还年轻，青春可以肆意挥霍。那天却突然意识到，父母已经走过了一大半的人生，他们为我付出了大半生的心血，本该到了收获和享受的时间，我却仍无法给他们任何承诺。 我始终觉得，我走的路是没有错的，早晚我会成功，早晚父母会幸福。也许只有拾起斗志，加快步伐，早日做出成绩，才能尽早给他们回报和安慰吧。 To be continued&#8230;]]></description>
			<content:encoded><![CDATA[<p>终于娶回了梦寐以求的小白，用上了传说中程序员必用的MacOS。</p>
<p>好久没写东西了，打点字，顺带磨合一下新机器。</p>
<p>出来找工作好多天了，交流中、面试中遇到的很多问题都是自己从未考虑过的，从中想到了不少，学到了不少。</p>
<h3>关于视野与极限</h3>
<p><span id="more-770"></span></p>
<p>2月底，在<a target="_blank" title="为什么我认为每个程序员都应该用Mac OS X？" href="http://tiny4.org/blog/2010/02/why-programmers-should-use-mac-os-x/">Tinyfool的文章</a>中看到一句话：</p>
<blockquote><p>我研究自己发展的过程中的瓶颈的时候，发现一切瓶颈都不来自能力，都来自视野，来自于给自己设置的愚蠢的极限。</p></blockquote>
<p>当时的我，正处在心理、生理状态接近崩溃的边缘，被工作和生活压抑的喘不过气来，看到这句话，突然觉得豁然开朗。但当时的我，过多的把原因归咎于公司、领导，认为是我所处的环境遮挡了我的视野，是我做的工作限制了我发挥出的极限。</p>
<p>不久之后便提交了辞职报告。从辞职那晚和Chaosconst的促膝长谈，到今天在异乡的漫漫求职，我逐渐意识到，自己之前做的太少，学的太少。视野，并不应该被地域，甚至一个公司所限制；极限，更不应是别人设定给你的，是需要自己去挑战。</p>
<p><strong>无畏多源于无知，狂妄总伴随孤陋。</strong></p>
<p>不过，还是庆幸我选择了这一步。否则，可能永远看不到差距，看不到自己的无知。出来的这些天，没怎么写代码，但是在终日的思索中，发现的我的错误，我的不足，和我的优势，我的资本，都是比任何专业技能都宝贵的收获。</p>
<h3>关于博客</h3>
<p>写博客的目的是什么？我觉得最重要的是总结回顾，其次才是分享交流。回头看看自己之前的博客文章，好像大多是为写博而写博，开发中遇到的困难、心得体会却很少去总结。后来再遇到，或者被问起同样的问题，就无法快速的找回答案。</p>
<p>实践中发现的问题、得到的经验，才是最宝贵、最值得记录的。</p>
<h3>工作以来的收获和提高</h3>
<p>经常有人问，参加工作到现在，同大学时期相比，你最大的收获和提高在哪里。</p>
<p>我认为最重要的一点，就是责任心。大学里，可能我们被设置的目标就是 ── 考试不挂科，平时不违纪。没人去逼你，没有指标去催你。而工作之后，我们被委派一个或大或小的任务，这个任务可能直接影响到一个项目、一个产品、甚至一个公司战略的结果，这时候，就必须具备独当一面的魄力，勇于承担责任的勇气。从学生到合格工程师的转变，关键应该就在这里。</p>
<p>其次，是分析、解决问题的能力。工作之后遇到很多没见过，或者找不到参照的新需求、新功能，如何去分析问题、解决问题，最终形成可用的产品，这应该是有经验的工程师与新手之间的最大差别所在。</p>
<p>然后，是对互联网、对互联网项目开发的了解和理解。工作之后加入到互联网开发团队里，参与大型互联网项目的开发。中间学到的技能，开拓的视野，自然和单兵作战、作坊开发大为不同。</p>
<p>现在想想2008年的我，在大学校园里，不知道自己会什么，该做什么，出路在哪里。而现在，虽然还有些焦虑和无奈，但已是踌躇满志，期待做出一份新的事业和成绩。</p>
<h3>父母</h3>
<p>面试中多次被问起，跑这么远来求职，有没有考虑过父母的担心和挂念。</p>
<p>是的，虽然爸妈一直说支持我的决定，支持我做自己喜欢的事。但是，从他们一遍遍的叮咛嘱咐和嘘寒问暖中，我总能感觉到他们的不舍。当他们同事朋友的孩子都回到父母身边接班，过起安闲适意的生活，我却辞去工作，跑到千里之外去追逐自己的梦想。</p>
<p>总觉得自己还年轻，青春可以肆意挥霍。那天却突然意识到，父母已经走过了一大半的人生，他们为我付出了大半生的心血，本该到了收获和享受的时间，我却仍无法给他们任何承诺。</p>
<p>我始终觉得，我走的路是没有错的，早晚我会成功，早晚父母会幸福。也许只有拾起斗志，加快步伐，早日做出成绩，才能尽早给他们回报和安慰吧。</p>
<p>To be continued&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/hola-macbook/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>可以在前端实现的几个地理位置小功能</title>
		<link>http://www.oncoding.cn/2010/geo-location-frontend/</link>
		<comments>http://www.oncoding.cn/2010/geo-location-frontend/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 16:09:55 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[地图]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=690</guid>
		<description><![CDATA[在Smashing Magazine上看到这篇Entering The Wonderful World of Geo Location，介绍了获取并处理用户地理位置的应用和方法，很有意思。结合原文的内容，加上之前的一些应用，整理了几个可以完全在前端实现的地理位置相关小功能。 1.通过IP获取用户位置 很多时候需要通过IP判断用户的位置，通常的办法是通过自己的后台程序查询数据库得到。如果用户位置只是应用在前端，或者有其他的特殊原因(比如，懒:)，也有一些其他办法来快速的获取用户位置。 maxmind.com提供了一个服务，通过引入一个js文件(http://j.maxmind.com/app/geoip.js)，可以把他判断到的用户的国家、城市、经纬度等信息加入到页面中来。下面是从青岛访问这个js文件返回的内容： 我们就可以利用这些信息做很多东西了：DEMO 另外，腾讯也有一个类似的接口，地址为 http://fw.qq.com/ipaddress，可以得到访问者的省、市信息，返回的格式如下： 具体的应用可以看这里： 断桥残雪WordPress天气插件 2.W3C共享位置接口 HTML5加入了的贡献地理位置的浏览器API接口，目前firefox3.5等浏览器已经支持这一功能。 用法： 看 DEMO 3. Google Gears 的 Geolocation API Google Gears是主要提供本地存储功能的浏览器扩展，新版本的Gears中，加入了判断用户地理位置的API，通过IP、WIFI热点等判断位置。不过Gears的使用似乎并不太广泛(Chrome内置了Gears，其他浏览器需要安装)，国内的地理位置信息也不够丰富，所以这个应用目前只可作为参考。 使用Gears的基本方法看这里，引入gears_init.js，使用Geolocation API的程序为： 更多内容参考这篇文章：使用Gears获取当前地理位置，以及DEMO。 4.逆经纬度解析 通过浏览器API等方式得到经纬度后，有时需要得到对应的城市名，这就是逆经纬度解析。 google maps api提供了一些经纬度解析方法，如果我们不想引入庞大的api，可以直接使用他的请求地址，通过jsonp方式得到google的经纬度解析数据。jsonp请求地址形式为： http://ditu.google.cn/maps/geo? output=json&#038;oe=utf-8&#038;q=纬度%2C经度 &#038;key=你申请到的key &#038;mapclient=jsapi&#038;hl=zh-CN&#038;callback=myfunction 参数q为经纬度，参数callback为回调函数名。 可以看下这个地址的返回结果，数据非常丰富，并且还是中文的： Yahoo提供的接口 雅虎提供了一些经纬度查询接口，可以使用YQL查询。 查询语句为： 用法： 使用YQL进行更多地理信息查询，可以看这个PPT：YQL Geo Library and Introduction to Geo Hacking [...]]]></description>
			<content:encoded><![CDATA[<p>在Smashing Magazine上看到这篇<a target="_blank" href="http://www.smashingmagazine.com/2010/03/08/entering-the-wonderful-world-of-geo-location/">Entering  The Wonderful World of Geo Location</a>，介绍了获取并处理用户地理位置的应用和方法，很有意思。结合原文的内容，加上之前的一些应用，整理了几个可以完全在前端实现的地理位置相关小功能。</p>
<h3>1.通过IP获取用户位置</h3>
<p>很多时候需要通过IP判断用户的位置，通常的办法是通过自己的后台程序查询数据库得到。如果用户位置只是应用在前端，或者有其他的特殊原因(比如，懒:)，也有一些其他办法来快速的获取用户位置。</p>
<p><a target="_blank" href="http://www.maxmind.com" >maxmind.com</a>提供了一个服务，通过引入一个js文件(<a target="_blank" href="http://j.maxmind.com/app/geoip.js">http://j.maxmind.com/app/geoip.js</a>)，可以把他判断到的用户的国家、城市、经纬度等信息加入到页面中来。下面是从青岛访问这个js文件返回的内容：<br />
<span id="more-690"></span></p>
<pre class="brush: jscript; title: ; notranslate">
function geoip_country_code() { return 'CN'; }
function geoip_country_name() { return 'China'; }
function geoip_city() { return 'Qingdao'; }
function geoip_region() { return '25'; }
function geoip_region_name() { return 'Shandong'; }
function geoip_latitude() { return '36.0986'; }
function geoip_longitude() { return '120.3719'; }
function geoip_postal_code() { return ''; }
</pre>
<p>我们就可以利用这些信息做很多东西了：<a href="http://isithackday.com/hacks/geo/js-location.html" target="_blank">DEMO</a></p>
<p>另外，腾讯也有一个类似的接口，地址为 http://fw.qq.com/ipaddress，可以得到访问者的省、市信息，返回的格式如下：</p>
<pre class="brush: jscript; title: ; notranslate">
var IPData = new Array(&quot;123.235.153.126&quot;,&quot;&quot;,&quot;山东省&quot;,&quot;青岛市&quot;);
</pre>
<p>具体的应用可以看这里：<a target="_blank" href="http://www.js8.in/wordpress-weather"> 断桥残雪WordPress天气插件</a></p>
<h3>2.W3C共享位置接口</h3>
<p>HTML5加入了的贡献地理位置的浏览器API接口，目前firefox3.5等浏览器已经支持这一功能。</p>
<p><a target="_blank" href="http://www.oncoding.cn/wp-content/uploads/2010/03/w3c-geo.jpg"><img src="http://www.oncoding.cn/wp-content/uploads/2010/03/w3c-geo-300x76.jpg" alt="" title="w3c-geo-api" width="300" height="76" class="aligncenter size-medium wp-image-693" /></a></p>
<p>用法：</p>
<pre class="brush: jscript; title: ; notranslate">
// if the browser supports the w3c geo api
if(navigator.geolocation){
  // get the current position
  navigator.geolocation.getCurrentPosition(

  // if this was successful, get the latitude and longitude
  function(position){
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;
  },
  // if there was an error
  function(error){
    alert('ouch');
  });
}
</pre>
<p>看 <a target="_blank" href="http://isithackday.com/hacks/geo/distance.php">DEMO</a> </p>
<h3>3. Google Gears 的 Geolocation API</h3>
<p><a target="_blank" href="http://gears.google.com/">Google Gears</a>是主要提供本地存储功能的浏览器扩展，新版本的Gears中，加入了判断用户地理位置的API，通过IP、WIFI热点等判断位置。不过Gears的使用似乎并不太广泛(Chrome内置了Gears，其他浏览器需要安装)，国内的地理位置信息也不够丰富，所以这个应用目前只可作为参考。</p>
<p>使用Gears的基本方法看<a target="_blank" href="http://code.google.com/intl/zh-CN/apis/gears/design.html">这里</a>，引入<a href="http://code.google.com/intl/zh-CN/apis/gears/gears_init.js" target="_blank">gears_init.js</a>，使用Geolocation API的程序为：</p>
<pre class="brush: jscript; title: ; notranslate">
var geo = factory.create('beta.geolocation'); //创建geolocation对象
var okCallback = function(d){
  alert('当前位置(纬度，经度): ' + d.latitude + ',' + d.longitude);
};
var errorCallback = function(err){
  alert(err.message);
};
geo.getCurrentPosition(okCallback , errorCallback);
</pre>
<p>更多内容参考这篇文章：<a href="http://www.qgy18.com/2009/09/%E4%BD%BF%E7%94%A8google-gears%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E5%9C%B0%E7%90%86%E4%BD%8D%E7%BD%AE/" target="_blank">使用Gears获取当前地理位置</a>，以及<a target="_blank" href="http://www.qgy18.com/lab/gears/">DEMO</a>。</p>
<h3>4.逆经纬度解析</h3>
<p>通过浏览器API等方式得到经纬度后，有时需要得到对应的城市名，这就是逆经纬度解析。</p>
<p>google maps api提供了一些经纬度解析方法，如果我们不想引入庞大的api，可以直接使用他的请求地址，通过<strong>jsonp方式得到google的经纬度解析数据</strong>。jsonp请求地址形式为：</p>
<blockquote><p>http://ditu.google.cn/maps/geo?<br />
output=json&#038;oe=utf-8&#038;q=纬度%2C经度<br />
&#038;key=<em>你申请到的key</em><br />
&#038;mapclient=jsapi&#038;hl=zh-CN&#038;callback=myfunction</p></blockquote>
<p>参数q为经纬度，参数callback为回调函数名。</p>
<p>可以看下<a target="_blank" href="http://ditu.google.cn/maps/geo?output=json&#038;oe=utf-8&#038;q=36.06023%2C120.3024&#038;key=ABQIAAAAira30FR5tVprWCJ-8_WcqxSrc1zAT9YCtP2kOyoD7kBAJfliJBROJEdu9hUE13rp9a4OHneyOoW5gg&#038;mapclient=jsapi&#038;hl=zh-CN&#038;callback=myfunction">这个地址</a>的返回结果，数据非常丰富，并且还是中文的：</p>
<pre class="brush: jscript; collapse: true; light: false; title: ; toolbar: true; notranslate">
myfunction &amp;&amp; myfunction( {
  &quot;name&quot;: &quot;36.06023, 120.3024&quot;,
  &quot;Status&quot;: {
    &quot;code&quot;: 200,
    &quot;request&quot;: &quot;geocode&quot;
  },
  &quot;Placemark&quot;: [ {
    &quot;id&quot;: &quot;p1&quot;,
    &quot;address&quot;: &quot;中国山东省青岛市市南区台西三路6号-10号&quot;,
    &quot;AddressDetails&quot;: {
   &quot;Accuracy&quot; : 8,
   &quot;Country&quot; : {
      &quot;AdministrativeArea&quot; : {
         &quot;AdministrativeAreaName&quot; : &quot;山东省&quot;,
         &quot;Locality&quot; : {
            &quot;DependentLocality&quot; : {
               &quot;DependentLocalityName&quot; : &quot;市南区&quot;,
               &quot;Thoroughfare&quot; : {
                  &quot;ThoroughfareName&quot; : &quot;台西三路6号-10号&quot;
               }
            },
            &quot;LocalityName&quot; : &quot;青岛市&quot;
         }
      },
      &quot;CountryName&quot; : &quot;中国&quot;,
      &quot;CountryNameCode&quot; : &quot;CN&quot;
   }
},
    &quot;ExtendedData&quot;: {
      &quot;LatLonBox&quot;: {
        &quot;north&quot;: 36.0633254,
        &quot;south&quot;: 36.0570301,
        &quot;east&quot;: 120.3054361,
        &quot;west&quot;: 120.2991409
      }
    },
    &quot;Point&quot;: {
      &quot;coordinates&quot;: [ 120.3024027, 36.0602271, 0 ]
    }
  }, {
    &quot;id&quot;: &quot;p2&quot;,
    &quot;address&quot;: &quot;中国山东省青岛市市南区台西三路8号阿双美容美发厅&quot;,
    &quot;AddressDetails&quot;: {
   &quot;Accuracy&quot; : 9,
   &quot;Country&quot; : {
      &quot;AdministrativeArea&quot; : {
         &quot;AdministrativeAreaName&quot; : &quot;山东省&quot;,
         &quot;Locality&quot; : {
            &quot;DependentLocality&quot; : {
               &quot;AddressLine&quot; : [ &quot;阿双美容美发厅&quot; ],
               &quot;DependentLocalityName&quot; : &quot;市南区&quot;,
               &quot;Thoroughfare&quot; : {
                  &quot;ThoroughfareName&quot; : &quot;台西三路8号&quot;
               }
            },
            &quot;LocalityName&quot; : &quot;青岛市&quot;
         }
      },
      &quot;CountryName&quot; : &quot;中国&quot;,
      &quot;CountryNameCode&quot; : &quot;CN&quot;
   }
},
    &quot;ExtendedData&quot;: {
      &quot;LatLonBox&quot;: {
        &quot;north&quot;: 36.0632366,
        &quot;south&quot;: 36.0569414,
        &quot;east&quot;: 120.3055696,
        &quot;west&quot;: 120.2992744
      }
    },
    &quot;Point&quot;: {
      &quot;coordinates&quot;: [ 120.3024220, 36.0600890, 0 ]
    }
  }, {
    &quot;id&quot;: &quot;p3&quot;,
    &quot;address&quot;: &quot;中国青岛市市南区台西四路站&quot;,
    &quot;AddressDetails&quot;: {
   &quot;Accuracy&quot; : 9,
   &quot;AddressLine&quot; : [ &quot;台西四路站&quot; ]
},
    &quot;ExtendedData&quot;: {
      &quot;LatLonBox&quot;: {
        &quot;north&quot;: 36.0630636,
        &quot;south&quot;: 36.0567684,
        &quot;east&quot;: 120.3063986,
        &quot;west&quot;: 120.3001034
      }
    },
    &quot;Point&quot;: {
      &quot;coordinates&quot;: [ 120.3032510, 36.0599160, 0 ]
    }
  }, {
    &quot;id&quot;: &quot;p4&quot;,
    &quot;address&quot;: &quot;中国青岛市市南区云南路(台西四路口)站&quot;,
    &quot;AddressDetails&quot;: {
   &quot;Accuracy&quot; : 9,
   &quot;AddressLine&quot; : [ &quot;云南路(台西四路口)站&quot; ]
},
    &quot;ExtendedData&quot;: {
      &quot;LatLonBox&quot;: {
        &quot;north&quot;: 36.0643586,
        &quot;south&quot;: 36.0580634,
        &quot;east&quot;: 120.3073456,
        &quot;west&quot;: 120.3010504
      }
    },
    &quot;Point&quot;: {
      &quot;coordinates&quot;: [ 120.3041980, 36.0612110, 0 ]
    }
  }, {
    &quot;id&quot;: &quot;p5&quot;,
    &quot;address&quot;: &quot;中国青岛市市南区贵州路站&quot;,
    &quot;AddressDetails&quot;: {
   &quot;Accuracy&quot; : 9,
   &quot;AddressLine&quot; : [ &quot;贵州路站&quot; ]
},
    &quot;ExtendedData&quot;: {
      &quot;LatLonBox&quot;: {
        &quot;north&quot;: 36.0614856,
        &quot;south&quot;: 36.0551904,
        &quot;east&quot;: 120.3036956,
        &quot;west&quot;: 120.2974004
      }
    },
    &quot;Point&quot;: {
      &quot;coordinates&quot;: [ 120.3005480, 36.0583380, 0 ]
    }
  }, {
    &quot;id&quot;: &quot;p6&quot;,
    &quot;address&quot;: &quot;中国青岛市市南区团岛站&quot;,
    &quot;AddressDetails&quot;: {
   &quot;Accuracy&quot; : 9,
   &quot;AddressLine&quot; : [ &quot;团岛站&quot; ]
},
    &quot;ExtendedData&quot;: {
      &quot;LatLonBox&quot;: {
        &quot;north&quot;: 36.0629146,
        &quot;south&quot;: 36.0566194,
        &quot;east&quot;: 120.3022496,
        &quot;west&quot;: 120.2959544
      }
    },
    &quot;Point&quot;: {
      &quot;coordinates&quot;: [ 120.2991020, 36.0597670, 0 ]
    }
  }, {
    &quot;id&quot;: &quot;p7&quot;,
    &quot;address&quot;: &quot;中国山东省青岛市市南区团岛四路海湾花园&quot;,
    &quot;AddressDetails&quot;: {
   &quot;Accuracy&quot; : 9,
   &quot;Country&quot; : {
      &quot;AdministrativeArea&quot; : {
         &quot;AdministrativeAreaName&quot; : &quot;山东省&quot;,
         &quot;Locality&quot; : {
            &quot;DependentLocality&quot; : {
               &quot;AddressLine&quot; : [ &quot;海湾花园&quot; ],
               &quot;DependentLocalityName&quot; : &quot;市南区&quot;,
               &quot;Thoroughfare&quot; : {
                  &quot;ThoroughfareName&quot; : &quot;团岛四路&quot;
               }
            },
            &quot;LocalityName&quot; : &quot;青岛市&quot;
         }
      },
      &quot;CountryName&quot; : &quot;中国&quot;,
      &quot;CountryNameCode&quot; : &quot;CN&quot;
   }
},
    &quot;ExtendedData&quot;: {
      &quot;LatLonBox&quot;: {
        &quot;north&quot;: 36.0642706,
        &quot;south&quot;: 36.0579754,
        &quot;east&quot;: 120.3006386,
        &quot;west&quot;: 120.2943434
      }
    },
    &quot;Point&quot;: {
      &quot;coordinates&quot;: [ 120.2974910, 36.0611230, 0 ]
    }
  }, {
    &quot;id&quot;: &quot;p8&quot;,
    &quot;address&quot;: &quot;中国山东省青岛市市南区&quot;,
    &quot;AddressDetails&quot;: {
   &quot;Accuracy&quot; : 4,
   &quot;Country&quot; : {
      &quot;AdministrativeArea&quot; : {
         &quot;AdministrativeAreaName&quot; : &quot;山东省&quot;,
         &quot;Locality&quot; : {
            &quot;DependentLocality&quot; : {
               &quot;DependentLocalityName&quot; : &quot;市南区&quot;
            },
            &quot;LocalityName&quot; : &quot;青岛市&quot;
         }
      },
      &quot;CountryName&quot; : &quot;中国&quot;,
      &quot;CountryNameCode&quot; : &quot;CN&quot;
   }
},
    &quot;ExtendedData&quot;: {
      &quot;LatLonBox&quot;: {
        &quot;north&quot;: 36.0954205,
        &quot;south&quot;: 36.0413849,
        &quot;east&quot;: 120.4266629,
        &quot;west&quot;: 120.2858189
      }
    },
    &quot;Point&quot;: {
      &quot;coordinates&quot;: [ 120.3877350, 36.0667110, 0 ]
    }
  }, {
    &quot;id&quot;: &quot;p9&quot;,
    &quot;address&quot;: &quot;中国山东省青岛市&quot;,
    &quot;AddressDetails&quot;: {
   &quot;Accuracy&quot; : 4,
   &quot;Country&quot; : {
      &quot;AdministrativeArea&quot; : {
         &quot;AdministrativeAreaName&quot; : &quot;山东省&quot;,
         &quot;Locality&quot; : {
            &quot;LocalityName&quot; : &quot;青岛市&quot;
         }
      },
      &quot;CountryName&quot; : &quot;中国&quot;,
      &quot;CountryNameCode&quot; : &quot;CN&quot;
   }
},
    &quot;ExtendedData&quot;: {
      &quot;LatLonBox&quot;: {
        &quot;north&quot;: 36.3313685,
        &quot;south&quot;: 35.9407727,
        &quot;east&quot;: 120.6326294,
        &quot;west&quot;: 120.0970459
      }
    },
    &quot;Point&quot;: {
      &quot;coordinates&quot;: [ 120.3827710, 36.0663480, 0 ]
    }
  }, {
    &quot;id&quot;: &quot;p10&quot;,
    &quot;address&quot;: &quot;中国山东省&quot;,
    &quot;AddressDetails&quot;: {
   &quot;Accuracy&quot; : 2,
   &quot;Country&quot; : {
      &quot;AdministrativeArea&quot; : {
         &quot;AdministrativeAreaName&quot; : &quot;山东省&quot;
      },
      &quot;CountryName&quot; : &quot;中国&quot;,
      &quot;CountryNameCode&quot; : &quot;CN&quot;
   }
},
    &quot;ExtendedData&quot;: {
      &quot;LatLonBox&quot;: {
        &quot;north&quot;: 38.4055838,
        &quot;south&quot;: 34.3851760,
        &quot;east&quot;: 122.7159599,
        &quot;west&quot;: 114.8033683
      }
    },
    &quot;Point&quot;: {
      &quot;coordinates&quot;: [ 117.0198960, 36.6692270, 0 ]
    }
  } ]
}
 )
</pre>
<p><strong>Yahoo提供的接口</strong></p>
<p>雅虎提供了一些经纬度查询接口，可以使用<a target="_blank" href="http://developer.yahoo.com/yql">YQL</a>查询。</p>
<p>查询语句为：</p>
<pre class="brush: sql; title: ; notranslate">select * from flickr.places where lat=36.06023 and lon=120.3024</pre>
<p>用法：</p>
<pre class="brush: jscript; title: ; notranslate">
&lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;
 function getPlaceFromFlickr(lat,lon,callback){
   // the YQL statement
   var yql = 'select * from flickr.places where lat='+lat+' and lon='+lon;

   // assembling the YQL webservice API
   var url = 'http://query.yahooapis.com/v1/public/yql?q='+
              encodeURIComponent(yql)+'&amp;format=json&amp;diagnostics='+
              'false&amp;callback='+callback;

   // create a new script node and add it to the document
   var s = document.createElement('script');
   s.setAttribute('src',url);
   document.getElementsByTagName('head')[0].appendChild(s);
 };

 // callback in case there is a place found
 function output(o){
   if(typeof(o.query.results.places.place) != 'undefined'){
     alert(o.query.results.places.place.name);
   }
 }

 // call the function with my current lat/lon
 getPlaceFromFlickr(36.6692270,117.0198960,'output');
&lt;/script&gt;
</pre>
<p>使用YQL进行更多地理信息查询，可以看这个PPT：<a target="_blank" href="http://www.wait-till-i.com/2010/03/11/yql-geo-library-and-introduction-to-geo-hacking-talk/">YQL Geo Library and Introduction to Geo Hacking talk</a></p>
<h3>5.经纬度解析</h3>
<p>经纬度解析就是通过地名取得经纬度数据，同样利用google那个请求地址，可以实现这一功能，请求地址格式为：</p>
<blockquote><p>http://ditu.google.cn/maps/geo?output=json&#038;oe=utf-8<br />
&#038;q=<em>地名的url encode编码</em><br />
&#038;key=<em>你申请到的key</em><br />
&#038;mapclient=jsapi&#038;hl=zh-CN&#038;callback=myfunction</p></blockquote>
<p>参数q为encodeURI(“中国山东省青岛市市北区”)，callback是jsonp回调函数名。</p>
<p><a target="_blank" href="http://ditu.google.cn/maps/geo?output=json&#038;oe=utf-8&#038;q=%E4%B8%AD%E5%9B%BD%E5%B1%B1%E4%B8%9C%E7%9C%81%E9%9D%92%E5%B2%9B%E5%B8%82%E5%B8%82%E5%8C%97%E5%8C%BA&#038;key=ABQIAAAAira30FR5tVprWCJ-8_WcqxSrc1zAT9YCtP2kOyoD7kBAJfliJBROJEdu9hUE13rp9a4OHneyOoW5gg&#038;mapclient=jsapi&#038;hl=zh-CN&#038;callback=myfunction">举个例子</a>，返回结果：</p>
<pre class="brush: jscript; collapse: true; light: false; title: ; toolbar: true; notranslate">
myfunction &amp;&amp; myfunction( {
  &quot;name&quot;: &quot;中国山东省青岛市市北区&quot;,
  &quot;Status&quot;: {
    &quot;code&quot;: 200,
    &quot;request&quot;: &quot;geocode&quot;
  },
  &quot;Placemark&quot;: [ {
    &quot;id&quot;: &quot;p1&quot;,
    &quot;address&quot;: &quot;中国山东省青岛市市北区&quot;,
    &quot;AddressDetails&quot;: {
   &quot;Accuracy&quot; : 4,
   &quot;Country&quot; : {
      &quot;AdministrativeArea&quot; : {
         &quot;AdministrativeAreaName&quot; : &quot;山东省&quot;,
         &quot;Locality&quot; : {
            &quot;DependentLocality&quot; : {
               &quot;DependentLocalityName&quot; : &quot;市北区&quot;
            },
            &quot;LocalityName&quot; : &quot;青岛市&quot;
         }
      },
      &quot;CountryName&quot; : &quot;中国&quot;,
      &quot;CountryNameCode&quot; : &quot;CN&quot;
   }
},
    &quot;ExtendedData&quot;: {
      &quot;LatLonBox&quot;: {
        &quot;north&quot;: 36.1237216,
        &quot;south&quot;: 36.0515859,
        &quot;east&quot;: 120.4388307,
        &quot;west&quot;: 120.3107713
      }
    },
    &quot;Point&quot;: {
      &quot;coordinates&quot;: [ 120.3748010, 36.0876620, 0 ]
    }
  } ]
}
 )
</pre>
<h3>6.google maps 图片接口</h3>
<p>有时候我们只想展示简单的地图，不需要交互和拖动，可以通过google maps提供的<a href="http://code.google.com/intl/zh-CN/apis/maps/documentation/staticmaps/" target="_blank">静态地图API</a>引入动态生成的地图图片，不过需要为你的域名申请一个key。</p>
<p>引入图片的url格式为：</p>
<pre class="brush: jscript; title: ; notranslate">

http://maps.google.com/maps/api/staticmap?

sensor=false
&amp;size=200x200
&amp;maptype=roadmap
&amp;key=&lt;em&gt;你申请到的KEY&lt;/em&gt;
&amp;markers=color:blue|label:1|37.4447,-122.161
&amp;markers=color:red|label:2|37.3385,-121.886
&amp;markers=color:green|label:3|37.3716,-122.038
&amp;markers=color:yellow|label:4|37.7792,-122.42
</pre>
<p>得到图片：</p>
<p><img src="http://maps.google.com/maps/api/staticmap?sensor=false&#038;size=400x250&#038;maptype=roadmap&#038;key=ABQIAAAANYuHabJr5Z8J0b86Q2gfvhR1W14e20gxBFMhpdYy_DdVp1kFtxTi-_5WaVDeQjdfRBmrQT3Diu153g&#038;markers=color:blue|label:1|37.4447,-122.161&#038;markers=color:red|label:2|37.3385,-121.886&#038;markers=color:green|label:3|37.3716,-122.038&#038;markers=color:yellow|label:4|37.7792,-122.42" alt="null" /></p>
<h3>后记</h3>
<p>关于地图的更多操作，可以参见以前的这篇文章：<a target="_blank" href="http://www.oncoding.cn/2009/google-maps-api/">Google Maps Api介绍与基础操作</a>。</p>
<p>随着互联网的发展，越来越多的功能可以在前端实现，出现了越来越多的强大的第三方服务，我们可以很方便的在我们的网站上加入一些实用的功能。这也许就是web2.0的魅力吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/geo-location-frontend/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>TED2010：下一代的地图技术在微软而非Google</title>
		<link>http://www.oncoding.cn/2010/bing-map-niubility/</link>
		<comments>http://www.oncoding.cn/2010/bing-map-niubility/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 14:16:25 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[地图]]></category>
		<category><![CDATA[微软]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=685</guid>
		<description><![CDATA[点击”View subtitles”可以显示中文字幕 TED2010上，来自微软的Blaise Aguera y Arcas展示了全新的结合虚拟现实体验的Bing地图技术，震撼了在场观众。如果你还在感慨Google街景，那么看看这个吧。看看他们怎么把流畅的街景技术和实时动态影像、天文景观结合在一起。让用户仿佛徜徉在异国他乡。街景也不再局限于街道，在一个小市场里，你可以看到你朋友拍得照片动态匹配到他曾经所看到的位置上。 看到他们的实时video，这种能够将影像和地图街景动态匹配的技术看起来非常炫，不知道多久会出现在Bing里面。 现在看来，整合了silverlight技术的Bing Map,将会对Google Maps最终形成非常大的挑战。]]></description>
			<content:encoded><![CDATA[<p><embed flashvars="vu=http://video.ted.com/talks/dynamic/BlaiseAguerayArcas_2010-medium.mp4&amp;su=http://images.ted.com/images/ted/tedindex/embed-posters/BlaiseAgueraYArcas-2010.embed_thumbnail.jpg&amp;vw=432&amp;vh=240&amp;ap=0&amp;ti=766&amp;introDuration=16500&amp;adDuration=4000&amp;postAdDuration=2000&amp;adKeys=talk=blaise_aguera;year=2010;theme=new_on_ted_com;theme=the_creative_spark;theme=a_taste_of_ted2010;event=TED2010;" allowfullscreen="true" bgcolor="#ffffff" wmode="transparent" pluginspace="http://www.macromedia.com/go/getflashplayer" src="http://video.ted.com/assets/player/swf/EmbedPlayer.swf" width="446" type="application/x-shockwave-flash" height="326"></embed></p>
<blockquote><p>点击”View subtitles”可以显示中文字幕</p></blockquote>
<p><span id="more-685"></span><br />
TED2010上，来自微软的Blaise Aguera y Arcas展示了全新的结合虚拟现实体验的Bing地图技术，震撼了在场观众。如果你还在感慨Google街景，那么看看这个吧。看看他们怎么把流畅的街景技术和实时动态影像、天文景观结合在一起。让用户仿佛徜徉在异国他乡。街景也不再局限于街道，在一个小市场里，你可以看到你朋友拍得照片动态匹配到他曾经所看到的位置上。</p>
<p>看到他们的实时video，这种能够将影像和地图街景动态匹配的技术看起来非常炫，不知道多久会出现在Bing里面。</p>
<p>现在看来，整合了silverlight技术的Bing Map,将会对Google Maps最终形成非常大的挑战。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/bing-map-niubility/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JavaScript单元测试工具 — QUnit</title>
		<link>http://www.oncoding.cn/2010/javascript-unit-testing-qunit/</link>
		<comments>http://www.oncoding.cn/2010/javascript-unit-testing-qunit/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 04:32:47 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[QUnit]]></category>
		<category><![CDATA[单元测试]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=629</guid>
		<description><![CDATA[QUnit是jQuery团队开发的JavaScript单元测试工具，使用方便，界面美观。近期试用了一下并进一步了解了JavaScript单元测试，记录一下所思所得。 什么是单元测试 单元测试又称为模块测试，是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。单元测试主要是用来检验程式的内部逻辑，也称为个体测试、结构测试或逻辑驱动测试。通常由撰写程式码的程式设计师负责进行。 通常来说，程式設計師每修改一次程式就會進行最少一次單元測試，在編寫程式的過程中前後很可能要進行多次單元測試，以證實程式達到軟件規格書(en:Specification)要求的工作目標，沒有臭蟲；雖然单元测试不是什么必须的，但也不坏，這牽涉到專案管理的政策決定。 —— 维基百科 (中文，英文) 为什么JavaScript需要单元测试 由于存在浏览器解析环境、用户操作习惯等差异，前端程序的许多问题是无法捕捉或重现的，现在前端程序的测试多是黑盒测试，即靠点击点击点击来寻找程序bug。这种方式既费时费力，又无法保证测试的覆盖面。 同时，前端逻辑和交互越来越复杂，和其他编程语言一样，一个函数，一个模块，在修改bug或添加新功能的过程中，很容易就产生新的bug，或使老的bug复活。这种情况下，反复进行黑盒测试，其工作量和测试质量是可想而知的。 此外，浏览器兼容性测试是前端程序测试的重要一环，在多个浏览器之间测试前端程序，上面说的工作量就会成n倍的增加。 为什么我们的前端程序如此脆弱？就是因为没用单元测试。。 假如使用了单元测试，上边的问题就变得很容易了，当然前提是你要花时间去研究和编写测试用例。 根据函数或模块的源代码，编写出包含各种情况的测试用例，每次解决bug或添加新功能，都随时更新这个用例然后进行测试，很容易就找出新bug和“复活”的老bug。 测试兼容性，只需要在不同的浏览器中分别运行这个测试，问题就一目了然了。 也许白盒比黑盒要多费几倍的脑子，但想想我们那脆弱的程序，想想那些随时冒出来的烦人的老bug，费点脑子，值了！ 使用QUnit 注：下面的内容主要参考了 QUnit文档 和 NetTuts+的这篇文章。 建立一个测试页面，引入 qunit.js 和 qunit.css 这两个必需的文件，这两个文件是存放在github上的，鉴于目前操蛋的互联网环境，最好下载到本地调用。 注：body中的元素id命名必须依照如下形式，否则无法正常显示。 测试示例 下面是一个最简单的函数测试用例，解释请见程序注释。 module( name, [lifecycle] ) 函数指定测试模块和周期。 ok( state, [message] ) 是QUnit中最常用的一个判断函数，只能判断true和false。 DEMO在这里，看一下测试结果： 结果都是绿的，说明两条测试语句都符合设定的规则。可以尝试修改下规则 就可以看到爆红了。。 更多测试判断 除了ok()之外，QUnit还有如下几个判断函数： 相等判断equals( actual, expected, [message] ) 示例： 相同判断(包含数组、对象等)same( actual, expected, [message] ) [...]]]></description>
			<content:encoded><![CDATA[<p>QUnit是jQuery团队开发的JavaScript单元测试工具，使用方便，界面美观。近期试用了一下并进一步了解了JavaScript单元测试，记录一下所思所得。</p>
<h3>什么是单元测试</h3>
<blockquote><p>单元测试又称为模块测试，是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。单元测试主要是用来检验程式的内部逻辑，也称为个体测试、结构测试或逻辑驱动测试。通常由撰写程式码的程式设计师负责进行。</p>
<p>通常来说，程式設計師每修改一次程式就會進行最少一次單元測試，在編寫程式的過程中前後很可能要進行多次單元測試，以證實程式達到軟件規格書(en:Specification)要求的工作目標，沒有臭蟲；雖然单元测试不是什么必须的，但也不坏，這牽涉到專案管理的政策決定。</p>
<p>—— 维基百科 (<a href="http://zh.wikipedia.org/wiki/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95" target="_blank">中文</a>，<a href="http://en.wikipedia.org/wiki/Unit_testing" target="_blank">英文</a>)</p></blockquote>
<h3>为什么JavaScript需要单元测试</h3>
<p><span id="more-629"></span><br />
由于存在浏览器解析环境、用户操作习惯等差异，前端程序的许多问题是无法捕捉或重现的，现在前端程序的测试多是<a href="http://zh.wikipedia.org/zh-cn/%E9%BB%91%E7%9B%92%E6%B5%8B%E8%AF%95" target="_blank">黑盒测试</a>，即靠点击点击点击来寻找程序bug。这种方式既费时费力，又无法保证测试的覆盖面。</p>
<p>同时，前端逻辑和交互越来越复杂，和其他编程语言一样，一个函数，一个模块，在修改bug或添加新功能的过程中，很容易就产生新的bug，或使老的bug复活。这种情况下，反复进行黑盒测试，其工作量和测试质量是可想而知的。</p>
<p>此外，浏览器兼容性测试是前端程序测试的重要一环，在多个浏览器之间测试前端程序，上面说的工作量就会成n倍的增加。</p>
<p><strong>为什么我们的前端程序如此脆弱？就是因为没用单元测试。。</strong></p>
<p>假如使用了单元测试，上边的问题就变得很容易了，当然前提是你要花时间去研究和编写测试用例。</p>
<p>根据函数或模块的源代码，编写出包含各种情况的测试用例，每次解决bug或添加新功能，都随时更新这个用例然后进行测试，很容易就找出新bug和“复活”的老bug。</p>
<p>测试兼容性，只需要在不同的浏览器中分别运行这个测试，问题就一目了然了。</p>
<p>也许白盒比黑盒要多费几倍的脑子，但想想我们那脆弱的程序，想想那些随时冒出来的烦人的老bug，费点脑子，值了！</p>
<h3>使用QUnit</h3>
<p>注：下面的内容主要参考了 <a href="http://docs.jquery.com/QUnit" target="_blank">QUnit文档</a> 和 <a href="http://net.tutsplus.com/tutorials/javascript-ajax/how-to-test-your-javascript-code-with-qunit" target="_blank">NetTuts+的这篇文章</a>。</p>
<p>建立一个测试页面，引入 <a href="http://github.com/jquery/qunit/raw/master/qunit/qunit.js" target="_blank">qunit.js</a> 和 <a href="http://github.com/jquery/qunit/raw/master/qunit/qunit.css" target="_blank">qunit.css</a> 这两个必需的文件，这两个文件是存放在github上的，鉴于目前操蛋的互联网环境，最好下载到本地调用。</p>
<p>注：body中的元素id命名必须依照如下形式，否则无法正常显示。</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;http://github.com/jquery/qunit/raw/master/qunit/qunit.css&quot; type=&quot;text/css&quot; media=&quot;screen&quot; /&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;http://github.com/jquery/qunit/raw/master/qunit/qunit.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1 id=&quot;qunit-header&quot;&gt;QUnit example&lt;/h1&gt;
  &lt;h2 id=&quot;qunit-banner&quot;&gt;&lt;/h2&gt;
  &lt;h2 id=&quot;qunit-userAgent&quot;&gt;&lt;/h2&gt;
  &lt;ol id=&quot;qunit-tests&quot;&gt;&lt;/ol&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<h3>测试示例</h3>
<p>下面是一个最简单的函数测试用例，解释请见程序注释。</p>
<pre class="brush: jscript; title: ; notranslate">
    //定义测试模块
    module( &quot;测试示例&quot; );
    //定义一个简单的函数，判断参数是不是数字
    function simpleTest(para) {
      if(typeof para == &quot;number&quot;) {
        return true;
      }
      else{
        return false;
      }
    }
    //开始单元测试
    test('simpleTest()', function() {
      //列举各种可能的情况，注意使用 ! 保证表达式符合应该的逻辑
      ok(simpleTest(2), '2是一个数字');
      ok(!simpleTest(&quot;2&quot;), '&quot;2&quot;不是一个数字');
    });
</pre>
<p><a href="http://docs.jquery.com/QUnit/module#namelifecycle" target="_blank">module( name, [lifecycle] ) </a>函数指定测试模块和周期。</p>
<p><a href="http://docs.jquery.com/QUnit/ok#statemessage" target="_blank">ok( state, [message] ) </a>是QUnit中最常用的一个判断函数，只能判断true和false。</p>
<p><a href="http://www.oncoding.cn/demos/qunit" target="_blank">DEMO在这里</a>，看一下测试结果：</p>
<p class="aligncenter">
<div class="wp-caption " style="width:336px"><img class="size-full wp-image-644" title="qunit" src="http://www.oncoding.cn/wp-content/uploads/2010/02/qunit.jpg" alt="" width="326" height="227" /></div>
</p>
<p>结果都是绿的，说明两条测试语句都符合设定的规则。可以尝试修改下规则</p>
<pre class="brush: jscript; title: ; notranslate">
//...
ok(simpleTest(&quot;2&quot;), '&quot;2&quot;是一个数字');
//...
</pre>
<p>就可以看到爆红了。。</p>
<h3>更多测试判断</h3>
<p>除了ok()之外，QUnit还有如下几个判断函数：</p>
<h4>相等判断<a href="http://docs.jquery.com/QUnit/equals#actualexpectedmessage" target="_blank">equals( actual, expected, [message] ) </a></h4>
<p>示例：</p>
<pre class="brush: jscript; title: ; notranslate">
  //定义一个简单的函数，返回数字和2的乘积
    function simpleTest1(para) {
      return para * 2;
    }
    //开始单元测试
    test('simpleTest1()', function() {
      //列举各种可能的情况
      equals(simpleTest1(2), 4, '2 * 2 等于 4');
      equals(simpleTest(2), 3, '2 * 2 等于 3');
    });
</pre>
<h4>相同判断(包含数组、对象等)<a href="http://docs.jquery.com/QUnit/same#actualexpectedmessage" target="_blank">same( actual, expected, [message] ) </a></h4>
<p>示例：</p>
<pre class="brush: jscript; title: ; notranslate">
  //定义一个简单的函数，返回一个数组
    function simpleTest2() {
      return [1, 2];
    }
    //开始单元测试
    test('simpleTest2()', function() {
      //列举各种可能的情况
      equals(simpleTest2(), [1, 2], '函数返回数组[1, 2]');
      equals(simpleTest2(), [1, 1], '函数返回数组[1, 1]');
    });
</pre>
<p>same()和意思和equals()差不多，但same()可以判断数组、对象等的相同，而equals不能。</p>
<h4>异步与Ajax</h4>
<p>对于异步程序的测试，如setTimeout、setInterval、Ajax等情况，按照上面的方法，在异步调用执行之前，测试就已完成并输出了结果。这时，配合使用QUnit提供的两个函数：<a href="http://docs.jquery.com/QUnit/stop#timeout" target="_blank">stop( [timeout] ) </a> 和 <a href="http://docs.jquery.com/QUnit/start" target="_blank">start()</a>，也可以轻松搞定。</p>
<p>直接看例子：</p>
<pre class="brush: jscript; title: ; notranslate">
    //异步测试
    module( &quot;异步测试示例&quot; );
    //setTimeout
    test('asynchronous test', function() {
      // 暂停测试
      stop();

      setTimeout(function() {
        ok(true, '完成运行');
        //待测试完成后，恢复
        start();
      }, 100)
    })
    //另一种形式
    asyncTest('asynchronous test', function() {
      setTimeout(function() {
        ok(true);
        //待测试完成后，恢复
        start();
      }, 100)
    })
</pre>
<p>Ajax也是类似的道理：</p>
<pre class="brush: jscript; title: ; notranslate">
    //Ajax测试
    function ajax(successCallback) {
      $.ajax({
        url: 'server.php',
        success: successCallback
      });
    }

    test('asynchronous test', function() {
      // 暂停测试
      stop();

      ajax(function() {
        // 异步调用判断
      })

      setTimeout(function() {
        //异步测试完成后，恢复
        start();
      }, 2000);
    })
</pre>
<h3>了解更多</h3>
<blockquote>
<ul>
<li><a href="http://docs.jquery.com/QUnit" target="_blank">QUnit文档</a></li>
<li><a href="http://net.tutsplus.com/tutorials/javascript-ajax/how-to-test-your-javascript-code-with-qunit" target="_blank">How to Test your JavaScript Code with QUnit</a></li>
<li><a href="http://www.swift-lizard.com/2009/11/24/test-driven-development-with-jquery-qunit/" target="_blank">Development with jQuery &amp; Qunit</a></li>
<li><a href="http://testswarm.com/" target="_blank">TestSwarm</a></li>
</ul>
</blockquote>
<p style="text-align: right;"><a href="http://www.oncoding.cn/2010/javascript-unit-testing-qunit/">幼学笔记</a>原创内容，根据<a href="http://creativecommons.org/licenses/by-nc-sa/2.5/">CC协议</a>发布，欢迎具名转载。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/javascript-unit-testing-qunit/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>中国工会网改版670万？国家队威武！</title>
		<link>http://www.oncoding.cn/2010/670wcnm/</link>
		<comments>http://www.oncoding.cn/2010/670wcnm/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 09:25:47 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[扯淡]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=617</guid>
		<description><![CDATA[一则消息 中华人民共和国财政部新发布了一条竞标公告：中国工会网扩建项目一期工程（网站改版、内容管理、站内检索、统计分析）成交结果公告TC099R72 ： 采购人名称：中国工会网络中心 采购项目名称：中国工会网扩建项目一期工程（网站改版、内容管理、站内检索、 统计分析） 招标编号：TC099R72 成交结果确定日期：2009年12月25日 成交金额：670万元 成交供应商名称：北京中软宏大信息技术有限公司 成交供应商地址：北京市海淀区学院南路55号中软大厦A座2层，10081 招标采购代理机构：中招国际招标有限公司 项目联系人：陆欣 电话：010-62108160 中招国际招标有限公司 2009年12月30日 那个数字一下子就揪住了我这IT民工的神经，网站改版、内容管理、站内检索、 统计分析。。这几个熟悉到白烂的字眼，第一次在我心中显得那么高大威猛。国家财务公开了，公开得我热泪盈眶。 我们来看看“中国工会网” 现在线上运行的中华全国总工会网站，备案号：京ICP备020034，使用jsp技术构建，技术服务支持：中科朗思、中软宏大。主要功能为新闻、公告发布，集成工作平台功能，集成邮件功能(使用Coremail邮件系统)。 网站功能确实比较简单，在firefox下还无法使用，这么烂的网站，确实需要改版，充分体现了党与时俱进的作风。改版招标情况进行全国公示，顺应民心，体现了我党公开公正的优秀品质。 但是，670万元的资金，要改成什么样子呢？公告里说的清楚：网站改版、内容管理、站内检索、 统计分析，这四个功能，不是任何一个CMS系统都具备的基本功能吗，这么点功能，一个兼职大学生，花一个月时间，给2000块钱就完全可以做出来嘛，这个”北京中软宏大信息技术有限公司“，莫非可以把这个小网站做出花来？ 关于”北京中软宏大信息技术有限公司“ 那我们就看看”北京中软宏大信息技术有限公司“的来头，有能力做670万的“大项目”的公司，其信息化建设自然应该非常牛B，就从他们的官方网站入手吧。 用firefox打开他们的网站，Oh My god！这是什么东西，乱成一团，完全不可用。哦，原来是IE Only的。。 一下子就可以看出这公司的水平了——初中生水平嘛。 是不是很不可思议？不过一看这公司名字的“中”字头，一切就都明白了—— 有什么想不开的，想想你是在中国，就都想开了。。]]></description>
			<content:encoded><![CDATA[<h3>一则消息</h3>
<p>中华人民共和国财政部新发布了一条竞标公告：<a href="http://www.mof.gov.cn/mof/xinxi/zhongyangbiaoxun/zhongbiaogonggao/200912/t20091230_254406.html" target="_blank">中国工会网扩建项目一期工程（网站改版、内容管理、站内检索、统计分析）成交结果公告TC099R72 </a>：<br />
<span id="more-617"></span></p>
<blockquote><p>采购人名称：中国工会网络中心<br />
采购项目名称：中国工会网扩建项目一期工程（网站改版、内容管理、站内检索、 统计分析）<br />
招标编号：TC099R72<br />
成交结果确定日期：2009年12月25日<br />
成交金额：670万元<br />
成交供应商名称：北京中软宏大信息技术有限公司<br />
成交供应商地址：北京市海淀区学院南路55号中软大厦A座2层，10081</p>
<p>招标采购代理机构：中招国际招标有限公司<br />
项目联系人：陆欣<br />
电话：010-62108160</p>
<p>中招国际招标有限公司<br />
2009年12月30日</p></blockquote>
<p>那个数字一下子就揪住了我这IT民工的神经，网站改版、内容管理、站内检索、 统计分析。。这几个熟悉到白烂的字眼，第一次在我心中显得那么高大威猛。国家财务公开了，公开得我热泪盈眶。</p>
<h3>我们来看看“中国工会网”</h3>
<p>现在线上运行的<a href="http://www.acftu.net/" target="_blank">中华全国总工会网站</a>，备案号：京ICP备020034，使用jsp技术构建，技术服务支持：中科朗思、中软宏大。主要功能为新闻、公告发布，集成工作平台功能，集成邮件功能(使用Coremail邮件系统)。</p>
<p>网站功能确实比较简单，在firefox下还无法使用，这么烂的网站，确实需要改版，充分体现了党与时俱进的作风。改版招标情况进行全国公示，顺应民心，体现了我党公开公正的优秀品质。</p>
<p>但是，670万元的资金，要改成什么样子呢？公告里说的清楚：网站改版、内容管理、站内检索、 统计分析，这四个功能，不是任何一个CMS系统都具备的基本功能吗，这么点功能，<strong>一个兼职大学生，花一个月时间，给2000块钱就完全可以做出来</strong>嘛，这个”北京中软宏大信息技术有限公司“，莫非可以把这个小网站做出花来？</p>
<h3>关于”北京中软宏大信息技术有限公司“</h3>
<p>那我们就看看”北京中软宏大信息技术有限公司“的来头，有能力做670万的“大项目”的公司，其信息化建设自然应该非常牛B，就从他们的<a href="http://www.csshd.com/" target="_blank">官方网站</a>入手吧。</p>
<p>用firefox打开他们的网站，Oh My god！这是什么东西，乱成一团，完全不可用。哦，原来是IE Only的。。</p>
<div id="attachment_458"><a href="http://www.oncoding.cn/wp-content/uploads/09img/2010/01/094402LZX.jpg"><img title="中标单位网站在chrome，FF下完全乱码！！" src="http://www.oncoding.cn/wp-content/uploads/09img/2010/01/094402LZX.jpg" alt="中标单位网站在chrome，FF下完全乱码！！" width="581" height="404" /></a></div>
<p>一下子就可以看出这公司的水平了——初中生水平嘛。</p>
<p>是不是很不可思议？不过一看这公司名字的“中”字头，一切就都明白了——</p>
<p><strong>有什么想不开的，想想你是在中国，就都想开了。。</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/670wcnm/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>jQuery1.4下载、性能及新特性详解</title>
		<link>http://www.oncoding.cn/2010/jquery-14-released/</link>
		<comments>http://www.oncoding.cn/2010/jquery-14-released/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 02:02:44 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=608</guid>
		<description><![CDATA[jQuery1.4正式版发布了，官方同步推出了The 14 Days of jQuery 网站，来介绍jQuery1.4的新特性和教程，其中有一篇文章详细介绍了jQuery1.4的新增功能，现转载其中文翻译如下： 原文：jQuery 1.4 Released 翻译：coolnalu jQuery 1.4 发布啦 为了庆祝jQuery的四周岁生日, jQuery的团队荣幸的发布了jQuery Javascript库的最新主要版本! 这个版本包含了大量的编程，测试，和记录文档的工作，我们为此感到很骄傲。 我要以个人的名义感谢 Brandon Aaron, Ben Alman, Louis-Rémi Babe, Ariel Flesler, Paul Irish, Robert Kati?, Yehuda Katz, Dave Methvin, Justin Meyer, Karl Swedberg, and Aaron Quint。谢谢他们在修复BUG和完成这次发布上所做的工作。 下载(Downloading) 按照惯例，我们提供了两份jQuery的拷贝，一份是最小化的(我们现在采用Google Closure作为默认的压缩工具了)，一份是未压缩的(供纠错或阅读)。 jQuery压缩 (23kb Gzipped) jQuery常规 (154kb) 另外，Google也在他们的服务器上放置了一份jQuery的拷贝。这份拷贝会自动的最小化然后压缩 – 并且放在Google最快的缓存服务器上。 http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js 你可以在你的站点上直接引用上面的URL，这样就可以享受迅速加载jQuery的性能优势了。 就jQuery1.4来说，我们努力的减少大规模升级中的麻烦 [...]]]></description>
			<content:encoded><![CDATA[<p>jQuery1.4正式版发布了，官方同步推出了<a target="_blank" href="http://jquery14.com/">The 14 Days of jQuery</a> 网站，来介绍jQuery1.4的新特性和教程，其中有一篇文章详细介绍了jQuery1.4的新增功能，现转载其中文翻译如下：</p>
<blockquote>
<p>原文：<a href="http://jquery14.com/day-01/jquery-14" target="_blank">jQuery 1.4 Released</a></p>
<p>翻译：<a href="http://www.uxd2.com/2010/01/%E7%BF%BB%E8%AF%91-jquery1-4%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3/" target="_blank">coolnalu</a></p>
</blockquote>
<h3>jQuery 1.4 发布啦</h3>
<p>为了庆祝jQuery的四周岁生日, jQuery的团队荣幸的发布了jQuery Javascript库的最新主要版本! 这个版本包含了大量的编程，测试，和记录文档的工作，我们为此感到很骄傲。</p>
<p>我要以个人的名义感谢 Brandon Aaron, Ben Alman, Louis-Rémi Babe, Ariel Flesler, Paul Irish, Robert Kati?, Yehuda Katz, Dave Methvin, Justin Meyer, Karl Swedberg, and Aaron Quint。谢谢他们在修复BUG和完成这次发布上所做的工作。</p>
<h4>下载(Downloading)</h4>
<p>按照惯例，我们提供了两份jQuery的拷贝，一份是最小化的(我们现在采用<a target="_blank"  href="http://code.google.com/closure/compiler/">Google Closure</a>作为默认的压缩工具了)，一份是未压缩的(供纠错或阅读)。<br />
<span id="more-608"></span></p>
<blockquote>
<p><a target="_blank"  href="http://code.jquery.com/jquery-1.4.min.js">jQuery压缩</a> (23kb <a target="_blank"  href="http://www.julienlecomte.net/blog/2007/08/13/">Gzipped</a>)</p>
<p><a target="_blank"  href="http://code.jquery.com/jquery-1.4.js">jQuery常规</a> (154kb)</p>
</blockquote>
<p>另外，Google也在他们的服务器上<a target="_blank"  href="http://code.google.com/apis/ajaxlibs/documentation/index.html">放置了一份jQuery的拷贝</a>。这份拷贝会自动的最小化然后压缩 – 并且放在Google最快的缓存服务器上。</p>
<blockquote>
<p><a target="_blank"  href="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js">http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js</a></p>
</blockquote>
<p>你可以在你的站点上直接引用上面的URL，这样就可以享受迅速加载jQuery的性能优势了。</p>
<p>就jQuery1.4来说，我们努力的减少大规模升级中的麻烦 – 通过保持所有public函数的签名。即使如此，还请通读<a target="_blank"  href="http://www.uxd2.com/2010/01/%E7%BF%BB%E8%AF%91-jquery1-4%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3/#backwards">可能会造成问题的变更列表</a>，这样能够了解哪些变更可能会给你的应用造成问题。</p>
<h3>功能(新特性)Features</h3>
<p>下面的内容概括了jQuery1.4里加入的变更和功能。另外所有的变更都已经在<a target="_blank"  href="http://api.jquery.com/category/version/1.4/">jQuery 1.4 的文档</a>里记录了。</p>
<h4>热门方法经过了性能上的大”检修”</h4>
<p>不少比较热门的和常用的jQuery方法在1.4里被重写了。(译注:重写了方法的内部，外部调用没有大幅度改变) 我们分析源码的时候发现我们能够获得大幅的性能提升，通过把jQuery和自己比较: 查看内部函数被调用了多少次，然后努力<a target="_blank"  href="http://ejohn.org/blog/function-call-profiling/">降低源码的复杂度</a>(译注:计算机算法中的Complexity)</p>
<p><a target="_blank"  rel="lightbox[69]" href="http://www.uxd2.com/wp-content/uploads/2010/01/01-funccall.jpg"><img title="常用jQuery方法调用频率" src="http://www.uxd2.com/wp-content/uploads/2010/01/01-funccall.jpg" alt="常用jQuery方法调用频率" width="500" height="375" /></a><br />
<small><a target="_blank"  title="# of Function Calls for Popular jQuery Methods by John Resig, on Flickr" href="http://www.flickr.com/photos/jeresig/4271691293/">View the cropped chart.</a></small></p>
<p>在1.4版里我们显著的降低了大部分热门jQuery方法的的复杂度。</p>
<h4>更易用的设置函数 (Easy Setter Functions)</h4>
<p>算来已经有一阵了，你们已经可以给<code><a target="_blank"  href="http://api.jquery.com/attr">.attr()</a></code>传递一个函数，然后这个函数的结果会被用来赋给相应的HTML属性(attribute)上。这个功能现在被移植到所有的设置函数了: <code><a target="_blank"  href="http://api.jquery.com/css">.css()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/attr">.attr()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/val">.val()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/html">.html()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/text">.text()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/append">.append()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/prepend">.prepend()</a></code>,  <code><a target="_blank"  href="http://api.jquery.com/before">.before()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/after">.after()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/replaceWith">.replaceWith()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/wrap">.wrap()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/wrapInner">.wrapInner()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/offset">.offset()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/addClass">.addClass()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/removeClass">.removeClass()</a></code>, 以及 <code><a target="_blank"  href="http://api.jquery.com/toggleClass">.toggleClass()</a></code>.</p>
<p>另外, 对于下面几个方法，当前的值会被作为第2个变量传递给这个函数。<code><a target="_blank"  href="http://api.jquery.com/css">.css()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/attr">.attr()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/val">.val()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/html">.html()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/text">.text()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/append">.append()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/prepend">.prepend()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/offset">.offset()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/addClass">.addClass()</a></code>, <code><a target="_blank"  href="http://api.jquery.com/removeClass">.removeClass()</a></code>, 以及 <code><a target="_blank"  href="http://api.jquery.com/toggleClass">.toggleClass()</a></code>.</p>
<p>这样代码就可以这样写:</p>
<pre class="brush: jscript; title: ; notranslate">
// 找出所有A标签里的'&amp;amp;'字符，然后用一个span标签包围
$('a').html(function(i,html){
  return html.replace(/&amp;amp;/gi,'&amp;amp;');
});

// 给一些链接的title属性加些信息
$('a[target]').attr(&quot;title&quot;, function(i,title){
  return title + &quot; (新窗口打开)&quot;;
});
</pre>
<h4>Ajax</h4>
<p><strong>嵌套参数的序列化</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.param/">jQuery.param() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/50d78e7658382d2a2f5149cae7a6572f78ce403f">Commit 1</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/67089eedf6f84acd9c16ea2a6dadadf7b13a7c84">Commit 2</a>)</p>
<p>jQuery 1.4在jQuery.param方法里加入了嵌入参数序列化的支持，借用了PHP编程里兴起的，而后又被Ruby on Rails推广开来的方式。<br />
举例来说，<br />
<code>{foo: ["bar", "baz"]}</code> 会被序列化为 “foo[]=bar&amp;foo[]=baz”.</p>
<p>在jQuery 1.3版里, <code>{foo: ["bar", "baz"]}</code> 曾被序列化为 “foo=bar&amp;foo=baz”. 但是，这样做没用办法将只含有一个元素的阵列编码。如果你需要旧的序列化方式，你可以设置传统Ajax设置来进行切换。(使用<code>jQuery.ajaxSettings.traditional</code>进行全局切换，或者根据情况单独切换。</p>
<p>总共有3种方式可以切换到旧的序列化方式:</p>
<pre class="brush: jscript; title: ; notranslate">// 全局改变序列化方式 (使用旧的)
jQuery.ajaxSettings.traditional = true;

// 指定情况使用旧的序列化方式
jQuery.param( stuff, true );

// 针对一个单独的Ajax请求使用旧的序列化方式
$.ajax({ data: stuff, traditional: true });</pre>
<p>更多信息参见: <a target="_blank"  href="http://api.jquery.com/jQuery.param/">jQuery.param() 文档</a>, <a target="_blank"  href="http://api.jquery.com/jQuery.ajax/">jQuery.ajax() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/39518945047413f1185682078043e70e0c5c9091">Commit</a>, <a target="_blank"  href="http://github.com/jquery/jquery/blob/master/src/ajax.js#L175">Code</a></p>
<p><strong>JSON和脚本类型通过”content-type”自动识别。</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.ajax/">jQuery.ajax 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/787f271052220c20787104f0eba6441aedac22ff">Commit 1</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/6861b5d4eb16222ed5ea623af6ce75362b55d1d4">Commit 2</a>)</p>
<p>如果一个Ajax请求的回复的媒体类型是JSON(application/json), dataType默认设为”json”(如果dataType没有被指明)。另外，如果回复的媒体类型是 Javascript(application/javascript), dataType默认设为”script”(同样，如果dataType没有明确指明), 这种情况下，脚本会自动运行。</p>
<p><strong>加入了Etag的支持</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.ajax/">jQuery.ajax() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/28ab4d32247943e1ae3409b23fe69303df0bc9eb">Commit</a>)</p>
<p>默认设置下, jQuery会忽略Ajax请求的”Last-Modified”页头。这样做是为了忽略浏览器的缓存。设置ifModified:true就可以使 jQuery使用可用的缓存。jQuery1.4还会发出”If-None-Match”的页头如果你设置了ifModified选项。</p>
<p><strong>严格JSON模式，本地的JSON.parse方法</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.ajax/">jQuery.ajax() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/90a87c03b4943d75c24bc5e6246630231d12d933">Commit 1</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/308d6cdad023da190ace2a698ee4815ed8dad9c5">Commit 2</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/44e6beb10304789044de2c5a58f5bb82e8321636">Commit 3</a>)</p>
<p>jQuery 1.3和以前的版本曾使用Javascript的<code>eval</code>对引入的JSON解析。1.4版则会使用本地的JSON解析器，前提是如果有本地的解析器可用。它也会对引入的JSON进行校验。所以在<a target="_blank"  href="http://api.jquery.com/jQuery.getJSON">jQuery.getJSON</a>方法里，或当一个Ajax请求的dataType是”json”的时候，jQuery会拒绝不合标准的JSON(例如<code>{foo: "bar"}</code>)。</p>
<p><strong>序列化HTML5的元素</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.param/">jQuery.param() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/b31b9bd756a1489c3b1b856ed8b624c55da9e02f">Commit</a>)</p>
<p>新的<a target="_blank"  href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#attr-input-type-keywords">HTML5输入方法</a> (比如’datetime’和’range’)在序列化<code><a target="_blank"  href="http://api.jquery.com/serialize">.serialize()</a></code>一个表单的时候会被包括在内。</p>
<p><strong>Ajax请求的环境</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.ajax/">jQuery.ajax() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/183f37e4b4128af7ba096ac40046768b84b6d66e">Commit</a>)</p>
<p>你可以附加一个”环境”到Ajax请求上，所有的回调函数里都会拥有同样的”环境”设置(这样可以简化你的代码，尽可能避免使用闭合,或是其他对象)。</p>
<pre class="brush: jscript; title: ; notranslate">jQuery.ajax({
    url: &quot;test.html&quot;,
    context: document.body,
    success: function(){
        jQuery(this).addClass(&quot;done&quot;);
    }
});</pre>
<p><strong>请求成功回调函数的第三个参数会被设为原始的XHR对象</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.ajax/">jQuery.ajax() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/c2101245c07afdb831b0c79869c7263420407b67">Commit</a>)</p>
<p>所有的Ajax请求的成功回调函数现在都会收到原始的XMLHttpRequest对象，作为第三个参数。之前这个XHR对象只能通过<code>$.ajax</code>一类方法的返回值来获取。</p>
<p><strong>明确设置”Content-Type”</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.ajax/">jQuery.ajax() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/25b0ba9f9612583033b902a0e40345463a3a71d0">Commit</a>)</p>
<p>在1.3版，如果没有实际数据发送，<a target="_blank"  href="http://api.jquery.com/jQuery.ajax/">jQuery.ajax</a>的contentType会被忽略。1.4版里，contentType将总是和请求一同发送。这修复了某些后台凭靠”Content-Type”页头判断回复类别所造成的问题。</p>
<p><strong>明确设置JSONP回调函数的名字</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.ajax/">jQuery.ajax 文档</a>,  <a target="_blank"  href="http://github.com/jquery/jquery/commit/fbc73d45b487dd863886c7fd3f0af1fd4dec261b">Commit</a>)</p>
<p>你可以使用<a target="_blank"  href="http://api.jquery.com/jQuery.ajax/">jQuery.ajax()</a>方法的jsonpCallback选项，通过名字来指定JSONP的回调函数。</p>
<p><strong>防止启动前跨域XHR</strong> (<a target="_blank"  href="http://github.com/jquery/jquery/commit/a7678267d848fcef8775c8b9f4fa3e507b8cc5f4">Commit</a>)</p>
<p>跨域Ajax(针对提供支持的浏览器)将更易用，因为默认设置下，启动前XHR被阻止了。(TODO)</p>
<p><strong>jQuery.ajax()现在使用”onreadystatechange”事件替换了计时器</strong> (<a target="_blank"  href="http://github.com/jquery/jquery/commit/fe6c86d53046b0f4d648f61c0b8e75387af65152">Commit</a>)</p>
<p>使用”onreadystatechange”替换了轮流探询，Ajax请求现在将使用更少的资源</p>
<h4>元素属性 (Attributes)</h4>
<p><strong><code>.css()</code>和<code>.attr()</code> 的性能被优化了。</strong></p>
<p>&lt;<a target="_blank"  rel="lightbox[69]" href="http://www.uxd2.com/wp-content/uploads/2010/01/02-perform-cssatrr.jpg"><img title=".css().attr()的性能提高" src="http://www.uxd2.com/wp-content/uploads/2010/01/02-perform-cssatrr.jpg" alt=".css().attr()的性能提高" width="500" height="375" /></a></p>
<p><strong><code>.attr()</code>方法多了一个设置函数作为参数</strong> (<a target="_blank"  href="http://api.jquery.com/attr/">.attr() 文档</a>)</p>
<p>你不但可以将一个函数用在<code>.attr()</code>里，还可以在这个函数里使用属性的当前值。</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery('&lt;img src=&quot;enter.png&quot; alt=&quot;enter your name&quot; /&gt;')
.attr(&quot;alt&quot;, function(index, value) {
    return &quot;Please, &quot; + value;
});
</pre>
<p><strong>.val( Function )</strong> (<a target="_blank"  href="http://api.jquery.com/val/">.val() 文档</a>)</p>
<pre class="brush: jscript; title: ; notranslate">
&lt;input class=&quot;food&quot; type='text' data-index=&quot;0&quot; /&gt;
&lt;input class=&quot;food&quot; type='text' data-index=&quot;1&quot; /&gt;

jQuery(&quot;input:text.food&quot;).hide();

jQuery(&quot;&lt;ul class='sortable'&gt;&lt;li&gt;Peanut Butter&lt;/li&gt;&lt;li&gt;Jelly&lt;/li&gt;&lt;/ul&gt;&quot;

)
  .sortable()
  .bind(&quot;endsort&quot;, function() {
    $(&quot;:text.food&quot;).val(function() {
      return $(&quot;ul.sortable li:eq(&quot; + $(this).attr(&quot;data-index&quot;)  + &quot;)&quot;).text();
    });
  });
</pre>
<p><strong>text和CDATAHTML元素也支持.text()方法了</strong> (<a target="_blank"  href="http://api.jquery.com/text/">.text() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/b30af34f28074b491929445f5aad3d62c63e772f">Commit</a>)</p>
<h4>核心 (Core)</h4>
<p><strong>快捷元素创建</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery/#jQuery2">jQuery() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/d40083c866738727aa7ffd7f13d2955bc9575d5e">Commit</a>)</p>
<p>现在当你需要使用jQuery函数创建一个元素的时候，你可以同时附递一个对象来指定属性值和事件:</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery(&quot;&quot;, {
    id: &quot;foo&quot;,
    css: { height: &quot;50px&quot;, width: &quot;50px&quot;, color: &quot;blue&quot;, backgroundColor: &quot;#ccc&quot; },
    click: function() {
            $(this).css(&quot;backgroundColor&quot;, &quot;red&quot;);
    }
}).appendTo(&quot;body&quot;);
</pre>
<p>对象里的键值的名字与相关的jQuery的方法的名字是对应的，对象的值会被作为参数传递给jQuery的方法。</p>
<p>(译注:譬如<code>$("&lt;a&gt;link&lt;/a&gt;", {css:{background:"#ccc"}});</code>相当于<code>$("&lt;a&gt;link&lt;/a&gt;")).css("background", "#ccc");</code></p>
<p><strong>.eq(-N), .get(-N) (负指数)</strong> (<a target="_blank"  href="http://api.jquery.com/eq/">.eq() 文档</a>, <a target="_blank"  href="http://api.jquery.com/get/">.get() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/e532dfe5228217f55a33122a4438fd70522dbb4b">Commit</a>)</p>
<p>你现在可以在<code>.get()</code>和<code>.eq()</code>方法里使用负数。譬如，你要选择倒数第2个div元素，或者是倒数第2个DOM对象:</p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;div&quot;).eq(-2);
$(&quot;div&quot;).get(-2);
</pre>
<p><strong>新的.first()和.last()方法</strong> (<a target="_blank"  href="http://api.jquery.com/first/">.first() 文档</a>, <a target="_blank"  href="http://api.jquery.com/last/">.last() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/9de120e6d7cfffa3d990a6ccf23db3cd74e2bdc0">Commit</a>)</p>
<p>方便起见, 新增的<code>.first()</code>和<code>.last()</code>方法等同于<a target="_blank"  href="http://api.jquery.com/eq/">.eq(0)</a>和<a target="_blank"  href="http://api.jquery.com/eq/">.eq(-1)</a>.</p>
<p><strong>新的.toArray()方法</strong> (<a target="_blank"  href="http://api.jquery.com/toArray/">.toArray() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/e124fec5e9cfee77cb23b27c0d43dc2631c83aab">Commit</a>)</p>
<p><a target="_blank"  href="http://api.jquery.com/get">.get()</a>方法自始就是从jQuery集合里返回一个阵列。为了能够更明确, 你可以用<a target="_blank"  href="http://api.jquery.com/toArray/">.toArray()</a>来达到一样的效果。(译注:这里应该是为了以后的版本留出空间，譬如以后可能会加入.toList()方法，到时候就会易于区分。) 不过，和<code>.get()</code>不一样的是，<code>.toArray()</code>不接受参数。</p>
<p><strong>jQuery()返回一个空集</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery/">jQuery() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/04524287d3e0112deae570ff9247c734833431bb">Commit</a>)</p>
<p>在jQuery 1.3中,<a target="_blank"  href="http://api.jquery.com/jQuery/">jQuery()</a>方法返回仅包括<code>document</code>的jQuery集合。这个可以用来创建一个空集，然后动态加入一些元素。注: <code>jQuery().ready()</code>方式在1.4中依然有效，但是被指示陈旧了。请使用<code>jQuery(document).ready()</code>或者<code>jQuery(function(){})</code>。</p>
<p><strong>jQuery(“TAG”)</strong> (<a target="_blank"  href="http://api.jquery.com/element-selector/">Element Selector 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/4ea4fad0902839c06c281b5de7b0aca29922b63d">Commit</a>)</p>
<p>当使用单个标签名字的时候jQuery会使用更快捷的路径。</p>
<p><strong>jQuery(“&lt;div&gt;”), jQuery(“&lt;div/&gt;”) 和 jQuery(“&lt;div&gt;&lt;/div&gt;”)</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery/#jQuery2">jQuery() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/c4c820efff4fa7bcce0d5bf0a448625278ea6379">Commit</a>)</p>
<p>现在这三个方法都使用同一个代码路径了(document.createElement), 来优化<code>jQuery("&lt;div&gt;&lt;/div&gt;")</code>的性能。注意，如果你指定了属性，将会使用浏览器本身的语法分析(通过设置innerHTML)。</p>
<h4>样式 (CSS)</h4>
<p><strong>.css()方法在性能是以前的2倍。</strong></p>
<p><a target="_blank"  rel="lightbox[69]" href="http://www.uxd2.com/wp-content/uploads/2010/01/03-perform-css.jpg"><img title=".css()的性能提高 " src="http://www.uxd2.com/wp-content/uploads/2010/01/03-perform-css.jpg" alt=".css()的性能提高 " width="500" height="375" /></a></p>
<p><strong><code>.addClass()</code>, <code>.removeClass()</code>, 和 <code>.hasClass()</code>这几个方法在性能上是以前的3倍</strong></p>
<p><a target="_blank"  rel="lightbox[69]" href="http://www.uxd2.com/wp-content/uploads/2010/01/04-perform-addClass.jpg"><img title="addClass, removeClass, 和 hasClass的性能提高" src="http://www.uxd2.com/wp-content/uploads/2010/01/04-perform-addClass.jpg" alt="addClass, removeClass, 和 hasClass的性能提高" width="500" height="375" /></a></p>
<p><strong>.toggleClass()可以切换多个css类了</strong> (<a target="_blank"  href="http://api.jquery.com/toggleClass/">.toggleClass() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/5e6e53835e552920db4f88ac0c9eca71aaacbef0">Commit</a>)</p>
<p>你可以通过<a target="_blank"  href="http://api.jquery.com/toggleClass/">.toggleClass()</a>调用多个css类的名字来切换他们。</p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;div&quot;).toggleClass(&quot;current active&quot;);
</pre>
<h4>数据</h4>
<p><strong>.data()返回对象, .data(Object)设置对象</strong> (<a target="_blank"  href="http://api.jquery.com/data/">.data() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/d36d224cc52e70d837306d33a03f517ef72abc60">Commit 1</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/f6a0bf6816f4e2e67382b1b13fdd3ff2ea4b22f8">Commit 2</a>)</p>
<p>有时候你可能需要在一个元素上附加一个复杂的对象。一个常见的例子是你需要从一个元素身上复制所有的数据到令一个元素上。在jQuery 1.4里, 不使用任何参数调用<a target="_blank"  href="http://api.jquery.com/data/">.data()</a>时，.data会返回一个复杂对象。(译注: 包含所有键-值对的对象。) 调用<a target="_blank"  href="http://api.jquery.com/data/">.data(Object)</a> 则会设置这个对象。注意这个对象还包括了元素上绑定的事件，所以用的时候要小心。</p>
<p><strong>除非需要, 不然不会创建数据缓存。</strong> (<a target="_blank"  href="http://github.com/jquery/jquery/commit/c4f144eeffd94c745839b0ced2de9c62cfa9f075">Commit 1</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/97e134fe80a734b97170bf43c9459511f4e165c7">Commit 2</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/67d445a703491c90a7d3c46be34bcdceb4d1c896">Commit 3</a>)</p>
<p>jQuery使用一个独特的自定义属性来获取特定元素上附加的数据。当查找数据，但是没有新加的数据的时候，jQuery会尽量避免创建这个自定义属性。这样可能会提高性能，同时还会在这种情况下避免污染DOM。</p>
<h4>效果 (Effects)</h4>
<p><strong>单个属性缓进缓出</strong> (<a target="_blank"  href="http://api.jquery.com/animate/#per-property-easing">Per-property Easing 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/93fdbeb963a9c350f807818c7cc99982942a92f3">Commit</a>)</p>
<p>除了能够给一个动态效果指定缓进出函数外，你现在可以指定每个属性的缓进出函数了。James Padolsey的<a target="_blank"  href="http://james.padolsey.com/javascript/easing-in-jquery-1-4a2/">blog上</a>有更进一步的信息和演示。</p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;#clickme&quot;).click(function() {
  $(&quot;div&quot;).animate({
    width: [&quot;+=200px&quot;, &quot;swing&quot;],
    height: [&quot;+=50px&quot;, &quot;linear&quot;],
  }, 2000, function() {
      $(this).after(&quot;&amp;lt;div&amp;gt;Animation complete.&amp;lt;/div&amp;gt;&quot;);
  });
});
</pre>
<h4>事件 (Events)</h4>
<p><strong>新方法: jQuery.proxy()</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.proxy/">jQuery.proxy() Documenation</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/66975de2d249643779e2b3daad0457f7f5f92508">Commit 1</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/1d2b1a57dae0b73b3d99197f73f4edb623b5574a">Commit 2</a>)</p>
<p>如果你需要保证一个函数内的”this”恒定地保持某个值, 你可以用<code>jQuery.proxy</code>获得一个相同作用域的函数。</p>
<pre class="brush: jscript; title: ; notranslate">
var obj = {
  name: &quot;John&quot;,
  test: function() {
    alert( this.name );
    $(&quot;#test&quot;).unbind(&quot;click&quot;, obj.test);
  }
};

$(&quot;#test&quot;).click( jQuery.proxy( obj, &quot;test&quot; ) );
</pre>
<p><strong>多个事件绑定</strong> (<a target="_blank"  href="http://api.jquery.com/bind">.bind() 文档</a>)</p>
<p>你可以通过递入一个对象来一次性绑定元素的多个事件。</p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;div.test&quot;).bind({
  click: function(){
    $(this).addClass(&quot;active&quot;);
  },
  mouseenter: function(){
    $(this).addClass(&quot;inside&quot;);
  },
  mouseleave: function(){
    $(this).removeClass(&quot;inside&quot;);
  }
});
</pre>
<p><strong>‘change’和’submit’事件规范化</strong> (<a target="_blank"  href="http://api.jquery.com/change">Change 文档</a>, <a target="_blank"  href="http://api.jquery.com/submit">Submit 文档</a>)</p>
<p>普通的或是即时的<code>change</code>和<code>submit</code>事件可以在各种浏览器上稳定工作了。我们覆盖了IE里的<code>change</code>和<code>submit</code>, 替换为与其他浏览器相同的事件。</p>
<p><strong>新的事件: ‘focusin’ and ‘focusout’</strong> (<a target="_blank"  href="http://api.jquery.com/focusin/">.focusin() 文档</a>, <a target="_blank"  href="http://api.jquery.com/focusout/">.focusout() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/03481a52c72e417b01cfeb499f26738cf5ed5839">Commit</a>)</p>
<p><code>focusin</code>和<code>focusout</code>在一般情况下等同于<code>focus</code>和<code>blur</code>, 但是多了向父元素传递的作用。如果你自己编写你的事件代理模式(TODO), 这个功能将对你有很大帮助。请注意对<code>focus</code>和<code>blur</code>使用<code>live()</code>方法将不会起作用; 在设计的时候我们根据 <a target="_blank"  href="http://www.w3.org/TR/DOM-Level-2-Events/events.html">DOM事件规范</a>决定不使其向父元素传递事件。</p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;form&quot;).focusout(function(event) {
    var tgt = event.target;
    if (tgt.nodeName == &quot;INPUT&quot; &amp;amp;&amp;amp; !tgt.value) {
        $(tgt).after(&quot;nothing here&quot;);
    }
});
</pre>
<p><strong>所有的事件都可以成为即时事件</strong> (<a target="_blank"  href="http://api.jquery.com/live">.live() 文档</a>)</p>
<p>除了<a target="_blank"  href="http://api.jquery.com/ready">ready</a>, <a target="_blank"  href="http://api.jquery.com/focus">focus</a> (用focusin), 和 <a target="_blank"  href="http://api.jquery.com/blur">blur</a> (用focusout)以外, 所有能用<code>.bind()</code>绑定的事件都可以成为即时事件。</p>
<p>在<code>live()</code>所支持的事件里，我们对能够支持下面这几个额外的事件感到尤其骄傲。通过<code>.live()</code>里的事件代理, 1.4版实现了对<code>change</code>, <code>submit</code>, <code>focusin</code>, <code>focusout</code>, <code>mouseenter</code>, 以及<code>mouseleave</code>事件的跨浏览器支持。</p>
<p>注: 如果你需要即时的<code>focus</code>事件，你应该用<code>focusin</code>和<code>focusout</code>, 而不要用<code>focus</code>和<code>blur</code>, 因为就像前面提到的, <code>focus</code>和<code>blur</code>不向上传递。</p>
<p>还有, <code>live()</code>也接受数据对象作为参数了, 同<code>bind()</code>方法一样 (<a target="_blank"  href="http://github.com/jquery/jquery/commit/71efbdd3b26f3a283f8d4bfdcc7b6343142027b9">Commit</a>)</p>
<p><strong>live/die也支持环境变量了</strong> (<a target="_blank"  href="http://github.com/jquery/jquery/commit/30e760b63fd6d82f30833cd2864f245dd9594cd9">Commit</a>)</p>
<p>现在可以在绑定事件的时候给选择符指定一个环境。如果环境被指定了, 只有属于这个环境下的元素才会被绑定事件。在创建即时事件的时候, 元素本身不需要已经被定义, 但是环境必须被创建。</p>
<p><strong>确定ready事件至少含有<code>body</code>元素</strong> (<a target="_blank"  href="http://github.com/jquery/jquery/commit/262fcf7b7b919da1564509f621cf7480a5d5572b">Commit</a>)</p>
<p>jQuery现在会检查<code>body</code>是不是存在，如果不存在，会对<code>body</code>进行轮流探询。</p>
<p><strong>在不需要手动处理内存溢出的非IE浏览器中, 卸载的速度提高了。</strong> (<a target="_blank"  href="http://github.com/jquery/jquery/commit/f3474c00cd6d9e5fd61b6ef1562003e9986ad67d">Commit</a>)</p>
<h4>DOM操作 (Manipulation)</h4>
<p>在jQuery 1.4里一系列的DOM操作方法的性能都有巨大的提升。</p>
<p><strong><a target="_blank"  href="http://api.jquery.com/append">.append()</a>, <a target="_blank"  href="http://api.jquery.com/prepend">.prepend()</a>, <a target="_blank"  href="http://api.jquery.com/before">.before()</a>, and <a target="_blank"  href="http://api.jquery.com/after">.after()</a>的性能提高了。</strong></p>
<p><a target="_blank"  rel="lightbox[69]" href="http://www.uxd2.com/wp-content/uploads/2010/01/05-perform-dom.jpg"><img title="DOM嵌入的性能提高" src="http://www.uxd2.com/wp-content/uploads/2010/01/05-perform-dom.jpg" alt="DOM嵌入的性能提高" width="500" height="375" /></a></p>
<p><strong><a target="_blank"  href="http://api.jquery.com/html">.html()</a>的性能提高到以前的3倍。</strong></p>
<p><a target="_blank"  rel="lightbox[69]" href="http://www.uxd2.com/wp-content/uploads/2010/01/06-perform-html.jpg"><img title=".html()的性能提高" src="http://www.uxd2.com/wp-content/uploads/2010/01/06-perform-html.jpg" alt=".html()的性能提高" width="500" height="375" /></a></p>
<p><strong>.remove()和.empty()的速度则达到以前的4倍.</strong></p>
<p><a target="_blank"  rel="lightbox[69]" href="http://www.uxd2.com/wp-content/uploads/2010/01/07-perform-remove.jpg"><img title=".remove() 和 .empty()的性能提高" src="http://www.uxd2.com/wp-content/uploads/2010/01/07-perform-remove.jpg" alt=".remove() 和 .empty()的性能提高" width="500" height="375" /></a></p>
<p><strong>新方法: .detach()</strong> (<a target="_blank"  href="http://api.jquery.com/detach/">.detach() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/7a67f8897d3c2ed97254f0fdb969be14e77962d1">Commit</a>)</p>
<p><code>detach()</code>将一个元素从DOM里移除, 但是并不卸载关联的事件处理函数。这个方法可用于暂时性的将一个元素移除，执行相关操作，然后返回。</p>
<pre class="brush: jscript; title: ; notranslate">
var foo = $(&quot;#foo&quot;).click(function() {
    // 相关操作
});
foo.detach();
// foo保留了相关处理函数
foo.appendTo(&quot;body&quot;);
</pre>
<p><strong>新的unwrap()方法</strong> (<a target="_blank"  href="http://api.jquery.com/unwrap/">documentation</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/69e6e53555f21f07b534f1169298f7b33011bb4b">commit</a>)</p>
<p><code>unwrap()</code>方法拿到一个已知的父元素的子元素，然后将父元素用子元素替换。(译注: 将子元素从”包裹”里拿出来, 因名unwrap)。如此这般:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;body&gt;
    &lt;div&gt;
        &lt;p&gt;annie&lt;/p&gt; &lt;p&gt;davey&lt;/p&gt; &lt;p&gt;stevie&lt;/p&gt;
    &lt;/div&gt;
&lt;/body&gt;

$('div').unwrap();

&lt;body&gt;
   &lt;p&gt;annie&lt;/p&gt; &lt;p&gt;davey&lt;/p&gt; &lt;p&gt;stevie&lt;/p&gt;
&lt;/body&gt;
</pre>
<p><strong>domManip方法里的缓存</strong> (<a target="_blank"  href="http://github.com/jquery/jquery/commit/8db967e9d52407c8e76d81b9d472800667f6fa29">commit</a>)</p>
<p>jQuery会将<code>jQuery("&lt;div&gt;")</code>和<code>.after("&lt;div&gt;")</code>一类方法创建的节点记入缓存。这样, 对于利用这些方法, 使用字符串进行DOM操作的页面，性能将有极大的提高。</p>
<p><strong>无连接的节点间的before, after, replaceWith操作</strong> (<a target="_blank"  href="http://github.com/jquery/jquery/commit/173c1477ae6efc4c2eeb7131ba0646c4e1323975">commit</a>)</p>
<p>现在你可以对还没有放置到DOM Tree上的节点进行<code>before</code>, <code>after</code>, 和<code>replaceWith</code>的操作了。意味着你可以先对节点进行复杂的操作, 待完成后再放到合适的DOM位置上。这样也能尽量避免操作过程中造成重新排版。</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery(&quot;&lt;div&gt;&quot;).before(&quot;&lt;p&gt;Hello&lt;/p&gt;&quot;).appendTo(&quot;body&quot;)
</pre>
<p><strong><code>.clone(true)</code> 也会复制关联数据</strong> (<a target="_blank"  href="http://api.jquery.com/clone/">clone 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/4b70f006f579fba24a882d80ca67f1971dbb4922">commit</a>)</p>
<p>1.3版中, <code>.clone(true)</code>虽然也是深度复制, 但是没有复制关联的数据。1.4版里，它则会复制数据, 同时还包括所有的事件。这点上和<code>jQuery.extend</code>在语义想同的, 所以普通对象和阵列会被复制, 但是自定义的对象则不会。</p>
<h4>位移 (Offset)</h4>
<p><strong>.offset( coords | Function )</strong> (<a target="_blank"  href="http://api.jquery.com/offset/">.offset() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/daffb954e397bd5d9f8e9aaedab6c0baa9609e1e">commit</a>)</p>
<p>现在可以设置元素的位移了! 和所有的设置函数一样, <code>offset</code>也可以接受一个函数作为第二个参数。</p>
<h4>队列 (Queueing)</h4>
<p>队列经历了一次大修, 使用队列会比使用默认的<code>fx</code>更易掌握。</p>
<p><strong>新的 .delay() 方法</strong> (<a target="_blank"  href="http://api.jquery.com/delay/">.delay() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/bbd933cbfe6d31a749cb336d7a84155ccfab247f">commit</a>)</p>
<p><code>.delay()</code>方法会根据参数滞后若干毫秒执行队列里剩下的对象。默认的它会使用”fx”队列。但你可以选择性的通过<code>delay</code>方法的第二个参数选择其他队列。(译注:每个队列都以一个名字识别。)</p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;div&quot;).fadeIn().delay(4000).fadeOut();
</pre>
<p><strong>队列里的<code>next</code></strong> (<a target="_blank"  href="http://api.jquery.com/queue/">.queue() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/89b4bc53ca0ca3d4e5c80b94ce92b09cc34af8ef">commit</a>)</p>
<p>jQuery 1.4版里, 当队列里的一个函数被调用的时候，第一个参数会被设为另一个函数。当后者被调用的时候, 会自动排除队列里的下一个对象, 以此来推动队列到下一步。</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery(&quot;div&quot;).queue(&quot;ajax&quot;, function(next) {
  var self = this;
  jQuery.getJSON(&quot;/update&quot;, function(json) {
    $(self).html(json.text);
    next();
  };
}).queue(&quot;ajax&quot;, function() {
  $(this).fadeIn();
});</pre>
<p><strong>.clearQueue()</strong> (<a target="_blank"  href="http://api.jquery.com/clearQueue/">clearQueue 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/d857315967a1cc07b73924bbdf2eb12f4f910c45">commit</a>)</p>
<p>队列可以被清空了。这个方法会移除队列里所有未执行的函数, 但不会移除正在运行的函数。无参数的情况下调用<code>.clearQueue()</code>方法将会清空默认的”fx”队列。</p>
<h4>选择符 (Selectors)</h4>
<p><strong>“#id p”效率更高</strong> (<a target="_blank"  href="http://github.com/jeresig/sizzle/commit/c5c18ae5f17f11b39b7f261633e4bfc5ef3e99d7">commit</a>)</p>
<p>所有以ID开头的选择符都得到了优化, 能够在瞬间得到返回值。所有以ID为开头的选择符速度将一直快于其他选择符。</p>
<h4>页面遍访 (Traversing)</h4>
<p><strong>.index(), .index(String)</strong> (<a target="_blank"  href="http://api.jquery.com/index/">index 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/ffd457d4561eb1a6653aaef90f92a3b3010b9139">commit</a>)</p>
<p><code>.index()</code> 方法经过重写, 变得更加直观和灵活。</p>
<p>你可以获得一个元素相对于同父元素的指数:</p>
<pre class="brush: jscript; title: ; notranslate">
// 计算第一个 &amp;lt;li&amp;gt; 元素在它所有的同父元素中的指数:
$(&quot;li.current&quot;).index()
</pre>
<p>你也可以获得一个元素在一个jQuery元素集合中的指数, 这个集合可以用一个选择符或者是一个DOM元素来指定:</p>
<pre class="brush: jscript; title: ; notranslate">// 计算这个 &amp;lt;h3 id=&quot;more-info&quot;&amp;gt; 元素在页面上所有 &amp;lt;h3&amp;gt; 元素里的指数:
$(&quot;#more-info&quot;).index(&quot;h3&quot;)
</pre>
<p><strong>新的.has()方法</strong> (<a target="_blank"  href="http://api.jquery.com/has/">has 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/4e27f17007c2329e31b449e61bb31197b90a37f1">commit</a>)</p>
<p>这个方法相当于选择符里的<code>:has()</code>过滤法。它拿到一个jQuery集合,返回含有指定选择符的元素。</p>
<p><strong>新的 .nextUntil(), .prevUntil(), .parentsUntil() 方法</strong> (<a target="_blank"  href="http://api.jquery.com/nextUntil/">.nextUntil() 文档</a>, <a target="_blank"  href="http://api.jquery.com/prevUntil/">.prevUntil() 文档</a>, <a target="_blank"  href="http://api.jquery.com/parentsUntil/">.parentsUntil() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/2b481b93cfca62f95aa7005e7db651456fa08e65">commit</a>)</p>
<p>新的”until”方法类似于<code>.nextAll()</code>, <code>.prevAll()</code>, 和<code>.parents()</code>。区别是可以用一个选择符来停止元素探索。</p>
<p><strong>.add(String, Element)</strong> (<a target="_blank"  href="http://jquery14.com/day-01/%3C/p%3E%3Cp%3Ehttp://api.jquery.com/add/%3C/p%3E%3Cp%3E">.add() 文档</a>, <a target="_blank"  href="http://jquery14.com/day-01/%3C/p%3E%3Cp%3Ehttp://github.com/jquery/jquery/commit/b0fe380cf89564305646bbd55d1fd7bd210fd591%3C/p%3E%3Cp%3E">commit</a>)</p>
<p>可以给<code>.add()</code>方法指定环境了。这个功能可以用于在一个调用链中加入和操作额外元素(比如Ajax请求里返回的新元素)。</p>
<p><strong>.closest(filter, DOMElement)</strong> (<a target="_blank"  href="http://api.jquery.com/closest/">.closest() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/d6991fa273515a8503692324499edcc71b5c3f64">commit</a>)</p>
<p>可以通过<code>closest</code>方法的第2个参数设置一个<code>DOMElement</code>环境。给<code>closest</code>设置一个环境一般能够提高这个方法的运行速度。这个优化也适用<code>live()</code>, 因为这个方法内部调用了<code>closest()</code>。</p>
<h4>常用工具 (Utilities)</h4>
<p><strong>jQuery.isEmptyObject()</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.isEmptyObject/">jQuery.isEmptyObject() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/a38a5cd531a328319f8b7f3f33a84044b54591ce">commit</a>)</p>
<p>如果对象,em&gt;没有任何属性, 该方法将返回<code>true</code>。<code>jQuery.isEmptyObject()</code>方法不对参数进行任何检查, 所以请保证参数是一个对象。</p>
<p><strong>jQuery.isPlainObject()</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.isPlainObject/">jQuery.isPlainObject()</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/4b55e94d0849568a2fd121952f13a9d6571c731f">commit</a> )</p>
<p>如果一个对象是通过字符创建的(译注:{}),<code>jQuery.isPlainObject()</code>返回<code>true</code>; 如果对象是其他类别的对象(译注:如new Object())或者是基本类型, 则返回<code>false</code>。</p>
<p><strong>jQuery.contains()</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.contains/">jQuery.contains() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/4e27f17007c2329e31b449e61bb31197b90a37f1">commit</a>)</p>
<p>如果两个参数都是DOM节点，并且第二个节点是嵌套在第一个节点内部的话, <code>jQuery.contains()</code>返回<code>true</code>。反之返回<code>false</code>。</p>
<p><strong>jQuery.noop</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.noop/">jQuery.noop() 文档</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/6cb2945837ccca55204191a8e7a70b2b2486c28e">commit</a>)</p>
<p>是个空的函数, 可以用在必须要有一个函数的情况下。(译注: noop是No Operation的意思。)</p>
<p><strong>jQuery.unique()</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.unique/">jQuery.unique() 文档</a>)</p>
<p>jQuery 1.4版中, <code>jQuery.unique()</code>方法返回结果里的元素是按照他们在页面里的顺序排序的。由于在创建jQuery集合的时候jQuery使用<code>jQuery.unique()</code>方法, 所以jQuery方法返回的集合也是按照他们在页面里的顺序排列的。</p>
<h4>其他 (Miscellaneous)</h4>
<p><strong>jQuery.browser以浏览器引擎为中心</strong> (<a target="_blank"  href="http://api.jquery.com/jQuery.browser/">jQuery.browser 文档</a>, <a target="_blank"  href="http://jquery14.com/day-01/%3Cbr%20/%3Ehttp://github.com/jquery/jquery/commit/ffb1867a4364ea65e60dad3469e8c8eb420ebcac">commit</a>)</p>
<p>例如, 你可以通过<code>jQuery.browser.webkit</code>探测引擎是否是Webkit。</p>
<p><strong>改进了对<code>applets</code>的处理</strong> (<a target="_blank"  href="http://github.com/jquery/jquery/commit/59802928566b6be3a66d65e77c2418fff37e6f5f">commit 1</a>, <a target="_blank"  href="http://github.com/jquery/jquery/commit/3ec2f1aef6b137d0f639e2fc53f95352d24b9d90">commit 2</a>)</p>
<p>jQuery不再试图在Java applets上绑定事件或是数据了(绑定事件或是数据会出现错误)。</p>
<p><strong>不再使用arguments.callee</strong> (<a target="_blank"  href="http://github.com/jquery/jquery/commit/985856b823b1648bffc3fd63c1faf836d0ddaf7c">commit</a>)</p>
<p>为了顺应<a target="_blank"  href="http://code.google.com/p/google-caja/">Caja</a>的要求, 同时也因为即将开始应用的ECMAScript 5规范里将其标记为陈旧, 我们将jQuery核心中所有用到<code>arguments.callee</code>的代码都移除了。</p>
<p><strong>用Closure Compiler替换了YUI Min</strong> (<a target="_blank"  href="http://github.com/jquery/jquery/commit/3fd62eae9df3159fc238a515bb748140a942313d">commit</a>)</p>
<h4>内部重组 (Internal Reorganization)</h4>
<p>在1.4版的开发过程中的一个重点是要建立一个更易读, 更易懂的代码库。为了达到这个目标我们树立了一系列编写代码规范的向导。</p>
<p>下面是一些主要的变化:</p>
<blockquote>
<p>旧的’core.js’文件被分成了’attribute.js’, ‘css.js’, ‘data.js’, ‘manipulation.js’, ‘traversing.js’, and ‘queue.js’.</p>
<p>ready事件被移入了’core.js’ (因为它是jQuery的一个基本组成之一)。</p>
<p>大部分核心代码都符合新的<a target="_blank"  href="http://docs.jquery.com/JQuery_Core_Style_Guidelines">代码规范</a>.</p>
<p>css和属性的逻辑被划分开来, 不再如以往相互缠绕。</p>
</blockquote>
<h4>测试 (Testing)</h4>
<p>jQuery 1.4版发布过程中我们<a target="_blank"  href="http://dev.jquery.com/report/34">修复了207个问题</a> (比较之下1.3版里有97个修复)。</p>
<p>jQuery 1.4.此外, 测试的数量从jQuery 1.3.2中的1504例升到了1.4中的3060例。</p>
<p>所有测试都在主要浏览器里完全通过了。(Safari 3.2, Safari 4, Firefox 2, Firefox 3, Firefox 3.5, IE 6, IE 7,<br />
IE 8, Opera 10.10, and Chrome)</p>
<p><a target="_blank"  rel="lightbox[69]" href="http://www.uxd2.com/wp-content/uploads/2010/01/08-test.jpg"><img title="jQuery 1.4 测试结果" src="http://www.uxd2.com/wp-content/uploads/2010/01/08-test.jpg" alt="jQuery 1.4 测试结果" width="500" height="277" /></a></p>
<h1><a target="_blank"  name="backwards"></a></h1>
<p>我们尽量试图减小jQuery 1.4对大规模升级可能造成的麻烦 – 保持所有公开函数的签名不变。即使如此, 请通读下面的列表以保证你对可能对你的应用造成问题的变更。</p>
<blockquote>
<p><a target="_blank"  href="http://api.jquery.com/add">.add()</a>不再简单的将结果串联到一起, 结果将会被混合到一起, 然后根据他们在页面里的顺序排列。</p>
<p><a target="_blank"  href="http://api.jquery.com/clone">.clone(true)</a>将复制事件和数据, 而不仅是事件。</p>
<p><a target="_blank"  href="http://api.jquery.com/jQuery.data">jQuery.data(elem)</a> 不再返回<code>id</code>, 取而代之的是元素的对象缓存。</p>
<p><a target="_blank"  href="http://api.jquery.com/jQuery">jQuery()</a> (无参数) 不再自动转换成<a target="_blank"  href="http://api.jquery.com/jQuery">jQuery(document)</a>了。</p>
<p>通过<a target="_blank"  href="http://api.jquery.com/val">.val(“…”)</a>获得一个<code>option</code>或一个<code>checkbox</code>的值不再有歧义(将总是根据<code>value</code>属性选择, 而不是根据<code>text</code>的值)。(<a target="_blank"  href="http://github.com/jquery/jquery/commit/f298cce100c6fe23840ac95e66aaea9cb2bfb447">Commit</a>)</p>
<p><a target="_blank"  href="http://api.jquery.com/jQuery.browser">jQuery.browser.version</a>现在将返回引擎的版本.</p>
<p>现在起将对引入的JSON更严格, 如果JSON的格式不符将会报错。如果你需要对不符合JSON严格格式的Javascript进行估值, 你必须设置请求的文件类型为纯文本, 然后用<code>eval()</code>来对内容估值。</p>
<p>参数序列化默认会按照PHP/Rails的风格进行。你可以通过<code>jQuery.ajaxSettings.traditional = true;</code>来切换到旧的序列化方式。你也可以针对个别请求进行切换, 在调用<a target="_blank"  href="http://api.jquery.com/jQuery.ajax">jQuery.ajax</a>的时候递入<code>{traditional: true}</code></p>
<p>内部的jQuery.className被移除了。</p>
<p><a target="_blank"  href="http://api.jquery.com/jQuery.extend">jQuery.extend(true, …)</a>不再扩展复杂对象或是阵列。(TODO)</p>
<p>如果一个<a target="_blank"  href="http://api.jquery.com/jQuery.ajax">Ajax请求</a>没有指定dataType, 而返回的数据类型是”text/javascript”, 那么回复将会被执行。之前, 必须明确的指定dataType。</p>
<p>设置<a target="_blank"  href="http://api.jquery.com/jQuery.ajax">Ajax 请求</a>的”ifModified”属性会将ETags纳入考虑。</p>
</blockquote>
<p>我们还针对1.4版中可能造成问题的变更编写了一个向后兼容的<a target="_blank"  href="http://github.com/jquery/jquery-compat-1.3">插件</a>。如果你升级到1.4以后出现问题, 可以在引入1.4版的文件之后引入这个插件。</p>
<p>如何使用这个插件:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;script src=&quot;http://code.jquery.com/jquery.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;http://code.jquery.com/jquery.compat-1.3.js&quot;&gt;&lt;/script&gt;
</pre>
<h3>原始数据和测试页面</h3>
<p>性能测试中我们使用了下列测试套包:</p>
<blockquote>
<p><a target="_blank"  href="http://ejohn.org/files/jquery1.4/slick/?type=attr">Attributes</a></p>
<p><a target="_blank"  href="http://ejohn.org/files/jquery1.4/slick/?type=class">Class</a></p>
<p><a target="_blank"  href="http://ejohn.org/files/jquery1.4/slick/?type=dom">DOM Manipulation</a></p>
<p><a target="_blank"  href="http://ejohn.org/files/jquery1.4/slick/?type=empty">Empty/Remove</a></p>
<p>Function Call Profiling: <a target="_blank"  href="http://ejohn.org/files/jquery-profile.html">1.3.2</a> <a target="_blank"  href="http://ejohn.org/files/jquery-profile-14.html">1.4</a>.</p>
</blockquote>
<p>结果的原始数据 (所有的数据都是 1.3.2 vs. 1.4):</p>
<blockquote>
<p>函数调用的次数<br />
547    3<br />
760    3<br />
500    200<br />
896    399<br />
23909    299<br />
307    118<br />
28955    100<br />
28648    201<br />
1662    593</p>
<p>DOM嵌入<br />
558    317<br />
1079    624<br />
1079    516<br />
1155    829<br />
436    332<br />
196    194<br />
243    169</p>
<p>HTML<br />
116    46<br />
281    78<br />
313    78<br />
234    63<br />
134    43<br />
43    42<br />
91    27</p>
<p>CSS/属性<br />
703    370<br />
1780    1250<br />
1765    1250<br />
1157    749<br />
629    498<br />
346    184<br />
333    161</p>
<p>CSS<br />
114    52<br />
203    93<br />
118    93<br />
109    47<br />
116    54<br />
58    24<br />
54    22</p>
<p>CSS类<br />
553    138<br />
1578    546<br />
1515    501<br />
1033    327<br />
769    298<br />
229    80<br />
173    41</p>
<p>移除/清空<br />
3298    286<br />
9030    2344<br />
7921    1703<br />
5282    1266<br />
2898    303<br />
1166    140<br />
1034    122</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/jquery-14-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>google的声明，谷歌百度解禁，白宫表态，接下来会发生什么？</title>
		<link>http://www.oncoding.cn/2010/what-happend-to-china/</link>
		<comments>http://www.oncoding.cn/2010/what-happend-to-china/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 11:45:59 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[扯淡]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=571</guid>
		<description><![CDATA[继1月12日百度被黑长达半天之后，今天互联网爆出了更重磅的新闻：google官方博客宣布有意关闭google.cn及谷歌中国办公室。 这一消息立即引起了轩然大波，互联网上弥漫着一股哀伤与低迷的氛围。 而接下来发生的一系列事情，让人不禁开始绷紧神经，不禁要问：百度和谷歌究竟发生了什么？中国政府到底想干什么？事态究竟将怎样发展？ 本文只搜集看到的、听到的一些消息，不发布个人意见。 Google 官方博客声明 Google官方博客于美国时间12日进行了更新(需翻墙查看)：A new approach to China ，文章详细的描述了来自中国大陆的攻击行为，以及政府对信息的封锁。 查看附件声明译文 据说谷歌中国全体员工组织观看阿凡达，吃散伙饭，看来谷歌离开已成定局： 今天谷歌搜索开始部分解除内容过滤： 同时百度也几乎完全解除了过滤，搜索结果令人及其心神不宁： 不过截止发稿时，百度已经重新封锁了这类敏感词的搜索。 今天下午，twitter、youtube等短时解封 据网友称，1月13日下午18点左右，原先墙外的twitter、youtube等网站短时可以访问，但到了19：00，这几个网站已再次被墙。 更令人寻味的是，美国国务卿克林顿在白宫网站上发表了这样一条声明： 外交部发言人姜瑜：“如果没有中国政府的积极培育，中国的互联网不可能如此迅速地发展……任何国家都对互联网实行依法管理” 人民网北京1月14日电　据外交部网站消息，13日外交部发言人姜瑜举行例行记者会。 会上有记者问：“大赦国际”称，北京奥运会期间该组织的网站在中国境内曾被解封，但最近又被屏蔽。中方对此有何评论？ 姜瑜回答说，中国政府对互联网实行积极开放和依法管理的政策，我们的互联网政策符合国际通行作法。目前，中国的互联网网站数量多达210万个，网民超过3亿，中国已成为网民数量最多的国家。如果没有中国政府的积极培育，中国的互联网不可能如此迅速地发展。 姜瑜强调，任何国家都对互联网实行依法管理。根据中国的法律，不能通过互联网传播违反法律的信息，如宣传邪教、鼓吹国家分裂等，“我想大家对这一点是清楚的。” 来源：外交部姜瑜：不能通过互联网传播违反法律的信息 百度首席产品设计师孙云丰表态：Google是市侩分子，对此感到恶心 孙云丰于13日下午1时20分，在CSDN博客上的博文(后被百度直接要求CSDN删帖)： google宣称要退出中国，所证明的，恰恰不是市面上的那些g粉所宣称的那样，google是个人权斗士，而刚好反了过来，正好证明google是个市侩分子。 google 的首席法律顾问的调调让我感到恶心。因经济利益退出，就直白白的说好了，把自己涂脂抹粉一番，还煞有介事的提到google被中国人攻击，中国异议分子的 Gmail信箱被攻击，把这些事情作为退出中国的铺垫，这种论调是侮辱中国普通老百姓的智商，但还真有可能迎合那帮目空一切，但从未到过中国、对中国没有丝毫了解，却又喜欢对中国说三道四的西方人的假想。 只提一个假设，如果谷歌占据了中国80%的搜索市场份额，google的高管，还会这么高调的宣称要do no evil，从中国退出吗？ 整个事情给我的唯一感受，就是恶心。 ————– 以上是作为一个曾经的忠实google用户而说的，和百度无关。市面上沾沾自喜于了解一点google的产品技术细节将google奉为道德楷模而自封G粉的兄弟，请勿跟帖瞎喷，你们根本不懂什么叫搜索引擎，什么叫自由人权。 来源：http://blog.xiqiao.info/2010/01/13/624 1月19日最新消息：谷歌中国内部混入内奸？ 昨天路透社发布新闻： Google probing possible inside help on attack，称谷歌中国内部人士将google代码泄露了出去，造成了google此次的大范围被攻击事件。 然而，公司中出现商业或技术间谍是很常见的事情，为什么google此次却要如此大动肝火呢？一位自称谷歌中国员工的豆瓣网友进行了解释：google事件真相。 谷歌宣布谷歌中国“恢复正常运转”，刘允、杨文洛发文“澄清不实的传言” 2010年1月19日下午，谷歌中国在其官方博客中澄清了有关谷歌中国关闭的传言。谷歌全球副总裁刘允和谷歌中国工程研究总经理杨文洛在日志中称，谷歌中国的员工同过去一样在办公室正常工作。 谷歌中国在博客中称，“过去几天，我们看到有很多关于谷歌中国以及谷歌员工的不真实的传言，一些报道称我们已经关闭了在中国的办公室，还有一些报道称我们在中国的员工已经接到通知将于近期离职。这些都是不真实的。目前，谷歌中国的员工同过去一样在办公室正常工作。” 一位接近谷歌的人士昨天向记者表示，谷歌中国的办公室已经恢复办公，从13日上午就无法登录的内部网站和全球数据库也开始恢复正常使用。 美国国务卿希拉里发表Internet Freedom(互联网自由)演讲 [...]]]></description>
			<content:encoded><![CDATA[<p>继1月12日百度被黑长达半天之后，今天互联网爆出了更重磅的新闻：<a href="http://googleblog.blogspot.com/2010/01/new-approach-to-china.html" target="_blank">google官方博客宣布有意关闭google.cn及谷歌中国办公室</a>。</p>
<p>这一消息立即引起了轩然大波，互联网上弥漫着一股哀伤与低迷的氛围。</p>
<p>而接下来发生的一系列事情，让人不禁开始绷紧神经，不禁要问：百度和谷歌究竟发生了什么？中国政府到底想干什么？事态究竟将怎样发展？</p>
<p>本文只搜集看到的、听到的一些消息，不发布个人意见。</p>
<h3>Google 官方博客声明</h3>
<p><span id="more-571"></span></p>
<p>Google官方博客于美国时间12日进行了更新(需翻墙查看)：<a href="http://googleblog.blogspot.com/2010/01/new-approach-to-china.html" target="_blank">A new approach to China </a>，文章详细的描述了来自中国大陆的攻击行为，以及政府对信息的封锁。</p>
<p><a href="http://www.oncoding.cn/2010/what-happend-to-china/#trans">查看附件声明译文</a></p>
<h3>据说谷歌中国全体员工组织观看阿凡达，吃散伙饭，看来谷歌离开已成定局：</h3>
<p style="text-align: center; border: 1px solid #eee;"><a href="http://www.oncoding.cn/wp-content/uploads/2010/01/7f0425a8a61e7d728ce2de027734ca96_1263374077852_445x351.jpeg" target="_blank"><img class="aligncenter size-full wp-image-576" src="http://www.oncoding.cn/wp-content/uploads/2010/01/7f0425a8a61e7d728ce2de027734ca96_1263374077852_445x351.jpeg" alt="" width="445" height="351" /></a></p>
<h3>今天谷歌搜索开始部分解除内容过滤：</h3>
<p style="text-align: center; border: 1px solid #eee;"><a href="http://www.oncoding.cn/wp-content/uploads/2010/01/guge.jpg" target="_blank"></a><a href="http://www.oncoding.cn/wp-content/uploads/2010/01/guge.jpg"><img class="aligncenter size-large wp-image-572" src="http://www.oncoding.cn/wp-content/uploads/2010/01/guge-1023x562.jpg" alt="" width="540" height="296" /></a></p>
<p style="text-align: center; border: 1px solid #eee;"><a href="http://www.oncoding.cn/wp-content/uploads/2010/01/guge2.jpg"><img class="aligncenter size-full wp-image-580" src="http://www.oncoding.cn/wp-content/uploads/2010/01/guge2.jpg" alt="" width="536" height="572" /></a></p>
<h3>同时百度也几乎完全解除了过滤，搜索结果令人及其心神不宁：</h3>
<p style="text-align: center; border: 1px solid #eee;"><a href="http://www.oncoding.cn/wp-content/uploads/2010/01/baidu.jpg" target="_blank"><img class="aligncenter size-full wp-image-574" src="http://www.oncoding.cn/wp-content/uploads/2010/01/baidu.jpg" alt="" width="295" height="383" /></a></p>
<p>不过截止发稿时，百度已经重新封锁了这类敏感词的搜索。</p>
<h3>今天下午，twitter、youtube等短时解封</h3>
<p>据网友称，1月13日下午18点左右，原先墙外的twitter、youtube等网站短时可以访问，但到了19：00，这几个网站已再次被墙。</p>
<h3>更令人寻味的是，美国国务卿克林顿在白宫网站上发表了<a href="http://www.state.gov/secretary/rm/2010/01/135105.htm" target="_blank">这样一条声明</a>：</h3>
<p style="text-align: center; border: 1px solid #eee;"><a href="http://www.oncoding.cn/wp-content/uploads/2010/01/baigong.jpg" target="_blank"><img class="aligncenter size-full wp-image-575" title="baigong" src="http://www.oncoding.cn/wp-content/uploads/2010/01/baigong.jpg" alt="" width="540" height="287" /></a></p>
<h3>外交部发言人姜瑜：“如果没有中国政府的积极培育，中国的互联网不可能如此迅速地发展……任何国家都对互联网实行依法管理”</h3>
<p>人民网北京1月14日电　据外交部网站消息，13日外交部发言人姜瑜举行例行记者会。</p>
<p>会上有记者问：“大赦国际”称，北京奥运会期间该组织的网站在中国境内曾被解封，但最近又被屏蔽。中方对此有何评论？</p>
<p>姜瑜回答说，中国政府对互联网实行积极开放和依法管理的政策，我们的互联网政策符合国际通行作法。目前，中国的互联网网站数量多达210万个，网民超过3亿，中国已成为网民数量最多的国家。如果没有中国政府的积极培育，中国的互联网不可能如此迅速地发展。</p>
<p>姜瑜强调，任何国家都对互联网实行依法管理。根据中国的法律，不能通过互联网传播违反法律的信息，如宣传邪教、鼓吹国家分裂等，“我想大家对这一点是清楚的。”</p>
<p>来源：<a href="http://media.people.com.cn/GB/8671780.html" target="_blank">外交部姜瑜：不能通过互联网传播违反法律的信息</a></p>
<h3>百度首席产品设计师孙云丰表态：Google是市侩分子，对此感到恶心</h3>
<p>孙云丰于13日下午1时20分，在CSDN博客上的<a href="http://news.csdn.net/a/20100113/216459.html" target="_blank">博文</a>(后被百度直接要求CSDN删帖)：</p>
<blockquote><p>google宣称要退出中国，所证明的，恰恰不是市面上的那些g粉所宣称的那样，google是个人权斗士，而刚好反了过来，正好证明google是个市侩分子。<br />
google 的首席法律顾问的调调让我感到恶心。因经济利益退出，就直白白的说好了，把自己涂脂抹粉一番，还煞有介事的提到google被中国人攻击，中国异议分子的 Gmail信箱被攻击，把这些事情作为退出中国的铺垫，这种论调是侮辱中国普通老百姓的智商，但还真有可能迎合那帮目空一切，但从未到过中国、对中国没有丝毫了解，却又喜欢对中国说三道四的西方人的假想。</p>
<p>只提一个假设，如果谷歌占据了中国80%的搜索市场份额，google的高管，还会这么高调的宣称要do no evil，从中国退出吗？</p>
<p>整个事情给我的唯一感受，就是恶心。<br />
————–<br />
以上是作为一个曾经的忠实google用户而说的，和百度无关。市面上沾沾自喜于了解一点google的产品技术细节将google奉为道德楷模而自封G粉的兄弟，请勿跟帖瞎喷，你们根本不懂什么叫搜索引擎，什么叫自由人权。</p>
</blockquote>
<p>来源：<a href="http://blog.xiqiao.info/2010/01/13/624" target="_blank">http://blog.xiqiao.info/2010/01/13/624</a></p>
<h3>1月19日最新消息：谷歌中国内部混入内奸？</h3>
<p>昨天路透社发布新闻： <a href="http://www.reuters.com/article/idUSTOE60H07V20100118" target="_blank">Google probing possible inside help on attack</a>，称谷歌中国内部人士将google代码泄露了出去，造成了google此次的大范围被攻击事件。</p>
<p>然而，公司中出现商业或技术间谍是很常见的事情，为什么google此次却要如此大动肝火呢？一位自称谷歌中国员工的豆瓣网友进行了解释：<a href="http://www.douban.com/group/topic/9535007/" target="_blank">google事件真相</a>。</p>
<h3>谷歌宣布谷歌中国“恢复正常运转”，刘允、杨文洛发文“澄清不实的传言”</h3>
<p>2010年1月19日下午，谷歌中国在其<a target="_blank" href="http://www.googlechinablog.com/">官方博客</a>中澄清了有关谷歌中国关闭的传言。谷歌全球副总裁刘允和谷歌中国工程研究总经理杨文洛在日志中称，谷歌中国的员工同过去一样在办公室正常工作。</p>
<p>谷歌中国在博客中称，“过去几天，我们看到有很多关于谷歌中国以及谷歌员工的不真实的传言，一些报道称我们已经关闭了在中国的办公室，还有一些报道称我们在中国的员工已经接到通知将于近期离职。这些都是不真实的。目前，谷歌中国的员工同过去一样在办公室正常工作。”</p>
<p>一位接近谷歌的人士昨天向记者表示，谷歌中国的办公室已经恢复办公，从13日上午就无法登录的内部网站和全球数据库也开始恢复正常使用。</p>
<h3>美国国务卿希拉里发表Internet Freedom(互联网自由)演讲</h3>
<p>美国国务卿希拉里·克林顿于21日发表了一份互联网政策讲话——Internet Freedom，阐述了美国政府应对网络时代的战略方针，其中多次提及了中国的互联网封锁及google事件。</p>
<p>英文原文：</p>
<p><a target="_blank" href="http://www.foreignpolicy.com/articles/2010/01/21/internet_freedom?page=0">http://www.foreignpolicy.com/articles/2010/01/21/internet_freedom?page=0</a></p>
<p>演讲中文翻译见：</p>
<p><a target="_blank" href="http://www.america.gov/st/democracyhr-chinese/2010/January/20100121212440eaifas0.9105341.html?CP.rss=true&#038;utm_source=twitterfeed&#038;utm_medium=twitter">http://www.america.gov/st/democracyhr-chinese/2010/January/20100121212440eaifas0.9105341.html?CP.rss=true&#038;utm_source=twitterfeed&#038;utm_medium=twitter</a></p>
<h3>事态会怎样发展，本博将继续关注..</h3>
<h3 id="trans">附：Google官方博客的译文</h3>
<p>来源：<a href="http://gb.hrichina.org/gate/gb?url=big5.hrichina.org/public/contents/18135" target="_blank">http://gb.hrichina.org/gate/gb?url=big5.hrichina.org/public/contents/18135</a></p>
<blockquote><p>谷歌声明：重新考虑在中国的做法</p>
<p>中国人权的中文译本</p>
<p>象许多其它着名的组织一样，我们经常面临不同程度的网络攻击。12月中旬，我们监测到一起针对我们公司基础设施的非常复杂且具高度针对性的攻击。这一攻击来自中国，并导致谷歌知识产权被窃。尽管最初在表面上这只是一起单纯的安全事件，但很快就表明这显然是一起严重的事件。</p>
<p>首先，这次攻击不仅是针对谷歌。作为我们调查的一部分，我们发现，至少有其它20家涉及许多行业领域的大公司，包括互联网、金融、技术、媒体和化工等，也成为类似的攻击对象。我们目前正通知这些公司，并与美国有关当局合作。</p>
<p>第二，我们有证据表明，攻击者的主要目标是中国从事人权活动人士的Gmail帐户。根据我们最新的调查，我们相信他们的攻击目标并未实现。只有两个Gmail帐户被侵入，但仅限於帐户信息（如帐户创建日期）和邮件主题，并没有进入邮件内容。</p>
<p>第三，作为这项调查的一部分（并不仅限於对攻击谷歌的调查），我们发现几十个在中国从事人权活动的Gmail用户，其账户设在美国、中国和欧洲，显示出经常被第三方侵入。这些账户不是由於谷歌的安全漏洞而被侵入的，而最有可能的是通过网络诈骗或安装在用户电脑上的恶意软件所为。</p>
<p>我们已经使用从攻击得到的信息去改善谷歌的基础设施和架构，提高谷歌自身和用户的安全性。在个人用户方面，我们建议在电脑上安装可靠的反病毒和反间谍软件程序，为操作系统安装补丁，并更新网络浏览器。在点击即时信息和电子邮件中的链接时，或在网上被要求分享个人信息如密码时，一定要格外小心。你可以点击这里，阅读更多关於我们的网络安全的建议。有兴趣了解这类黑客攻击的人们可以阅读美国政府的报告（PDF格式），纳尔特·维伦纽夫的博客（Nart Villeneuve&#8217;s blog）和对GhostNet间谍事件的介绍。</p>
<p>对这些攻击，我们已采取了非常措施来与广大读者分享信息，这不只是因为我们发现其对安全和人权的影响，还因为这些信息与一个更大的关於言论自由的全球性辩论的核心相联系。在过去20年里，中国的经济改革计划和其公民的创业精神已经使亿万中国人脱离了贫困。事实上，这个伟大的国家，正处於当今世界许多经济进步和发展的中心。</p>
<p>2006年我们推出谷歌中国，就是基於这样的信念，让中国人民获得更多信息渠道的好处以及一个更为开放的互联网，这比我们当初并不愉快地同意过滤搜索结果更为重要。当时我们说得很清楚：“我们将仔细监督在中国运营的环境，包括新的法律和其它对我们提供服务的限制。如果确定我们不能达到预定的目标，我们将会毫不犹豫地重新考虑我们在中国的做法。”</p>
<p>这些攻击和监视—结合着去年进一步对网络言论自由的限制—已经使我们得出结论，我们应该审视我们在中国商业运作的可行性。我们已决定，我们将不会再继续过滤我们在谷歌中国上的搜索结果，未来几个星期我们将同中国政府讨论我们在法律范围内是否有可能进行不经过滤的搜索引擎运作的基础。我们知道这可能意味着必须（关系）关闭谷歌中国，以及我们在中国的机构。</p>
<p>做出审议我们在中国商业运作的决定是非常困难的，我们知道，这可能会产生深远的后果。我们希望明确一点，这一决定是我们在美国的主管做出的，我们在中国的雇员并不了解或介入其中，他们的极其努力的工作才（是）使谷歌中国有了今天的成功。我们保证通过负责任的工作来解决出现的非常困难的问题。</p>
<p>谷歌高级副总裁、公司发展和法律主管  大卫•德鲁蒙德<br />
2010年1月12日</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/what-happend-to-china/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>百度被黑深层分析</title>
		<link>http://www.oncoding.cn/2010/baidu-cracked/</link>
		<comments>http://www.oncoding.cn/2010/baidu-cracked/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 04:14:16 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[扯淡]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=561</guid>
		<description><![CDATA[扯淡分析 1. 百度被黑的真正原因是：伊朗圣战军的新任领袖阿卜杜.阿卜杜拉（abaidu.abaidula)看百度不爽，犯了名讳：） -_-! 2. abaidu.abaidula在GOOGLE上搜“SB”搜到自己的名字一下就怒了于是黑了百度 -_-! 3. 政治抗议只是表面原因，其实——由于米国的军事打击威胁，伊朗人准备大批量购买火箭筒，于是来百度搜索，但是遭遇百度的竞价排名，伊朗人选购了搜索结果排名第一位的火箭筒，到手之后发现上当。伊朗人气不过，遂黑了百度 -_-! 4. 国内互联网形势风起云涌，百度忙于公关打理，忘了域名续费 -_-! 5. 因为李彦宏不信春哥，百度未能满状态原地复活。。-_-! 阴谋论分析 6. 据称此次伊朗网军所用标志与之前不符，有可能是天朝欲出兵Irac，正在为师出有名制造舆论氛围。 7. “有关部门”发布紧急通知：为防止事态进一步扩大，决定切断中美、中欧通信光缆，开通时间另行通知。。 8. 伊朗网络部队搞毕业考试，把国内网站黑了给结业证，把外国网站黑了给毕业证，把百度黑了给毕业证+推荐工作（google赞助）。。。 天朝逻辑分析 9. CCAV报道：百度今晨被黑，山西一大学生火线举报伊朗网络军，声称此举令其心神不宁。 10. 百度称，由于www.baidu.com的域名在美国域名注册商处被非法篡改，导致www.baidu.com不能被正常访问，百度公司有关部门正在积极处理。这时工信部应该站出来，批判一下国外的域名注册商多么不靠谱——想稳定，还得用.cn！ 11. 百度被黑，真理部出面宣称对此事不负责，云山同志火线电话李彦宏总：“你丫放心，这是伊朗人干的，不是我们”。外交部紧急召开发布会，秦刚严厉谴责伊朗网络军玩过界，挑战中国作为互联网封锁第一大国的权威。]]></description>
			<content:encoded><![CDATA[<h3>扯淡分析</h3>
<p>1. 百度被黑的真正原因是：伊朗圣战军的新任领袖阿卜杜.阿卜杜拉（abaidu.abaidula)看百度不爽，犯了名讳：） -_-!</p>
<p>2. abaidu.abaidula在GOOGLE上搜“SB”搜到自己的名字一下就怒了于是黑了百度 -_-!</p>
<p>3. 政治抗议只是表面原因，其实——由于米国的军事打击威胁，伊朗人准备大批量购买火箭筒，于是来百度搜索，但是遭遇百度的竞价排名，伊朗人选购了搜索结果排名第一位的火箭筒，到手之后发现上当。伊朗人气不过，遂黑了百度 -_-!</p>
<p>4. 国内互联网形势风起云涌，百度忙于公关打理，忘了域名续费 -_-!</p>
<p>5. 因为李彦宏不信春哥，百度未能满状态原地复活。。-_-!</p>
<h3>阴谋论分析</h3>
<p><span id="more-561"></span></p>
<p>6. 据称此次伊朗网军所用标志与之前不符，有可能是天朝欲出兵Irac，正在为师出有名制造舆论氛围。</p>
<p>7. “有关部门”发布紧急通知：为防止事态进一步扩大，决定切断中美、中欧通信光缆，开通时间另行通知。。</p>
<p>8. 伊朗网络部队搞毕业考试，把国内网站黑了给结业证，把外国网站黑了给毕业证，把百度黑了给毕业证+推荐工作（google赞助）。。。</p>
<h3>天朝逻辑分析</h3>
<p>9. CCAV报道：百度今晨被黑，山西一大学生火线举报伊朗网络军，声称此举令其心神不宁。</p>
<p>10. 百度称，由于www.baidu.com的域名在美国域名注册商处被非法篡改，导致www.baidu.com不能被正常访问，百度公司有关部门正在积极处理。这时工信部应该站出来，批判一下国外的域名注册商多么不靠谱——想稳定，还得用.cn！</p>
<p>11. 百度被黑，真理部出面宣称对此事不负责，云山同志火线电话李彦宏总：“你丫放心，这是伊朗人干的，不是我们”。外交部紧急召开发布会，秦刚严厉谴责伊朗网络军玩过界，挑战中国作为互联网封锁第一大国的权威。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/baidu-cracked/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>团队内分享：总结2009，展望2010</title>
		<link>http://www.oncoding.cn/2010/hello2010/</link>
		<comments>http://www.oncoding.cn/2010/hello2010/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 14:29:43 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[扯淡]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=763</guid>
		<description><![CDATA[有幸在2010年第一次团队会议上作了一次分享，总结了2009年前端界和普加前端发生的事情，对2010年的发展作了一些展望。 View more presentations from guestc94918. slideshare处理后版面产生了些问题，不过不影响阅读，不再作调整了。]]></description>
			<content:encoded><![CDATA[<p>有幸在2010年第一次团队会议上作了一次分享，总结了2009年前端界和普加前端发生的事情，对2010年的发展作了一些展望。</p>
<div style="width:425px" id="__ss_3618949"><object width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=201001-100402042818-phpapp01&#038;rel=0&#038;stripped_title=20092010-3618949" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=201001-100402042818-phpapp01&#038;rel=0&#038;stripped_title=20092010-3618949" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="padding:5px 0 12px">View more <a target="_blank" href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/guestc94918">guestc94918</a>.</div>
</div>
<p>slideshare处理后版面产生了些问题，不过不影响阅读，不再作调整了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/hello2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用框架的最高境界是忘掉框架，而不是依赖甚至依附框架</title>
		<link>http://www.oncoding.cn/2010/uselesswork-with-framework/</link>
		<comments>http://www.oncoding.cn/2010/uselesswork-with-framework/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 15:27:20 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[扯淡]]></category>
		<category><![CDATA[框架]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=557</guid>
		<description><![CDATA[张三丰一路剑法使完，竟无一人喝彩，各人竟皆诧异：“这等慢吞吞、软绵绵的剑法，如何能用来对敌过招？”转念又想：“料来张真人有意放慢了招数，好让他瞧得明白。” 只听张三丰问道：“孩儿，你看清楚了没有？”张无忌道：“看清楚了。”张三丰道：“都记得了没有？”张无忌道：“已忘记了一小半。”张三丰道：“好，那也难为了你。你自己去想想罢。”张无忌低头默想。过了一会，张三丰问道：“现下怎样了？”张无忌道：“已忘记了一大半。” 周颠失声叫道：“糟糕！越来越忘记得多了。张真人，你这路剑法是很深奥，看一遍怎能记得？请你再使一遍给我们教主瞧瞧罢。”张三丰微笑道：“好，我再使一遍。”提剑出招，演将起来。众人只看了数招，心下大奇，原来第二次所使，和第一次使的竟然没一招相同。周颠叫道：“糟糕，糟糕！这可更加叫人胡涂啦。”张三丰画剑成圈，问道：“孩儿，怎样啦？”张无忌道：“还有三招没忘记。”张三丰点点头，放剑归座。张无忌在殿上缓缓踱了一个圈子，沉思半晌，又缓缓踱了半个圈子，抬起头来，满脸喜色，叫道：“这我可全忘了，忘得乾乾净净的了。”张三丰道：“不坏，不坏！忘得真快，你这就请八臂神剑指教罢！”]]></description>
			<content:encoded><![CDATA[<p>张三丰一路剑法使完，竟无一人喝彩，各人竟皆诧异：“这等慢吞吞、软绵绵的剑法，如何能用来对敌过招？”转念又想：“料来张真人有意放慢了招数，好让他瞧得明白。”</p>
<p>只听张三丰问道：“孩儿，你看清楚了没有？”张无忌道：“看清楚了。”张三丰道：“都记得了没有？”张无忌道：“已忘记了一小半。”张三丰道：“好，那也难为了你。你自己去想想罢。”张无忌低头默想。过了一会，张三丰问道：“现下怎样了？”张无忌道：“已忘记了一大半。”</p>
<p>周颠失声叫道：“糟糕！越来越忘记得多了。张真人，你这路剑法是很深奥，看一遍怎能记得？请你再使一遍给我们教主瞧瞧罢。”张三丰微笑道：“好，我再使一遍。”提剑出招，演将起来。众人只看了数招，心下大奇，原来第二次所使，和第一次使的竟然没一招相同。周颠叫道：“糟糕，糟糕！这可更加叫人胡涂啦。”张三丰画剑成圈，问道：“孩儿，怎样啦？”张无忌道：“还有三招没忘记。”张三丰点点头，放剑归座。张无忌在殿上缓缓踱了一个圈子，沉思半晌，又缓缓踱了半个圈子，抬起头来，满脸喜色，叫道：“这我可全忘了，忘得乾乾净净的了。”张三丰道：“不坏，不坏！忘得真快，你这就请八臂神剑指教罢！”</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2010/uselesswork-with-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>寻根究底：Ajax请求的GET与POST方式比较</title>
		<link>http://www.oncoding.cn/2009/ajax-get-post/</link>
		<comments>http://www.oncoding.cn/2009/ajax-get-post/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 13:38:05 +0000</pubDate>
		<dc:creator>j5726</dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[get]]></category>
		<category><![CDATA[post]]></category>

		<guid isPermaLink="false">http://www.oncoding.cn/?p=480</guid>
		<description><![CDATA[YSlow里有一条规则叫Use GET for AJAX requests，即“使用GET方式请求AJAX”，YSlow中的解释如下： When using the XMLHttpRequest object, the browser implements POST in two steps: (1) send the headers, and (2) send the data. It is better to use GET instead of POST since GET sends the headers and the data together (unless there are many cookies). IE&#8217;s maximum URL length is 2 [...]]]></description>
			<content:encoded><![CDATA[<p>YSlow里有一条规则叫<a target="_blank" href="http://developer.yahoo.com/performance/rules.html#ajax_get">Use GET for AJAX requests</a>，即“<strong>使用GET方式请求AJAX</strong>”，YSlow中的解释如下：</p>
<blockquote><p>When using the XMLHttpRequest object, the browser implements POST in two steps: (1) send the headers, and (2) send the data. It is better to use GET instead of POST since GET sends the headers and the data together (unless there are many cookies). IE&#8217;s maximum URL length is 2 KB, so if you are sending more than this amount of data you may not be able to use GET.</p></blockquote>
<p>翻译：</p>
<blockquote><p>当使用XMLHttpRequest对象时，浏览器通过两个步骤实现POST：(1)发送请求头；(2)发送数据。而GET的请求头和数据是一起发送的(除非包含很多cookie)，所以使用GET方式更好些。IE支持的最大URL长度是2KB，所以你的数据很长的话就不能用GET了。</p></blockquote>
<p>这段话蜻蜓点水，只说了GET和POST的这两个差别，而实际使用中会是这么简单吗？</p>
<h3>寻根：GET与POST的差别</h3>
<p><span id="more-480"></span></p>
<p><a href="http://www.rfc2616.com/" target="_blank">RFC2616</a>中详细定义和解释了<a href="http://www.rfc2616.com/#9.3" target="_blank">GET</a>和<a href="http://www.rfc2616.com/#9.5" target="_blank">POST</a>，简单来说，<strong>GET和POST的根本区别如下：</strong></p>
<p>GET通过URL传递参数(以本文的动态地址 http://www.oncoding.cn/?p=480 为例)，同时发送请求头，从服务器取得数据：</p>
<blockquote>
<p>GET /?p=480 HTTP/1.1</p>
<p>Host: www.oncoding.cn</p>
<p>Mozilla/5.0</p>
<p>&#8230;.</p>
</blockquote>
<p>POST也需要URL和请求头，同时需要额外发送数据到服务器，然后取得服务器响应，其数据格式如下：</p>
<blockquote>
<p>POST /wp-login.php HTTP/1.1</p>
<p>Host: www.oncoding.cn</p>
<p>User-Agent: Mozilla/5.0</p>
<p>&#8230;.</p>
<p>userid=admin&#038;password=asdfg</p>
</blockquote>
<p><strong>GET和POST为什么有速度的差异？</strong></p>
<p>如YSlow所说，POST比GET多出了一个发送数据的步骤，我们可以通过MIDP实现GET和POST的程序代码来理解这一个过程：</p>
<pre class="brush: java; title: ; notranslate">
// MIDP实现GET的过程(变量定义省略)：
conn = (HttpConnection) Connector.open( url ); //建立连接
conn.setRequestProperty( &quot;User-Agent&quot;, agent ); //设置请求头

int rc = conn.getResponseCode(); //取得响应
// ....
// MIDP实现POST的过程(encodedData为post数据)：
conn = (HttpConnection) Connector.open( url ); //建立连接
conn.setRequestMethod( HttpConnection.POST ); //设置请求头
conn.setRequestProperty( &quot;User-Agent&quot;, agent );
conn.setRequestProperty( &quot;Content-Type&quot;, type );
conn.setRequestProperty( &quot;Content-Length&quot;,
				encodedData.length() );

OutputStream os = conn.openOutputStream(); //发送数据
os.write( encodedData.getBytes() );

int rc = conn.getResponseCode(); //取得响应
</pre>
<p>以上程序摘自<a href="http://developers.sun.com/mobility/midp/ttips/HTTPPost/" target="_blank">HTTP POST Basics</a>。</p>
<p>分析可见，速度的差别确实出在这一个发送数据的环节上，这一环节究竟耗时多少，我们一会儿来测一下。</p>
<p><strong>何时用GET，何时用POST</strong></p>
<p>这个问题不该在我们话题的讨论之列。关于使用场合的差别，无非有两个因素：</p>
<blockquote>
<p>1. POST比GET更安全。因为GET数据可以缓存，url可以被人轻松的得到，而Ajax中不存在这个问题；</p>
<p>2. IE支持url最长为2KB，所以参数过长不能用GET，这条是Ajax需要考虑的地方。</p>
</blockquote>
<h3>究底：Ajax的GET与POST在速度上有多少差别</h3>
<p>刚刚有老外写的一篇<a target="_blank" href="http://dotnetperls.com/get-post-performance">GET and POST Requests in AJAX</a>，比较GET和POST在Ajax中的速度问题，写的洋洋洒洒，但通篇没有一点数据和理论，各浏览器的测试结果居然只有”Very slow”和”Fast”。。。</p>
<p>我们干脆自己写程序来测试一下，通过发送Ajax请求前和接收到Ajax数据后的时间差，来测试其速度的差异。使用了纯Javascript和jquery两种方式作比较。</p>
<p><a href="http://www.oncoding.cn/demos/getpost/" target="_blank">测试DEMO在这里</a>  |  <a href="http://www.oncoding.cn/demos/getpost/demo.zip" target="_blank">下载测试程序包(请根据网速，酌情修改请求时间间隔，否则会引起混乱)</a></p>
<p>手头的几个浏览器测试了一下，PHP程序放在美国Dreamhost服务器上，通过山东电信网络测试结果如下：</p>
<p><strong>Firefox 3.5</strong></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ff3_5.jpg" alt="" title="" width="481" height="133" class="aligncenter size-full wp-image-488" /></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ff3_5_j.jpg" alt="" title="" width="494" height="135" class="aligncenter size-full wp-image-493" /></p>
<p><strong>Chrome 4.0.266 Beta</strong></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/chrome4.jpg" alt="" title="" width="357" height="122" class="aligncenter size-full wp-image-491" /></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/chrome4_j.jpg" alt="" title="" width="358" height="120" class="aligncenter size-full wp-image-492" /></p>
<p><strong>IE8</strong></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ie8.jpg" alt="" title="" width="476" height="121" class="aligncenter size-full wp-image-490" /></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ie8_j.jpg" alt="" title="" width="488" height="121" class="aligncenter size-full wp-image-504" /></p>
<p><strong>虚拟机中的IE6：</strong></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ie61.jpg" alt="" title="" width="474" height="121" class="aligncenter size-full wp-image-506" /></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ie6_j1.jpg" alt="" title="" width="489" height="121" class="aligncenter size-full wp-image-507" /></p>
<p><strong>虚拟机中的Firefox 2.0：</strong></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ff2.jpg" alt="" title="" width="479" height="134" class="aligncenter size-full wp-image-508" /></p>
<p><img src="http://www.oncoding.cn/wp-content/uploads/2009/12/ff2_j.jpg" alt="" title="" width="490" height="134" class="aligncenter size-full wp-image-505" /></p>
<p>通过对这几个流行的浏览器的测试，发现<strong>POST确实比GET要慢，而慢的这个时间基本等于服务器的响应时间(Ping值)</strong>。浏览器之间的差距不大，Firefox3.5和Chrome4速度比IE要快一点。通过jQuery进行Ajax调用比纯JavaScript稍快(是jQuery做了优化还是我JS程序写的不好？)。</p>
<p>其他浏览器有时间再测试一下，也欢迎有条件的朋友帮忙测试。</p>
<h3>后记</h3>
<p>为什么要寻根究底研究这个东西呢？</p>
<p>源于同事开发中遇到的一个问题——使用beforeunload事件，在用户关闭浏览器时通过Ajax向服务器发送数据，使用的POST方式。</p>
<p>在分析数据时，发现有一种情况，得到了请求头信息，却没有得到Ajax数据。虽然这部分数据很少，但引起了我的兴趣，同时把心里一直不明白的这个问题搞清楚了。<del datetime="2009-12-31T00:52:45+00:00">通过这通分析知，这种情况的原因可能是浏览器在得到服务器响应之前，就关闭了连接，而Ajax的异步调用方式，致使beforeunload不会等待Ajax返回，导致POST数据未能发送。解决方法，可以将数据发送改为同步方式。</del>(这个设想不成立，因为发送请求不是异步的，所以原因可能在别的地方。)</p>
<p style="text-align: right;"><a href="http://www.oncoding.cn/2009/ajax-get-post/">幼学笔记</a>原创内容，根据<a href="http://creativecommons.org/licenses/by-nc-sa/2.5/">CC协议</a>发布，欢迎具名转载。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncoding.cn/2009/ajax-get-post/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

