<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[W3C标准WEB前端DHTML精英俱乐部]]></title>
<link>http://www.v-ec.com/dh20156/</link>
<description><![CDATA[Javascript和CSS权威专家WEB前端开发指南]]></description>
<language>zh-cn</language>
<copyright><![CDATA[Copyright PBlog 子舜到处留广告哈 ^_^]]></copyright>
<webMaster><![CDATA[dh20156@126.com(风之石)]]></webMaster>
<generator>PBlog</generator> 
<image>
	<title>W3C标准WEB前端DHTML精英俱乐部</title>
	<url>http://www.v-ec.com/dh20156/images/logos.gif</url>
	<link>http://www.v-ec.com/dh20156/</link>
	<description>W3C标准WEB前端DHTML精英俱乐部</description>
</image>

			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=305</link>
			<title><![CDATA[于北京参加Google前端开发大会前夜]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[My Life]]></category>
			<pubDate>Wed,01 Sep 2010 22:52:37 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=305</guid>
		<description><![CDATA[<p>刚到明天将要举办Google前端开发大会的酒店，与先期抵达的淘宝一行取得联系后，安排好了明天会后与月MM他们聚会事宜，期待哇，大家！：）</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=304</link>
			<title><![CDATA[超赞iPhone (MM) Show]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[My Life]]></category>
			<pubDate>Mon,09 Aug 2010 13:03:23 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=304</guid>
		<description><![CDATA[<p>无需多说，你知道的！</p>
<p><embed height="490" width="600" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://player.youku.com/player.php/sid/XMTYxNDU3MTI0/v.swf" play="true" loop="true" menu="true"></embed></p>
<p>&nbsp;</p>
<p><embed height="490" width="600" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://player.youku.com/player.php/sid/XMTYwMTYwMDA0/v.swf" play="true" loop="true" menu="true"></embed></p>
<p>&nbsp;</p>
<p>Another Android Show:</p>
<p><embed height="490" width="600" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://player.youku.com/player.php/sid/XMTc2NjA2NjY4/v.swf" play="true" loop="true" menu="true"></embed></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=303</link>
			<title><![CDATA[发送自IPad的日志]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Wed,28 Jul 2010 21:28:46 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=303</guid>
		<description><![CDATA[Fck Editer只能在源码模式下输入, File Upload灰色禁用状态，木有办法上传文件的IPad下的liu浏览器不是很好用的说。 ]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=302</link>
			<title><![CDATA[JQuery字符串转DOM节点BUG]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Tue,22 Jun 2010 17:37:07 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=302</guid>
		<description><![CDATA[<p>在修正一个UI的BUG时发现<strong>JQuery将字符串转DOM节点时会将针对IE6的CSS Hack的样式部分进行转义</strong>，测试代码如下：</p>
<p><strong>1、引入JQuery代码</strong></p>
<p>2、运行如下代码测试：</p>
<p><span style="font-size: 14px;">+function(){<br />
var s = '&lt;h1&gt;&lt;em class=&quot;a_b c&quot; style=&quot;min-height:50px;_height:50px;&quot;&gt;x&lt;/em&gt;&lt;/h1&gt;';<br />
var d = $(s);<br />
alert(d.html());<br />
}();</span></p>
<p><strong>FF中的结果为：</strong></p>
<p>&lt;em class=&quot;a_b c&quot; style=&quot;min-height: 50px;&quot;&gt;x&lt;/em&gt;</p>
<p>&quot;_height:50px;&quot; 部分不见了。</p>
<p><strong>IE下的结果为：</strong></p>
<p>&lt;EM class=&quot;a_b c&quot; style=&quot;MIN-HEIGHT: 50px; HEIGHT: 50px&quot;&gt;x&lt;/EM&gt;</p>
<p>&quot;_&quot; 不见了。</p>
<p>&nbsp;</p>
<p>遇到此BUG的同学可以将inline的style改成className的方式来处理一下。</p>
<p><strong>JQuery Bug Report:</strong> <a href="http://forum.jquery.com/topic/transform-bug-in-html-string" target="_blank">http://forum.jquery.com/topic/transform-bug-in-html-string</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=301</link>
			<title><![CDATA[苏州太湖之行]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[My Life]]></category>
			<pubDate>Thu,17 Jun 2010 23:05:13 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=301</guid>
		<description><![CDATA[<p>苏州，一路过去，半山半水，鱼米之乡的感叹油然而出，悠然、大气的太湖更是让人无法一窥全貌，朦胧如出浴的妃子。</p>
<p><img alt="苏州太湖" src="http://www.w3cgroup.com/attachments/month_1006/s201061723823.jpg" /></p>
<p>&nbsp;<img alt="苏州太湖" src="http://www.w3cgroup.com/attachments/month_1006/n201061723834.jpg" /></p>
<p>&nbsp;在某开心农场做了本次Off-Site的课外活动，对很久木有外出的大家来说，景致真的不错！</p>
<p><img alt="苏州绿光开心农场" src="http://www.w3cgroup.com/attachments/month_1006/b2010617231012.jpg" /></p>
<p><img alt="农场中的卡丁车赛场" src="http://www.w3cgroup.com/attachments/month_1006/j2010617231325.jpg" /></p>
<p><img alt="农场水渠" src="http://www.w3cgroup.com/attachments/month_1006/y2010617231411.jpg" /></p>
<p><img alt="农场沙滩" src="http://www.w3cgroup.com/attachments/month_1006/o2010617231440.jpg" /></p>
<p><img alt="农场果园" src="http://www.w3cgroup.com/attachments/month_1006/02010617231518.jpg" /></p>
<p><img alt="农场林荫小道" src="http://www.w3cgroup.com/attachments/month_1006/q2010617231546.jpg" /></p>
<p><img alt="农场葡萄架" src="http://www.w3cgroup.com/attachments/month_1006/h2010617231616.jpg" /></p>
<p><img alt="农场中红透的李子" src="http://www.w3cgroup.com/attachments/month_1006/g2010617231648.jpg" /></p>
<p><img alt="结满果实的梨树" src="http://www.w3cgroup.com/attachments/month_1006/l2010617231735.jpg" /></p>
<p><img alt="金黄色的琵琶" src="http://www.w3cgroup.com/attachments/month_1006/k2010617231820.jpg" /></p>
<p>本次Off-Site课外活动的集合点</p>
<p><img alt="Cisco WebEx Off-Site Kick Off" src="http://www.w3cgroup.com/attachments/month_1006/i2010617231858.jpg" /></p>
<p>晚上的篝火晚会灰常热闹，不过火焰太大，好热!</p>
<p><img alt="" src="http://www.w3cgroup.com/attachments/month_1006/3201061723213.jpg" /></p>
<p>苏州真的不错！^_^</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=300</link>
			<title><![CDATA[Freemarker风格的JavaScript模板引擎EasyTemplate]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Sat,05 Jun 2010 16:32:45 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=300</guid>
		<description><![CDATA[<h2>在前后端分离的解决方案中，模板起到了重要作用！</h2>
<p>在使用Struts或Spring的后端中，使用Freemarker模板作为载体，能够非常有效的实现前后端的分离。</p>
<p>有人或许会认为使用前端模板一样可以实现此效果，而且实现的会更好。</p>
<p>如果单纯从技术和实现的角度去考虑，确实是使用前端模板效果会更好，前后端分离的会更彻底，但如果真的这样做，任何地方都采用前端模板去渲染，那这样的WEB应用将会失去高可靠性及易用性。</p>
<p>我们的建议是，一般的页面由后端模板渲染，页面中的某些特殊模组，可以由前端模板进行渲染，比如，一个具有诸多交互且内容不断变化的数据列表。</p>
<h3>在使用过Freemarker模板后，感觉它的语法比较朴实，平易近人，容易上手，于是决定按它的语法风格实现一个前端的模板引擎，这就有了下面的EasyTemplate!</h3>
<p>EasyTemplate模板的<strong>函数大小为1.34k</strong>（未压缩），暂时只<strong>实现了list，list index，if elseif&nbsp;else</strong>等功能，应该可以满足大部分的使用需求了。</p>
<p>EasyTemplate模板引擎的解析速度测试，渲染1000行数据，在不同的浏览器中，平均速度大约在<strong>30毫秒以内</strong>（测试机器性能较弱）。</p>
<h3>EasyTemplate可用标签：</h3>
<p><span style="background-color: Yellow;">&lt;#et tname dataname&gt; //模板开始标签，tname为此模板的名称，dataname为此模板中用到的数据名称<br />
</span></p>
<p><span style="background-color: Yellow;">&lt;#if (condition)&gt;</span><span style="background-color: Yellow;"><br />
<br />
&lt;#elseif (condition)&gt;<br />
<br />
&lt;#else&gt;<br />
<br />
&lt;/#if&gt;</span></p>
<p><span style="background-color: Yellow;">${x?a:b} //三元表达式，最后不能加分号&quot;；&quot; 注意：在所有的 {} 中都不能出现分号！<br />
</span></p>
<p><span style="background-color: Yellow;">&lt;#list List as list&gt; //遍历一个数组对象<br />
<br />
${list_idx} //在此次遍历中的当前索引<br />
<br />
${list.xxx} //取值<br />
<br />
&lt;/#list&gt; //结束遍历</span></p>
<p><span style="background-color: Yellow;">&lt;/#et&gt; //模板结束标签</span></p>
<p>&nbsp;</p>
<h3>调用方法：</h3>
<p><strong><span style="background-color: Lime;">var x = easyTemplate(sTemplate,oData);</span></strong></p>
<p>&nbsp;</p>
<p>EasyTemplate模板引擎函数下载：<a href="http://www.easyui.org.cn/easyTemplate.js" target="_blank">http://www.easyui.org.cn/easyTemplate.js</a></p>
<p>EasyTemplate模板引擎在线演示：<a href="http://www.easyui.org.cn/easyTemplate.html" target="_blank">http://www.easyui.org.cn/easyTemplate.html</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=299</link>
			<title><![CDATA[离线存储解决方案分析实现]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Thu,13 May 2010 16:05:31 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=299</guid>
		<description><![CDATA[<p>随着HTML5的呼声逐渐增大，是时候将其中的<strong>DOM Storage</strong>纳入考量范围了。</p>
<h2>DOM Storage</h2>
<p>类似http session和cookies的两种全新机制：</p>
<p><strong>Session Storage</strong></p>
<ul>
    <li>会话存储是针对用户执行单个事务的方案而设计的。</li>
    <li>应用于用户在同一时间（同一个会话期）跨多窗口运行同一事务的场景。</li>
    <li>来自MDC的说法:它常用于临时存储那些需要保存的数据以便当浏览器不小心刷新时能够恢复它们。</li>
    <li>它含有一个在页面会话有效期内可用的存储区域。</li>
    <li>只要页面没有关闭，一个页面会话就始终保持着，并且当页面被重新载入或恢复时&ldquo;复活&rdquo;。</li>
    <li>打开一个新的标签页或新窗口都会初始化新的会话。</li>
    <li>Internet Explorer 8:不会在浏览器故障得到恢复后继续使用 sessionStorage。</li>
    <li>Firefox也木有实现介个功能，参见：bug 33945 https://bugzilla.mozilla.org/show_bug.cgi?id=339445</li>
</ul>
<p><br />
Cookies不能很实时的处理这些情形：<br />
<em><br />
如，某个用户在某站点购买机票时打开了两个不同的窗口，如果该站点使用cookies来记录用户的购买信息，那么，该用户在一个窗口中&ldquo;已购买&rdquo;的机票信息可能在另一个窗口中就被&ldquo;漏&rdquo;掉了，这将导致该用户在另一个窗口中得不到实时通知的情况下购买两张相同航班的机票。</em><br />
<br />
sessionStorage接口的定义正是为了解决此情形，一个站点可以将它的数据添加到session storage，然后，该站点在某窗口中打开的任何页面都可以访问到此数据。<br />
<br />
<strong>Local Storage</strong></p>
<ul>
    <li>本地存储机制跨多个窗口，且持续范围可超过当前会话。localStorage属性可为域提供持久存储区域。</li>
    <li>它可使得WEB程序能够存储MB级的用户数据，如，存储整个用户签名档或用户的收件箱。</li>
    <li>它也为客户端性能的优化提供了一种解决方案。</li>
</ul>
<p><br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Cookies还是不能很好地处理这些情形，因为它每次请求时都会将值传送给服务器，而且数据会过期。<br />
<br />
<strong>每个站点都会有它们各自的存储区域。</strong><br />
<br />
<strong>Storage对象接口定义</strong><br />
<br />
<strong>constructor:</strong><br />
&nbsp;&nbsp;&nbsp; 返回Storage对象的构造器引用（Object）<br />
<br />
<strong>remainningSpace:</strong><br />
&nbsp;&nbsp;&nbsp; 返回Storage对象中剩余的内存数量（Bytes）<br />
<br />
<strong>length:</strong><br />
&nbsp;&nbsp;&nbsp; 返回当前Storage对象中key/value配对列表的长度，只读，数字类型<br />
<br />
<strong>key(n):</strong><br />
&nbsp;&nbsp;&nbsp; 返回当前Storage对象中key/value配对列表的第N个元素的key值，如果N&gt;=length，则返回null<br />
<br />
<strong>getItem(key):</strong><br />
&nbsp;&nbsp;&nbsp; 返回当前Storage对象中给定的key值（复制的）<br />
<br />
<strong>setItem(key, value):</strong><br />
&nbsp;&nbsp;&nbsp; 复制一份给定的value（不支持包含ImageData的对象，报NOT_SUPPORTED_ERR）<br />
&nbsp;&nbsp;&nbsp; 检测在当前Storage对象list中是否存在指定的key：<br />
&nbsp;&nbsp;&nbsp; 如果不存在，则在该list中插入此key/value的配对。<br />
&nbsp;&nbsp;&nbsp; 如果存在，则更新此key的value。<br />
&nbsp;&nbsp;&nbsp; 如果操作失败，则报空间不足（QUOTA_EXCEEDED_ERR）异常。<br />
<br />
<strong>removeItem(key):</strong><br />
&nbsp;&nbsp;&nbsp; 从当前Storage对象中移除指定的key值<br />
<br />
<strong>clear():</strong><br />
&nbsp;&nbsp;&nbsp; 清空当前Storage对象中所有的key/value<br />
<br />
<strong>sessionStorage对象</strong></p>
<ul>
    <li>sessionStorage作为Storage对象的实例，存在于浏览器全局作用域中，同源共用。</li>
    <li>全局对象，可通过sessionStorage或window.sessionStorage访问。</li>
    <li>生存周期为一个窗口或一个TAB的生存期间所加载的所有同源页面。</li>
    <li>session storage存储的内容只在用户请求的数据被删除或者存储空间不足时才会被设置过期。</li>
    <li>当sessionStorage调用setItem,removeItem或clear方法并成功执行时，所有打开的窗口中的sessionStorage都会</li>
    <li>被指向到相同的存储区域，且都会触发Storage对象的相应事件。</li>
</ul>
<p><br />
<strong>localStorage对象</strong></p>
<ul>
    <li>localStorage对象作为Storage对象的实例，存在于浏览器全局作用域中，同源共用。</li>
    <li>每个域和子域都具有自己单独的本地存储区域。 域可以访问子域的存储区域，而子域也可以访问父域的存储区域。</li>
    <li>注意：http://example.com域无法访问https://example.com中的localStorage数据。</li>
    <li>localStorage['example.com']&nbsp; 可由 example.com 及其任何子域访问。</li>
    <li>子域 localStorage['www.example.com']可由 example.com 访问，但不能由其他子域访问，如 mail.example.com。</li>
    <li>全局对象，可通过localStorage或window.localStorage访问。</li>
    <li>local storage存储的内容只有在用户提出请求或出于安全因素处理时才会被设置过期。</li>
</ul>
<p><br />
<strong>安全提示</strong></p>
<ol>
    <li>当请求违反存储限制时，抛出SECURITY_ERR异常（如用户设置不允许存储数据）。</li>
    <li>磁盘配额限制将施加于设置相应值的页面所在的域，而不是施加于在其中设置相应值的域。 这可防止恶意脚本用尽相关域的存储配额。 同时还可阻止此类脚本使用随机子域来存储无限数量的数据。</li>
    <li>如果来自非同源（源由协议、主机名（或 IP 地址）和域的 URL 的端口号确定）的脚本，抛出SECURITY_ERR异常并忽略其他步骤。</li>
    <li>如果文档来源不属于HTML5源时，抛出SECURITY_ERR异常并忽略其他步骤。</li>
    <li>存储在Storage中的数据未经过任何编码和加密，建议在使用的时候不要将敏感的重要的用户数据存储在Storage中。</li>
</ol>
<p>当浏览器切换到private模式时（如果可以的话），localStorage存储的数据在浏览器模式改变后将被丢弃。</p>
<p>当localStorage调用setItem,removeItem或clear方法并成功执行时，所有打开的窗口中的localStorage都会被指向到相同的存储区域，且都会触发Storage对象的相应事件。<br />
<br />
<strong>Storage事件（实现者）</strong><br />
<br />
当一个存储区域发生改变时，Storage事件即被触发，所有窗口中的Storage对象都将被影响。<br />
<br />
<strong>事件定义</strong><br />
<br />
<strong>initStorageEvent():</strong><br />
&nbsp;&nbsp;&nbsp; 使用类似DOM Events接口的方式初始化事件<br />
<br />
<strong>key:</strong><br />
&nbsp;&nbsp;&nbsp; 表示key被改变<br />
<br />
<strong>oldValue:</strong><br />
&nbsp;&nbsp;&nbsp; key被改变之前的值<br />
<br />
<strong>newValue:</strong><br />
&nbsp;&nbsp;&nbsp; key改变之后的值<br />
<br />
<strong>url:</strong><br />
&nbsp;&nbsp;&nbsp; 表示该地址文档对象中的key被改变<br />
<br />
<strong>storageArea:</strong><br />
&nbsp;&nbsp;&nbsp; 影响到的Storage对象<br />
<br />
<strong>DOM Storage Events（IE8+）</strong><br />
<br />
当更新存储区域中的数据时，Internet Explorer 将触发相应事件，以便在浏览器或选项卡的多个实例之间能够保持信息同步。<br />
<br />
<strong>onstorage</strong></p>
<ul>
    <li>当存储区域发生更改时，document&nbsp; 中将触发&nbsp; onstorage 事件。</li>
    <li>所有共享相同会话上下文的文档，以及当前显示来自相同域或子域（即，本地存储将要提交到的域或子域）的页面的文档，都会接收到该事件。</li>
    <li>如果目标文档对象当前未处于活动状态，则 Internet Explorer 不会触发任何事件。</li>
</ul>
<p><br />
<strong>onstoragecommit</strong></p>
<ul>
    <li>Internet Explorer 使用 XML 文件来存储本地存储数据。 将本地存储数据写入到磁盘上时，将触发&nbsp; onstoragecommit 事件。</li>
</ul>
<p>&nbsp;&nbsp;&nbsp; <br />
<strong>磁盘空间</strong></p>
<p>每个域默认可以存储 <strong>5 MB</strong> 的数据，当超过时，需要提醒用户是否增加空间。<br />
IE8+浏览器默认为 10 MB<br />
<br />
<strong>userData Behavior</strong><br />
<br />
IE5+支持，允许对象存储数据在用户端<br />
<br />
使用条件，<strong>为某对象设置behavior样式</strong><br />
<br />
<strong>html:</strong><br />
&nbsp;&nbsp;&nbsp; &lt;ELEMENT&nbsp; STYLE=&quot;behavior:url('#default#userData')&quot; ID=sID&gt;</p>
<p><strong>scripting:</strong><br />
&nbsp;&nbsp;&nbsp; object.style.behavior = &quot;url('#default#userData')&quot;<br />
&nbsp;&nbsp;&nbsp; object.addBehavior(&quot;#default#userData&quot;)<br />
<br />
<strong>userData对象成员表</strong><br />
<br />
<strong>expires:</strong><br />
&nbsp;&nbsp;&nbsp; 设置或返回userData的到期时间<br />
<br />
<strong>XMLDocument:</strong><br />
&nbsp;&nbsp;&nbsp; 返回一个XML引用<br />
<br />
<strong>load(user):</strong><br />
&nbsp;&nbsp;&nbsp; 加载指定user存储在userData中的数据对象<br />
<br />
<strong>getAttribute(attr):</strong><br />
&nbsp;&nbsp;&nbsp; 返回指定attr的值<br />
<br />
<strong>setAttribute(attr):</strong><br />
&nbsp;&nbsp;&nbsp; 设置指定attr的值<br />
<br />
<strong>removeAttribute(attr):</strong><br />
&nbsp;&nbsp;&nbsp; 移除指定的attr值<br />
<br />
<strong>save(user):</strong><br />
&nbsp;&nbsp;&nbsp; 保存指定user的数据对象到userData中<br />
<br />
<strong>磁盘空间</strong><br />
<br />
<strong>本地：</strong><br />
&nbsp;&nbsp;&nbsp; document limit:128KB，domain limit:1024KB<br />
<strong>局域网：</strong><br />
&nbsp;&nbsp;&nbsp; document limit:512KB，domain limit:10240KB<br />
<strong>可信站点：</strong><br />
&nbsp;&nbsp;&nbsp; document limit:128KB，domain limit:1024KB<br />
<strong>互联网：</strong><br />
&nbsp;&nbsp;&nbsp; document limit:128KB，domain limit:1024KB<br />
<strong>受限站点：</strong><br />
&nbsp;&nbsp;&nbsp; document limit:64KB，domain limit:640KB<br />
<br />
<strong>安全提示</strong></p>
<ol>
    <li>为了安全考虑，userData存储的数据只对相同的目录，且使用相同的协议才能访问。</li>
    <li>存储在userData中的数据未经过任何编码和加密，建议在使用的时候不要将敏感的重要的用户数据存储在userData中。</li>
    <li>将userData行为应用在html,head,title,style等对象上时，使用save和load方法时将会发生错误。</li>
</ol>
<p><br />
<br />
<strong>Adobe Flash Player本地存储</strong><br />
存储空间: 100 KB<br />
<br />
<strong>Cookie</strong><br />
存储空间: 4 KB<br />
<br />
<a href="http://www.easyui.org.cn/domStorage.html" target="_blank">简单实现一个兼容新老浏览器的离线存储演示，简单判断是否可用localStorage，否则使用cookie.</a><br />
<br />
在线演示DEMO：<a href="http://www.easyui.org.cn/domStorage.html" target="_blank">http://www.easyui.org.cn/domStorage.html</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=298</link>
			<title><![CDATA[客户端环境诊断为解决用户遇到的问题做好准备]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Tue,11 May 2010 11:15:53 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=298</guid>
		<description><![CDATA[<p>记得以前和<em><strong> <a href="http://www.blogjava.net/emu/" target="_blank">EMU</a></strong></em>  同学聊天的时候，他提到最多的话题就是如何处理用户咨询和投诉，从而较好的解决他们遇到的问题。</p>
<p>当一个产品的用户数量达到一个很大 的数量级时，这种情况确实会经常发生，若不能有效的解决，的确让产品工程师们很困扰。</p>
<p>在<a href="http://www.baiduux.com/" target="_blank"><em><strong>百 度泛用户体验博客</strong></em></a>中，百度有啊的同学分享了他们是怎么来处理这种情况的，那就是，提供一个客户端环境诊断的小工具 （页面），让用户配合工程师一起进行诊断，为处理用户遇到的问题提供较有价值，较全面的资料。</p>
<p>原文如下：</p>
<p><span class="author">作者：<a title="由 Miller
发表" href="http://www.baiduux.com/blog/author/chenminliang/">Miller</a></span></p>
<p><a target="_blank" href="http://co.youa.baidu.com/content/qmrIO0W0Ep43TjA/weddiagnose/index.html">有啊网页诊断工具</a>是一个轻量级的浏览器环境检测工具，基于Javascript以及Flash实现。它的主要 功能包括问题检测以及针对某些问题给予提示性的建议，从而帮助用户自助的解决一些简单的问题。此外还能生成简单的检测报告，通过报告开发人员可是获得更为 详细的环境信息，为解决问题提供有效的支持。</p>
<p>该工具具体的检测项包括以下几个：</p>
<p>1. Javascript版本信息<br />
2. Cookie是否开启<br />
3. 用户的屏幕分辨率<br />
4. Flash版本号以及浏览器是否开启了Flash拦截功能<br />
5. 浏览器字体大小是否正常（某些浏览器缩放后会导致页面布局混乱）<br />
6. 浏览器的Ajax功能是否正常，包括Get方式和Post方式<br />
7. 浏览器的图片浏览功能是否正常<br />
8. 用户的网络速度</p>
<p>通过对以上几个问题的检测，开发人员能够比较全面的了解目标浏览器的整体环境。</p>
<p>&nbsp;</p>
<h3>一、Javascript版本检测</h3>
<p>对于Javascript版本的检测似乎显得不是那么必要，因为通常都可以根据浏览器的版本找到对应关系，不过作为浏览器环境的一部分，还是把该功  能加了进来。具体的实现原理：在页面中嵌入各个版本的script标签，并在每个标签中都给同一个全局变量赋值，最后根据变量的值得到版本号：</p>
<pre><!--mce:0--> &nbsp;&nbsp;&nbsp;&nbsp;
 JS_VERSION=('1.0');&nbsp;&nbsp;&nbsp;&nbsp;

 &nbsp;&nbsp;&nbsp;&nbsp;
 JS_VERSION=('1.1');&nbsp;&nbsp;&nbsp;&nbsp;

 &nbsp;&nbsp;&nbsp;&nbsp;
 JS_VERSION=('1.2');&nbsp;&nbsp;&nbsp;&nbsp;

      ......
      ......
 <!--mce:3-->&nbsp;&nbsp; &nbsp;
 JS_VERSION=('1.3');&nbsp;&nbsp; &nbsp;

 &nbsp;&nbsp; &nbsp;
 window.onload = function(){
 if( typeof JS_VERSION != 'undefined' )
 document.getElementById('test').innerHTML = JS_VERSION;
 }&nbsp;&nbsp; &nbsp;
  <!--mce:4-->
</pre>
<p>根据W3C规范，script的language属性已经被废弃了，不过经测试该属性的兼容性较好，并能得到比较准确的结果。如果使用type=  &ldquo;text/javascriptN&rdquo;则在很多浏览器下得不到正确的版本，因此在此依然使用了language属性。另外，关于javascript各个 版本与浏览器的对应关系可以参考如下表格：</p>
<table border="1">
    <tbody>
        <tr>
            <th>Version</th>
            <th>Release date</th>
            <th>Equivalent to</th>
            <th>Netscape<br />
            Navigator</th>
            <th>Mozilla<br />
            Firefox</th>
            <th>Internet<br />
            Explorer</th>
            <th>Opera</th>
            <th>Safari</th>
            <th>Google<br />
            Chrome</th>
        </tr>
        <tr>
            <td>1.0</td>
            <td>March 1996</td>
            <td>&nbsp;</td>
            <td>2.0</td>
            <td>&nbsp;</td>
            <td>3.0</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>1.1</td>
            <td>August 1996</td>
            <td>&nbsp;</td>
            <td>3.0</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>1.2</td>
            <td>June 1997</td>
            <td>&nbsp;</td>
            <td>4.0-4.05</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>1.3</td>
            <td>October 1998</td>
            <td>ECMA-262 1<sup>st</sup> edition / ECMA-262 2<sup>nd</sup> edition</td>
            <td>4.06-4.7x</td>
            <td>&nbsp;</td>
            <td>4.0</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>1.4</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>Netscape<br />
            Server</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>1.5</td>
            <td>November 2000</td>
            <td>ECMA-262 3<sup>rd</sup> edition</td>
            <td>6.0</td>
            <td>1.0</td>
            <td>5.5 (JScript 5.5),<br />
            6 (JScript 5.6),<br />
            7 (JScript 5.7),<br />
            8 (JScript 6)</td>
            <td>6.0,<br />
            7.0,<br />
            8.0,<br />
            9.0,<br />
            10.0</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>1.6</td>
            <td>November 2005</td>
            <td>1.5 + Array extras + Array and String generics + E4X</td>
            <td>&nbsp;</td>
            <td>1.5</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>3.0, 3.1</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>1.7</td>
            <td>October 2006</td>
            <td>1.6 + Pythonic generators + Iterators + let</td>
            <td>&nbsp;</td>
            <td>2.0</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>3.2, 4.0</td>
            <td>1.0</td>
        </tr>
        <tr>
            <td>1.8</td>
            <td>June 2008</td>
            <td>1.7 + Generator expressions + Expression closures</td>
            <td>&nbsp;</td>
            <td>3.0</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>1.8.1</td>
            <td>&nbsp;</td>
            <td>1.8 + Native JSON support + Minor Updates</td>
            <td>&nbsp;</td>
            <td>3.5</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>1.8.2</td>
            <td>&nbsp;</td>
            <td>1.8.1 + Minor updates</td>
            <td>&nbsp;</td>
            <td>3.6</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>1.9</td>
            <td>&nbsp;</td>
            <td>1.8.1 + <a href="http://en.wikipedia.org/wiki/ECMAScript" title="ECMAScript"><span style="color: rgb(0, 0, 0);">ECMAScript</span></a> 5 Compliance</td>
            <td>&nbsp;</td>
            <td>4</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>相关参考资料：</p>
<p><a href="http://www.w3.org/TR/REC-html40/interact/scripts.html">http://www.w3.org/TR/REC-html40/interact/scripts.html</a>  W3C 关于script标签的描述</p>
<p><a href="http://en.wikipedia.org/wiki/JavaScript">http://en.wikipedia.org/wiki/JavaScript#Versions</a>  维基百科关于JavaScript中的版本描述</p>
<p><a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/JavaScript_Overview">https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/JavaScript_Overview</a>  JavaScript Versions and ECMAScript Editions</p>
<p><a href="http://hi.baidu.com/jiaozhenqing/blog/item/d8f026380392f22cb9998fc7.html">http://hi.baidu.com/jiaozhenqing/blog/item/d8f026380392f22cb9998fc7.html</a>  JavaScript版本一览</p>
<h3>二、检测Cookie是否开启</h3>
<p>先获取window.navigator['cookieEnabled']的值，如果该值非undefined的话则直接使用该值即可判断(经测  试IE7、Firefox3.5、Safari4、Opera10均能支持)。如果为undefined(即不支持该属性）则使用如下的方式：尝试向  Cookie中写入数据（为避免浪费设置1分钟的有效期），写入后检测document.cookie中是否存在刚才写入的数据，如果有则cookie有  效否则cookie无效：</p>
<pre>
 var cookie = document.cookie;
 var cookieEnabled = window.navigator['cookieEnabled'];

 if(typeof cookieEnabled == 'undefined'){
    var expireDate = new Date();
    expireDate.setTime(expireDate.getTime() + 1000);//Expired after 1 second
    var time = expireDate*1;
    var regExp = new RegExp(time + '=' + time);
    document.cookie = time + '=' + time + ';expires=' + expireDate.toGMTString();
    if( regExp.test(document.cookie) )
       cookieEnabled = true;
    else
       cookieEnabled = false;
 }
</pre>
<h3>三、Flash版本以及可用性检测</h3>
<p>Flash检测包含两方面的内容：</p>
<h4>1. Flash是否安装、禁用，Flash版本号</h4>
<p>对于Flash的版本检测可以通过在页面中引入AC_OETags.js（包含在Adobe官方的<a href="http://www.adobe.com/products/flashplayer/download/detection_kit/">Flash   Player Detection Kit</a>中），然后通过调用其中的GetSwfVer方法获得具体的版本号，如果Flash未安装或者被禁用 则  GetSwfVer方法将会返回-1，否则返回正确的版本号。查看GetSwfVer的实现，与浏览器版本检测如出一辙，也是通过navigator信息  得到的，感兴趣的可以直接查看其源码。</p>
<h4>2. 如果Flash已经安装是否被拦截</h4>
<p>做这一步检查的前提是第一步能够获得正确的版本号。具体的检测方法也很简单，在页面中引入一个自定义的swf文件，在该swf文件中只定义  了一个方法checkFlash，并将该方法暴露出来使得JavaScript能够访问到，即  ExternalInterface.addCallback(&ldquo;checkFlash&rdquo;,checkFlash);在swf加载完成后通过 JavaScript访问checkFlash方法，如 果存在该方法则说明Flash访问正常，否则Flash可能被拦截了。</p>
<p>以上两步的代码实现大致如下：</p>
<p>HTML代码</p>
<pre>
&nbsp;</pre>
<p>Javascript代码</p>
<pre>
    //获取Flash版本号，如果version为-1则可能未安装Flash或者Flash被禁用
    var version = GetSwfVer();
    if( version != -1 ){
         var isIE = navigator.appVersion.indexOf(&quot;MSIE&quot;) != -1;
         if( isIE )//IE下取Object元素
            var swfObj = document.getElementById('oCheck');
        else//其他浏览器下取embed元素
            var swfObj = document.getElementById('eCheck');
        if( !swfObj.checkFlash ) {
            //被拦截
        }
        else {
           //未拦截
        }
    }
    else{
        //未安装Flash Player或者Flash Player被禁用
    }</pre>
<div>参考资料</div>
<div><a href="http://www.adobe.com/products/flashplayer/download/detection_kit/">http://www.adobe.com/products/flashplayer/download/detection_kit/</a>  Flash Player Detection Kit</div>
<p>&nbsp;</p>
<h3>四、Ajax功能检测</h3>
<p>该功能的检测比较直接，即分别构造Ajax Get和Ajax  Post请求，在请求过程中详细的记录Ajax的实例类型（ActiveXObject 或  XMLHTTPRequest）、请求的各个阶段的状态以及最终的请求结果。</p>
<h3>五、检测图片是否被禁用</h3>
<p>检测图片是否禁用的原理：新建一个Image对象，并监听其onload事件（IE某些版本中无效，需要监听onreadystatechange  事件）以及onerror事件。</p>
<pre>
 var img = new Image;
 //监听onload事件，由于在ie的某些版本中onload事件并不会被触发，因此增加onreadystatechange监听器
 img.onload = img.onreadystatechange = function(){
 //加载成功说明图片功能是正常的
 }
 //监听onerr事件
 img.onerror = function(){
 //如果触发了onerror事件，则说明图片功能不正常（在img的src正确的情况下）
 }
 img.src = 'xxx';</pre>
<p>以上的实现中，对于加载事件的监听并没有什么问题，不过对于onerror事件还是存在比较大的兼容性问题：经测试发现，在IE下禁用图片后并不会 触发  onerror事件，而在Firefox中禁用图片后则能正常的触发onerror事件，至此的结论是使用onerror来判断图片功能是准确的。取而代  之的是使用超时检测来判断，即假定图片在一定时间内仍未能加载成功则视为失败。</p>
<pre>
 var img = new Image;
 //监听onload事件，由于在ie的某些版本中onload事件并不会被触发，因此增加onreadystatechange监听器
 img.onload = img.onreadystatechange = function(){
 //加载成功说明图片功能是正常的
 }
 //监听onerr事件
 img.onerror = function(){
 //如果触发了onerror事件，则说明图片功能不正常（在img的src正确的情况下）
 }
 img.src = 'xxx';
 var timer = setTimeout(function(){
 //如果执行到这里则认为图片功能异常
 },TIMEOUT);</pre>
<h3>六、检测网络速度</h3>
<p>实现原理：请求一张已知大小的图片N次，并分别记录每次请求所花费的时间，最后根据图片大小计算出平均的网络速度。这里需要注意的是图片的大小问 题，图片如果太小结果会不准确，需要选择一张合适的图片，另外为防止图片被浏览器缓存需要给图片的src添加时间戳。</p>
<pre>
/*
 * @param { Integer } times 请求图片的次数
 * @callback { Function } callback 图片请求完成后调用的函数
 */
 function detectNetSpeedWithImage(times,callback){&nbsp;&nbsp; &nbsp;
 times = times || 1;
 //已完成请求
 var completedImg = 0,
 res = [],
 timer = null,
 done = false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;
 for( var i = 0; i &lt; times; i++){
 (function( index ){
 setTimeout(function(){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;
 var img = new Image();
 //开关，在某些浏览器（如IE）会响应两次onreadystatechange
 var loaded = false;
 //请求开始时间
 var tStart = new Date();
 img.onload = img.onreadystatechange = function(){
 if( loaded ) return;
 //请求结束时间
 var tEnd = new Date();
 res.push(tEnd - tStart);
 //已完成请求加1
 completedImg++;
 loaded = true;
 //全部请求完成后调用callback
 if( completedImg == times &amp;&amp; callback ){
 callback.call(null,res);
 if( timer ) clearTimeout(timer);
 }
 }
 img.onerror = function(){
 if( done ) return;
 callback([]);
 done = true;
 clearTimeout(timer);
 }
 img.src = Config.NET_SPEED_DETECT_IMAGE_URL + '?t=' + (new Date())*1;
 },index * Config.NET_SPEED_DETECT_IMAGE_REQUEST_INTERVAL);
 })(i);
 }
 //超时操作
 timer = setTimeout(function(){
 if( completedImg != times &amp;&amp; !done ){
 callback([]);
 }
 },Config.NET_SPEED_DETECT_TIMEOUT + times * Config.NET_SPEED_DETECT_IMAGE_REQUEST_INTERVAL);
 }

 detectNetSpeedWithImage(Config.NET_SPEED_DETECT_TIMES,function(res){
 //失败
 if( res.length &lt; 1 ){
 _handleError();
 }
 //成功
 else{
 var time = 0;
 for( var i = 0,l = res.length; i &lt; l; i++){
 time += res[i] / ( l * 1000 );
 }
 //计算速度
 var speed = Config.NET_SPEED_DETECT_IMAGE_SIZE / time;
 //取小数点后两位
 speed = speed.toFixed(2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 me.isOver = true;&nbsp;&nbsp; &nbsp;
 }
 });</pre>
<h3>七、检测客户端分辨率</h3>
<p>直接获取window.screen的width与height即可。</p>
<h3>八、检测浏览器字体大小是否正常</h3>
<p>在IE6下，当使用px作为单位时，元素（字体大小）无法进行缩放，这在很多情况下都会造成页面混乱。另外，对于目前大多数浏览器，在默认字体设置 下，1em恰恰等于16px，于是可以根据这个原理来检测浏览器字体是否正常，具体的方式如下：</p>
<p>1.   创建一个DIV元素1，并设定其高为16px，宽为1px并使用CSS将其定位到可视范围之外（不能通过display或visibility隐藏）</p>
<p>2.   创建另一个DIV元素2，并设置其font-size为medium。在该DIV内部创建一个DIV元素3，并设置其高位1em，宽为1px并使用CSS 将其定位到可视范围之外</p>
<p>3. 比较元素1和元素3的高度，如果相等则字体大小正常否则异常</p>
<p>注意，元素3必须包含在元素2中，并且给元素2设置font-size:   medium。因为em是一个相对单位，1em的大小相当于其父元素字体的大小，为了使检测不受其他样式影响，将其放在一个字体大小为浏览器默认值的容器 中。</p>
<pre>
 //隐藏DIV的CSS
 var hideCSS = 'position:absolute;left:-2000px;';

 //以px为宽度单位的元素
 var pxBlock = document.createElement('div');
 pxBlock.style.cssText = 'width:16px;height:1px;' + hideCSS;
 document.body.appendChild(pxBlock);
 //构建一个字体大小为浏览器默认值的容器
 var emBlockWrapper = document.createElement('div');
 emBlockWrapper.style.fontSize = 'medium';

 //以em为字宽度单位的元素
 var emBlock = document.createElement('div');
 emBlock.style.cssText = 'width:1em;height:1px;' + hideCSS;

 emBlockWrapper.appendChild(emBlock);
 document.body.appendChild(emBlockWrapper);

 //获得固定和变化的div宽度
 var pxBlockWidth = pxBlock.offsetWidth;
 var emBlockWidth = emBlock.offsetWidth;

 if(pxBlockWidth == emBlockWidth){
 //字体正常
 }
 else{
 //字体异常
 }</pre>
<p>&nbsp;</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=297</link>
			<title><![CDATA[在WEB开发中怎样的代码才是可维护性高的代码]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Wed,05 May 2010 09:59:33 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=297</guid>
		<description><![CDATA[<h2>&ldquo;大道至简，返璞归真&quot;</h2>
<p>在看到<a href="http://www.nczonline.net/" target="_blank">Nicholas C. Zakas</a>提出的<strong>可维护性的代码</strong>的观点后，这种感觉越发的强烈！</p>
<p>原文出处：</p>
<p><a href="http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/" target="_blank">http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/</a></p>
<h3>可维护的Javascript代码</h3>
<p>当我们在开发WEB程序时，如何保证代码的可维护性？很简单，<strong>不要修改不是自己定义的对象</strong>。</p>
<h3>为什么不可以去修改不属于自己定义的对象？</h3>
<p>当我们去修改一个已有的并非我们自己定义的对象时，将发生多么糟糕的事情：</p>
<ul>
    <li><strong>不可信任，导致混乱</strong><br />
    <br />
    这样的修改不可信任，很有可能之前使用过此对象的地方发生BUG<br />
    &nbsp;</li>
    <li><strong>不兼容</strong><br />
    <br />
    在修改这些对象时，我们很可能会将一些新的方法添加进去，而没有考虑到这个对象很可能被应用在并没有实现这些方法的环境中<br />
    &nbsp;</li>
    <li><strong>维护的梦魇</strong><br />
    <br />
    试想，当这种情形发生在一个大项目，大团队中，对成员间开发的代码维护将会是件多么恐怖的事情。</li>
</ul>
<h3>在WEB开发中，怎样的代码才是可维护性高的代码？</h3>
<p>有一段代码，<strong>当浏览器发生改变时，它并不需要作出任何修改</strong>，这就是可维护性高的代码！</p>
<p>在WEB开发中，这不仅适用于Javascript，同样适用于Css!</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=296</link>
			<title><![CDATA[Ajax History 实现分析]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Tue,04 May 2010 15:45:32 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=296</guid>
		<description><![CDATA[<p>最近研究了一下Ajax History的实现，目前多数的实现是用一个Timer去定时check浏览器的hash是否改变，还有一些兼容性不强的unInterval的实现。</p>
<h3>IE：</h3>
<ul>
    <li>链接到一个锚点，如果该锚点在当前页未被定义，则不能产生history</li>
    <li>页面中的iframe，如果改变其hash，href，或重新写入新的HTML内容，都会产生history</li>
    <li>对iframe产生的history进行&ldquo;向前&rdquo;，&ldquo;向后&rdquo;操作时，页面地址栏的值不会改变</li>
    <li>iframe中使用hash change的方式，在操作历史记录时会相应回滚，可以以此作为历史记录改变的触发事件</li>
    <li>页面hash的改变，无法通过location.hash获取</li>
</ul>
<h3>其他浏览器：</h3>
<ul>
    <li>链接到一个锚点，如果该锚点在当前页未被定义，也能产生history</li>
    <li>页面hash的改变，可以通过location.hash获取</li>
    <li>iframe中使用hash change的方式，在操作历史记录时不会相应回滚，没办法以此作为历史记录改变的触发事件</li>
</ul>
<h3>实现方案：</h3>
<ul>
    <li>定时检测hash的变化</li>
</ul>
<p><a target="_blank" href="http://www.easyui.org.cn/ajaxHistory.html">ajax history demo: http://www.easyui.org.cn/ajaxHistory.html</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=295</link>
			<title><![CDATA[hasLayout in Microsoft Internet Explorer]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Mon,26 Apr 2010 15:36:45 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=295</guid>
		<description><![CDATA[<h1>hasLayout Property</h1>
<hr size="1" />
<p>Retrieves a value that indicates whether the <span replace="1">object</span>   has layout.</p>
<p class="clsRef">Syntax</p>
<blockquote>
<table class="clsStd">
    <tbody>
        <tr>
            <th><b>HTML</b></th>
            <td>N/A</td>
        </tr>
        <tr>
            <th><b>Scripting</b></th>
            <td>[ <span class="clsRange">sHasLayout</span><b> =</b> ] <i><span class="moreinfo" title="an element from the Applies To list below">object</span></i>.<b>currentStyle.hasLayout</b></td>
        </tr>
    </tbody>
</table>
</blockquote>
<p class="clsRef">Possible Values</p>
<blockquote>
<table class="clsStd">
    <tbody>
        <tr>
            <td><span class="clsRange">sHasLayout</span></td>
            <td><b>Boolean</b> that receives one of the following  values.
            <table class="clsStd">
                <tbody>
                    <tr>
                        <td nowrap="nowrap"><span class="clsDefValue">false</span></td>
                        <td>Default. Object does not have layout.</td>
                    </tr>
                    <tr>
                        <td nowrap="nowrap"><span class="clsLiteral">true</span></td>
                        <td>Object has layout.</td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<p>The property is read-only. The property has a default value of <span class="clsDefValue">false</span>. The Microsoft Cascading Style Sheets  (CSS)  extension is not inherited.</p>
</blockquote>
<p class="clsRef">Remarks</p>
<blockquote>
<p>The following table shows Cascading Style Sheets (CSS) properties and   corresponding values that, if set, cause an element to have layout.
<table class="clsStd">
    <tbody>
        <tr>
            <th>CSS property</th>
            <th>Value</th>
        </tr>
        <tr>
            <td><a href="http://www.v-ec.com/dh20156/../properties/display.html">display</a></td>
            <td><span class="clsLiteral">inline-block</span></td>
        </tr>
        <tr>
            <td><a href="http://www.v-ec.com/dh20156/../properties/height_0.html">height</a></td>
            <td>any value</td>
        </tr>
        <tr>
            <td><a href="http://www.v-ec.com/dh20156/../properties/float.html">float</a></td>
            <td><span class="clsLiteral">left</span> or <span class="clsLiteral">right</span></td>
        </tr>
        <tr>
            <td><a href="http://www.v-ec.com/dh20156/../properties/position.html">position</a></td>
            <td><span class="clsLiteral">absolute</span></td>
        </tr>
        <tr>
            <td><a href="http://www.v-ec.com/dh20156/../properties/width_0.html">width</a></td>
            <td>any value</td>
        </tr>
        <tr>
            <td><a href="http://www.v-ec.com/dh20156/../properties/writingmode.html">writing-mode</a></td>
            <td><span class="clsLiteral">tb-rl</span></td>
        </tr>
        <tr>
            <td><a href="http://www.v-ec.com/dh20156/../properties/zoom.html">zoom</a></td>
            <td>any value</td>
        </tr>
    </tbody>
</table>
</p>
<p>As of Microsoft&reg; Internet Explorer 6, when the <a href="http://www.v-ec.com/dh20156/../objects/doctype.html">!DOCTYPE</a> declaration  specifies strict  standards compliance, inline elements will ignore the <b>width</b>  and  <b>height</b> properties, and setting the <b>width</b> and <b>height</b>   properties will not cause the element to have layout.</p>
<p>Setting the <a href="http://www.v-ec.com/dh20156/../properties/contenteditable.html">contentEditable</a>   property to <span class="clsLiteral">true</span> will cause an element  to have  layout.</p>
<p><strong>BODY</strong>, <strong>FIELDSET</strong>, <strong>IMG</strong>,  <strong>INPUT</strong>,  <strong>TABLE</strong> and <strong>TD</strong>  elements always have layout.</p>
<p>&nbsp;</p>
</blockquote>
<p><strong>当hasLayout为false的元素中包含了hasLayout为true的元素时，该子元素在应 用position类型的样式时将会遇到兼容问题。</strong></p>
<p>&nbsp;</p>
<p><strong>当 hasLayout为false的元素应用position类型的样式时，将会遇到兼容问题。</strong></p>
<p>&nbsp;</p>
<p>See  also:</p>
<p><a href="http://blog.doyoe.com/article.asp?id=165" target="_blank"><strong>background与 border的恩怨情仇</strong></a></p>
<p><a href="http://www.jslab.org.cn/?tag=hasLayoutBug" target="_blank"><strong>http://www.jslab.org.cn/?tag=hasLayoutBug</strong></a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=294</link>
			<title><![CDATA[重温High Performance Web Sites]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Thu,22 Apr 2010 14:36:39 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=294</guid>
		<description><![CDATA[<h2>High Performance Web Sites - yahoo14条</h2>
<p><strong>由谁提出的</strong><br />
&nbsp;&nbsp;&nbsp;  来自Yahoo! Exceptional Performance team<br />
<br />
<strong>什么时候开始发起的</strong><br />
&nbsp;&nbsp;&nbsp;  2004年开始研究，2007年4月开始，陆续发布,(5月,7月,9月)<br />
<br />
<strong>为什么</strong><br />
&nbsp;&nbsp;&nbsp;  Yahoo希望对自己的产品性能做出一些测量和改善<br />
<br />
<strong>成绩</strong><br />
&nbsp;&nbsp;&nbsp;  总结出14条提升WEB产品性能的准则（后续21条）</p>
<p>&nbsp;</p>
<h3>第一条：最小化HTTP请求(Frontend)</h3>
<p>&nbsp;&nbsp;&nbsp;  将CSS文件和JS文件合并（可行性不高）<br />
&nbsp;&nbsp;&nbsp; CSS Sprites<br />
&nbsp;&nbsp;&nbsp; Image  Maps(很久以前经常使用的&ldquo;热区&rdquo;)<br />
&nbsp;&nbsp;&nbsp; Inline Images,data:URL（浏览器兼容问题）<br />
<br />
&nbsp;&nbsp;&nbsp;  每天大概有40-60%的访问者去到我们的站点的时候都是empty cache，所以，<br />
&nbsp;&nbsp;&nbsp;  我们如果能够使得他们在第一次访问时速度更快，那对他们来说将获得很好的体验。</p>
<p>&nbsp;</p>
<h3>第二条：使用内容分发网络 (Server)</h3>
<p>&nbsp;&nbsp;&nbsp; 将静态文件分发到其他独立的服务器上。<br />
&nbsp;&nbsp;&nbsp;  目的：使得用户可以就近获取到静态文件，从而解决动态内容站点网络拥挤的状况，提高用户访问网站的响应速度。<br />
&nbsp;&nbsp;&nbsp; Performance  Golden Rule:<br />
&nbsp;&nbsp;&nbsp; 80-90%的用户响应时间都花费在了下载某个页面上的组件上，<br />
&nbsp;&nbsp;&nbsp;  如：images,stylesheets,scripts,flash等等，而这些文件都是静态的，完全可以分发出去。<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;  CDN很昂贵，可以租用，也可以退而求其次，采用部署多台Server进行反向代理</p>
<p>&nbsp;</p>
<h3>第三条：设置一个 Expires头(Server)</h3>
<p>&nbsp;&nbsp;&nbsp; 静态文件：永不过期<br />
&nbsp;&nbsp;&nbsp;  动态文件：适当设置&quot;Cache-Control&quot;头<br />
<br />
&nbsp;&nbsp;&nbsp;  现在的WEB页面设计越来越丰富，这也意味着页面上会有越来越多的script,stylesheets,images,flash等等<br />
&nbsp;&nbsp;&nbsp;  用户在第一次访问我们的站点时，会发出若干请求，但再次访问时或者继续访问其他页面时，<br />
&nbsp;&nbsp;&nbsp;  如果这些文件设置了Expires头，就可以避免再次为它们发出新的HTTP请求，<br />
&nbsp;&nbsp;&nbsp;  从而提高页面加载速度，减轻服务器压力，提升用户体验。</p>
<p>&nbsp;</p>
<h3>第四条：Gzip压缩静态文件(Server)</h3>
<p>&nbsp;&nbsp;&nbsp;  为所有静态文件开启GZip<br />
&nbsp;&nbsp;&nbsp; 压缩文件，节约带宽，提高下载速度</p>
<h3>第五条：将样式表放置在源文件的顶部 (Frontend)</h3>
<p>&nbsp;&nbsp;&nbsp; 将所有样式文件放置在接近源文件顶部的&lt;head&gt;标签内<br />
<br />
&nbsp;&nbsp;&nbsp;  页面按加载进度逐步渲染，给予访问者视觉上的反馈，尤其是内容较大，网速较慢的访问者，尤为明显。</p>
<p>&nbsp;</p>
<h3>第六 条：将Script脚本放置在源文件底部(Frontend)</h3>
<p>&nbsp;&nbsp;&nbsp;  在第二条中提到浏览器在同一主机上平行下载的进程是有限制的，HTTP/1.1规范中指定的是两个。<br />
&nbsp;&nbsp;&nbsp;  如果在页面下载进程中遇到了Scripts的下载，则它会将这种平行下载阻断，导致页面加载更慢。</p>
<p>&nbsp;</p>
<h3>第七 条：避免使用CSS表达式(Frontend)</h3>
<p>&nbsp;&nbsp;&nbsp; 不兼容<br />
&nbsp;&nbsp;&nbsp;  监听评估导致页面性能低下，移动一次鼠标可能导致超过10,000次的评估。<br />
<br />
第八条：将JavaScript和CSS全部放置到外部文件 进行调用(Frontend)<br />
&nbsp;&nbsp;&nbsp; 减小主文件大小，加快page加载速度<br />
&nbsp;&nbsp;&nbsp; 对XHTML进行兼容<br />
&nbsp;&nbsp;&nbsp;  可作为静态文件分发到CDN<br />
&nbsp;&nbsp;&nbsp; 可缓存<br />
&nbsp;&nbsp;&nbsp; 可共用</p>
<p>&nbsp;</p>
<h3>第九条：减少DNS查询 （Frontend）</h3>
<p>&nbsp;&nbsp;&nbsp; Domain Name System，域名系统，它将主机映射到某个IP地址。<br />
&nbsp;&nbsp;&nbsp;  当我们输入一个网址的时候，DNS会分析该网址，然后转换到具体的IP，这个过程大概会花20-120毫秒<br />
&nbsp;&nbsp;&nbsp;  显然，如果DNS的查找能够进行缓存，将会提高站点的访问速度。<br />
&nbsp;&nbsp;&nbsp;  当我们访问一个页面时，该页的URL，images,script,stylesheet,flash等等都会有一个DNS查询的过程<br />
&nbsp;&nbsp;&nbsp;  如果我们能够减少该页面上出现多个不同的主机地址，就可以减少DNS的查询<br />
&nbsp;&nbsp;&nbsp;  这样就会和之前讲到的平行下载有冲突，减少DNS查询会减少页面响应时间，<br />
&nbsp;&nbsp;&nbsp; 但是降低了平行下载数量，则会增大页面响应时间，<br />
&nbsp;&nbsp;&nbsp;  平衡的做法是，将所有静态文件分离到至少1个独立的主机，最多不超过4个。</p>
<p>&nbsp;</p>
<h3>第十条：最小化 JavaScript和CSS</h3>
<p>&nbsp;&nbsp;&nbsp; 将JavaScript和CSS中任何多余的字符移除，如：注释，换行，排版用的空格等等<br />
&nbsp;&nbsp;&nbsp;  减少文件大小，加速下载进度。</p>
<p>&nbsp;</p>
<h3>第十一条：避免重定向(Frontend)</h3>
<p>&nbsp;&nbsp;&nbsp;  重定向将导致用户响应时间增加<br />
&nbsp;&nbsp;&nbsp; 使用具体的URL<br />
&nbsp;&nbsp;&nbsp; 如果一定要重定向，可使用标准的3xx HTTP状态码</p>
<p>&nbsp;</p>
<h3>第 十二条：移除重复的脚本</h3>
<p>&nbsp;&nbsp;&nbsp; 使用外部脚本文件<br />
&nbsp;&nbsp;&nbsp; 引入这些脚本文件时给文件名加上版本号<br />
&nbsp;&nbsp;&nbsp;  &lt;script type=&quot;text/javascript&quot;  src=&quot;menu_1.0.17.js&quot;&gt;&lt;/script&gt;<br />
&nbsp;&nbsp;&nbsp; 养成提取公共方法，公共类的习惯<br />
&nbsp;&nbsp;&nbsp;  在编码的过程中，如果发现某段代码至少有两个地方用到，而且代码量挺大的，<br />
&nbsp;&nbsp;&nbsp;  就可以考虑将这部分代码提取成为公共的方法，在编写CSS的时候同样适用。</p>
<p>&nbsp;</p>
<h3>第十三条：配置ETag</h3>
<p>&nbsp;&nbsp;&nbsp;  ETag，Entity tags的简称，<br />
&nbsp;&nbsp;&nbsp;  它用来确定在浏览器向服务端请求一个组件时判断缓存的组件与服务器上的是否仍然还是同一份（即没有更改过）。<br />
&nbsp;&nbsp;&nbsp;  Entity，其实就是&ldquo;组件&rdquo;的另一种说法，也就是images,scripts,stylesheets等等这些东西。&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;  ETag的值由 INode（索引节点）, Size和MTime（最后修改时间）决定。<br />
&nbsp;&nbsp;&nbsp;  由于这个INode在不同的服务器上是不同的，所以导致同一个组件会有不同的ETag，<br />
&nbsp;&nbsp;&nbsp;  这就使得该组件不能发送304的状态，没有办法被用户缓存<br />
&nbsp;&nbsp;&nbsp; 由于这个原因，在大型多服务器的站点，一般建议将ETag配置关闭<br />
&nbsp;&nbsp;&nbsp;  如果可以保证各服务器对同一组件生成相同的ETag，则完全可以使用。</p>
<h3>第十四条：缓存AJAX请求</h3>
<p>&nbsp;&nbsp;&nbsp;  根据业务类型，为处理AJAX请求的Action文件的设置合适的到期时间<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;  动态更新AJAX请求的URL，如，给这个URL后面加上一个更新时间，如：<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;  &amp;t=1190241612，只在请求的数据发生变化时动态修改该URL地址。</p>
<p>后续二十一条下次再过一遍! ^_^</p>
<p>&nbsp;</p>
<p><a target="_blank" href="http://www.w3cgroup.com/attachments/month_1004/High Performance Websites.ppt">High Performance Web Sites.ppt</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=293</link>
			<title><![CDATA[ECMA262深入浅出]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Sun,11 Apr 2010 13:02:21 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=293</guid>
		<description><![CDATA[<div>
<h2>ECMA262深入浅出</h2>
<h3>ECMA-262简述</h3>
<h3>ECMAScript语言概述</h3>
<h3>ECMAScript对象概述(原型链Prototype Chain)</h3>
<h3>ECMA-262主要术语</h3>
<h3>ECMAScript执行环境(作用域链Scope Chain，闭包机制)</h3>
<h3>ECMAScript函数(new原理)</h3>
<h3>ECMAScript内部属性(参考)</h3>
<h3>ECMAScript执行环境作用域链图示</h3>
<h3>ECMA-262参考资料</h3>
</div>
<div>&nbsp;</div>
<div><strong>ECMA-262简述</strong></div>
<div>&nbsp;</div>
<div>ECMA(European Computer Manufacturers Association)</div>
<div>&nbsp;</div>
<div>ECMA-262标准的最初的版本是基于Brendan Eich创造的JavaScript语言来制定的，它是ECMAScript脚本语言的规范及标准。该标准在1998年4 月通过快速通道提交到ISO/IEC JTC 1并被采纳为国际标准ISO/IEC 16262，所以之后一直简称为ECMA-262，该标准发展到现在已经到了第5版。 <br />
<br />
<br />
所有遵循ECMA-262标准实现的脚本都可以称之为ECMAScript，如JavaScript, JScript, ActionScript等等。</div>
<div>&nbsp;</div>
<div>注意：ECMA-262是从ECMAScript脚本引擎实现的角度去描述的。</div>
<div>&nbsp;</div>
<div>我们目前所使用的大部分浏览器中的脚本引擎多数都是基于ECMA-262标准第3版的实现，参见下图：</div>
<div>&nbsp;</div>
<div>&nbsp;<img alt="ECMA262 3rd edition实现引擎列表" src="http://www.w3cgroup.com/attachments/month_1004/62010411125812.png" /></div>
<div>&nbsp;</div>
<div><strong>ECMAScript语言概述</strong></div>
<div>&nbsp;</div>
<div>ECMAScript最初的设计是一种网页脚本语言。<br />
<br />
&nbsp;</div>
<div>脚本语言是一种编程语言，可用来操作、自定义、自动化现有系统中的设备。</div>
<div>在某些系统中，一些可用的功能是可以通过用户接口来使用的。而脚本语言，就是将这些功能暴露给编程人员进行控制的机制。这样的系统，我们可以说，它们为我们提供了一个运行脚本语言的宿主环境。脚本语言是专门给专业和非专业的编程人员使用的，为了适应非专业的程序员，有些方面多少有些不太严格。<br />
<br />
脚本语言与宿主环境是两个不同的主体，比如，浏览器就为ECMAScript提供了一个宿主环境，BOM和DOM则都是浏览器提供的功能，而各种基于ECMA262实现的脚本语言，如JavaScript,Jscript等，都可以为我们提供对BOM和DOM的操作方法。因为宿主环境的不同，它们提供的功能也不尽相同，这也是我们知道的，不同的浏览器中会有不同的BOM和DOM的属性和方法。</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>ECMAScript是基于对象(object-based)的编程语言，在宿主环境中执行计算或操作对象。ECMAScript程序就是一个对象间交互通信的聚合。&nbsp;在ECMAScript中，&ldquo;对象&rdquo;(object)的properties是一个无序的集合，properties 是一个容器，可以包含其他的对象，原始值(primitive&nbsp;values)或方法(methods)。<br />
<br />
原始值属于下列&ldquo;内置类型&rdquo;(built-in types)中的一员：Undefined, Null, Boolean, Number和String,&ldquo;对象 &rdquo;则是内置类型：Object,&ldquo;方法&rdquo;是一个透过property关联到对象的函数。<br />
<br />
&nbsp;</div>
<div>ECMAScript定义了&ldquo;内置对象&rdquo;(built-in objects)，以使ECMAScript实体更为完善。这些内置对象包括：Global对象，Object对象， Function对象，Array对象，String对象，Boolean对象，Number对象，Math对象，Date对象， RegExp对象和错误对象： Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError。<br />
<br />
&nbsp;</div>
<div>ECMAScript还定义了&ldquo;内置操作符&rdquo;或者说是&ldquo;函数&rdquo;或&ldquo;方法&rdquo;。ECMAScript操作符包括了各种一元运算符、乘除运算符、加减法运算符、位移运算符、关系运算符、相等运算符、二元运算符、二元逻辑运算符、分配运算符和逗号运算符。<br />
<br />
&nbsp;</div>
<div>ECMAScript的语法类似Java的语法。ECMAScript语法宽松是为了使它能够成为更容易使用的脚本语言。比如，变量不需要申明类型也不需要为properties指定类型，函数定义也可以不需要出现在它们的调用语句之前。</div>
<div>&nbsp;</div>
<div><strong>ECMAScript对象概述</strong></div>
<div>&nbsp;</div>
<div>ECMAScript没有像C++，Smalltalk，Java等语言中的真正的类，但是它支持构造器(constructors)。它在代码执行时创建对象，为对象分配内存并初始化它们全部或部分初始值和properties。所有的构造器都是对象，但不是所有对象都是构造器。每个构造器都有一个Prototype属性用于实现基于原型的继承(prototype-based inheritance)和属性共享(shared properties)。</div>
<div>&nbsp;</div>
<div>对象在对构造器使用new表达式时被创建，比如，new String(&ldquo;A String&rdquo;)创建了一个新的字符串对象。不用new表达式直接去调用一个构造器，其结果将依赖于这个构造器的具体实现，如，String(&quot;A String&quot;) 产生一个原始值String，而不是一个对象。<br />
<br />
&nbsp;</div>
<div>ECMAScript支持基于原型的继承。所有构造器都有一个相关联的原型，所有由构造器创建的对象都隐含一个指向到该原型的引用（称为对象原型），此外，一个原型可能有一个非空的、隐含的引用，指向到它的原型，所以，这又被称为是：原型链(prototype chain)</div>
<div>&nbsp;</div>
<div><img alt="ECMAScript Prototype Chain原型链" src="http://www.w3cgroup.com/attachments/month_1004/a2010411125916.png" /></div>
<div>&nbsp;</div>
<div>当一个引用来自一个对象时，它会去该对象和它的原型(链)中查找与该property同名的属性，换句话说，会先直接从该对象中检测是否存在这个同名的引用，如果有则返回，否则再从该对象的原型(链)中去检测是否存在该引用。(DEMO)</div>
<div>&nbsp;</div>
<div>DEMO:</div>
<div>&lt;script type=&quot;text/javascript&quot;&gt;</div>
<div>Object.prototype.hi = function(){</div>
<div><span>&nbsp;&nbsp;&nbsp; alert('object.prototype.hi');</span></div>
<div>};</div>
<div>Object.prototype.greetings = function(){</div>
<div><span>&nbsp;&nbsp;&nbsp; alert('object.prototype.greetings');</span></div>
<div>};</div>
<div>&nbsp;</div>
<div>Function.prototype.greetings = function(){</div>
<div><span>&nbsp;&nbsp;&nbsp; alert('function.prototype.greetings');</span></div>
<div>};</div>
<div>&nbsp;</div>
<div>var CF = function(){};</div>
<div>CF.prototype.hello = function(){</div>
<div><span>&nbsp;&nbsp;&nbsp; alert('CF.prototype.hello');</span></div>
<div>};</div>
<div>CF.prototype.bye = function(){</div>
<div><span>&nbsp;&nbsp;&nbsp; alert('CF.prototype.bye');</span></div>
<div>};</div>
<div>&nbsp;</div>
<div>var o = new CF();</div>
<div>o.hello = function(){alert('o.hello');};</div>
<div>&nbsp;</div>
<div>o.hello();</div>
<div>o.bye();</div>
<div>o.hi();</div>
<div>o.greetings();</div>
<div>&nbsp;</div>
<div>CF.hi();</div>
<div>CF.greetings();</div>
<div>&lt;/script&gt;</div>
<div>&nbsp;</div>
<div><br />
在基于类的面向对象语言里,通常,状态由实例持有，方法由类持有，继承只有结构和行为。在ECMAScript中，状态和方法由对象持有，结构、行为和状态都可以被继承。</div>
<div>&nbsp;<br />
对象通常都不会直接包含那些由原型包含共享的属性和值。描述见下图：</div>
<div>&nbsp;</div>
<div>&nbsp;<img alt="ECMAScript prototype原型" src="http://www.w3cgroup.com/attachments/month_1004/82010411125948.png" /></div>
<div>&nbsp;</div>
<div>CF是一个构造函数（同时也是一个对象）。通过对它进行new表达式创建了5个实例对象：cf1,cf2,cf3,cf4,cf5。每个实例对象都包含有q1 和q2两个属性。(DEMO)<br />
<br />
例如，Cfp是cf3的原型(虚线，表示隐含的原型关系)，构造函数CF自己有两个属性P1和P2，它们对 Cfp,cf1,cf2,cf3,cf4,cf5都不可见。Cfp的属性CFP1对cf1,cf2,cf3,cf4,cf5可见（但不包括CF），还有那些在Cfp的隐含的原型链中找到的 property name(非q1,q2或者CFP1的其他属性)。注意，CF和Cfp之间并非隐含的原型联系。</div>
<div>与基于类的对象语言不同，ECMAScript对象的属性可以通过给对象赋值的方式动态地添加到对象上，意思就是，构造函数不需要一个个地为那些由它构造出的对象赋值，如上图，只要为CFp添加一个属性值,即可使得由CF构造出的所有对象：cf1,cf2,cf3,cf4,cf5共享。</div>
<div>&nbsp;</div>
<div>DEMO:</div>
<div>&lt;script type=&quot;text/javascript&quot;&gt;</div>
<div>var CF = function(){};</div>
<div>CF.p1 = 'p1';</div>
<div>CF.p2 = 'p2';</div>
<div>&nbsp;</div>
<div>CF.prototype = {CFP1:'cfp1'};</div>
<div>&nbsp;</div>
<div>var cf1 = new CF(),cf2 = new CF(),cf3 = new CF(),cf4 = new CF(),cf5 = new CF();</div>
<div>&nbsp;</div>
<div>alert(cf1.p1+','+cf2.p2);//构造函数自身的属性对由它构造出的对象不可见</div>
<div>&nbsp;</div>
<div>alert(CF.CFP1);//对CF不可见</div>
<div>alert(cf1.CFP1);//对CF构造的所有对象可见</div>
<div>&nbsp;</div>
<div>cf3.__proto__.CFP2 = 'cfp2';//在构造函数原型上添加属性</div>
<div>//__proto__相当于从cf3到CF.prototype的隐含的原型关系，该属性是SpiderMonkey引擎的私有属性，仅限在SpiderMonkey引擎中访问</div>
<div>&nbsp;</div>
<div>alert(cf1.CFP2);//即可对所有该构造函数构造的对象进行共享</div>
<div>&lt;/script&gt;</div>
<div>&nbsp;</div>
<div><strong>ECMA-262主要术语</strong></div>
<div>&nbsp;</div>
<div>以下是ECMAScript中主要术语的非正式定义。</div>
<div>&nbsp;</div>
<div>Type<br />
数据值的集合</div>
<div>Primitive Value<br />
原始值包括Undefined,Null,Boolean,Number,String这些类型成员。原始值是语言实现中底层可以直接表示的数据。</div>
<div>Object<br />
每个对象都是Object类型的成员。它包含的所有属性成员，如原始值、对象或者函数，是一个无序的集合。对象属性成员放置的函数又被称为方法。</div>
<div>Constructor<br />
构造器是一个函数对象，用来创建和初始化对象。每个构造器都有一个关联的原型对象用来实现属性成员的继承和共享。</div>
<div>&nbsp;</div>
<div>Prototype <br />
ECMAScript中的原型用来实现对象结构、状态和行为的继承。当一个构造器构造了一个对象，这个对象会隐含地引用到该构造器关联的原型去解析属性的引用。构造器关联的原型可以通过程序表达式constructor.prototype 来引用。在某个共享对象的原型上添加的属性值，通过继承，可以被所有其他对象共享。</div>
<div>Native Object <br />
原生对象是由ECMAScript的实现提供的，独立于宿主环境。有些原生对像同时又是内置对象，其他的则可能会在执行一个 ECMAScript程序时产生。</div>
<div>Built-in Object <br />
内置对象是由ECMAScript的实现提供的，独立于宿主环境，它们出现在ECMAScript程序开始执行的时候。所有的内置对象都是原生对象。</div>
<div>Host Object<br />
宿主对象由为ECMAScript提供完整执行环境的宿主环境提供的。任何对象，不是原生对象，就是宿主对象。</div>
<div>&nbsp;</div>
<div>Undefined Value<br />
Undefined值是一个原始值，当一个变量没有被分配值的时候使用。</div>
<div>Undefined Type<br />
Undefined类型只有一个值，undefined。</div>
<div>Null Value<br />
Null值是一个原始值，它表示空的，没有的，或不存在的引用。</div>
<div>Null Type<br />
Null类型有一个值，null。</div>
<div>Boolean Value<br />
Boolean值是Boolean类型的成员，它只能是两个值中的一个，true或false。</div>
<div>Boolean Type<br />
Boolean类型表示一个逻辑实体，由两个唯一值组成，一个是true，另一个是false。</div>
<div>&nbsp;</div>
<div>Boolean Object <br />
Boolean对象是Object类型的成员，它是内置对象Boolean的实例。意思是，一个Boolean对象是通过Boolean构造器的 new表 达式创建，提供一个boolean参数。结果对象有一个隐含的（未命名）原型boolean。一个Boolean对象支配一个 Boolean值。</div>
<div>String Value <br />
String值是String类型的成员，它是一个有限的有序的，0到16位无符号整数长度的值。注意：尽管每个值通常都表示一个单独的16位的UTF-16文本的单元，但该语言不会做出任何限制和要求当这个值不是16位无符号整数的情况时。</div>
<div>String Type <br />
String类型是所有字符串值的集合。</div>
<div>String Object <br />
String对象是Object类型的成员，它是内置对象String的实例。</div>
<div>&nbsp;</div>
<div>Number Value <br />
Number值是Number类型的成员，它是一个直接表示的数字。</div>
<div>Number Type <br />
Number类型是表示数字的值的集合。在ECMAScript中，该集合表示IEEE754的64位双精度运算格式的值，包含一个特殊值&quot;Not-a-&nbsp;Number&quot;(NaN)，正无穷大和负无穷大。</div>
<div>Number Object <br />
Number对象是Object类型的成员，它是内置对象Number的实例。</div>
<div>Infinity <br />
原始值Infinity表示一个正无穷大的数字，Number类型成员。</div>
<div>NaN<br />
原始值NaN表示IEEE标准&quot;Not-a-Number&quot;值的集合，Number类型成员。</div>
<div>&nbsp;</div>
<div><strong>ECMAScript执行环境</strong></div>
<div>&nbsp;</div>
<div>什么是执行环境?<br />
<br />
想象一下，假设你就是一个ECMAScript引擎。<br />
<br />
当你接收到一条语句：<br />
<br />
this.x = y;<br />
<br />
你能确定该做什么吗？<br />
<br />
很明显， 我们不知道该做些什么，因为我们既不知道this是什么，也不清楚y是什么。<br />
<br />
所以，如果要正确执行这条语句，我们需要一个上下文，用以确定this和y到底是什么，这个上下文，就是执行环境。</div>
<div>&nbsp;</div>
<div><strong>执行环境</strong></div>
<div><br />
当控制器转到ECMAScript可执行代码时，即会进入到一个执行环境中。活动的执行环境会在逻辑上形成一个堆栈，在这个堆栈的顶端存放的是运行时的执行环境。</div>
<div>&nbsp;</div>
<div><strong>函数对象</strong>(两种类型)<br />
通过在源文件中透过函数声明、函数表达式或内置Function对象来定义的函数对象。<br />
内部函数对象，它们属于内置对象，如parseInt, Math.exp等等。</div>
<div>&nbsp;</div>
<div><strong>可执行代码</strong> (三种ECMAScript可执行代码类型)<br />
Global代码<br />
Eval代码<br />
Function代码</div>
<div>&nbsp;</div>
<div><strong>变量实例</strong></div>
<div><br />
每个执行环境都会与一个&ldquo;变量对象&rdquo;关联。在源文件中定义的的变量和函数都会作为properties添加到该对象中去。例如函数的代码，参数将作为properties添加到该函数执行环境的变量对象中去。</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong>在进入一个执行环境时，&ldquo;变量对象&rdquo;绑定properties的顺序如下</strong>：(DEMO)</div>
<div><br />
<strong>针对函数代码</strong>：为每一个在参数列表中定义的形参，创建一个同名的标识符作为property添加到&ldquo;变量对象&rdquo;中，其值由调用[[call]]时以参数的形式提供。如果调用者提供的参数值少于形参数量，其他的形参值将为undefined。如果遇到多个同名的形参，最后一个同名形参的值将被保留，如果这最后一个形参也未被提供值，同样会是undefined。</div>
<div><br />
<strong>针对函数声明</strong>：在&ldquo;变量对象&rdquo;中创建一个以它们的名字作为标识符的property，其值为创建后的函数对象。如果&ldquo;变量对象&rdquo;中已经有一个同名的property，则将它替换掉。</div>
<div><br />
<strong>针对变量声明</strong>：在&ldquo;变量对象&rdquo;中创建一个以它们的名字作为标识符的property，其值为undefined，如果之前已有这个property,则其值不变。</div>
<div>&nbsp;</div>
<div>DEMO:</div>
<div>&lt;script type=&quot;text/javascript&quot;&gt;</div>
<div>/*-------------函数代码------------*/</div>
<div>function x(a,a,b){alert(a);alert(b);};</div>
<div>x(1,2,3);</div>
<div>x(1);</div>
<div>/*-------------函数声明------------*/</div>
<div>function a(){alert(1);};</div>
<div>alert(a);</div>
<div>function a(){alert(2)};</div>
<div>alert(a);</div>
<div>/*-------------变量声明------------*/</div>
<div>var b;</div>
<div>alert(b); //其值为undefined</div>
<div>&lt;/script&gt;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong>作用域链与标识符查找</strong></div>
<div><br />
所有的执行环境都与一个作用域链(scope chain)相关联。作用域链是一个用来查找标识符的对象列表。当控制器进入到一个执行环境中的时候，作用域链被创建并放置了一个初始的对象集合。在一个执行环境运行的时候，它的作用域链只受with语句和catch子句影响。在执行的时候，标识符查找的方法如下：</div>
<div><br />
1. 获取Scope Chain的下一个对象。如果没有对象了，则转到第5步 <br />
2. 调用Result(1)的[[HasProperty]]方法, 传递Identifier作为参数&nbsp;<br />
3. 如果Result(2)是true, 则返回一个Reference(引用)类型的值，它的base object是Result(1)，而它的property name是Identifier<br />
4. 跳到第1步<br />
5. 返回一个Reference类型，它的base object是null，它的property name是Identifier<br />
<br />
标识符查找的结果通常是一个名字为标识符字符串的引用值。</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong>全局对象(Global Object)</strong></div>
<div><br />
在控制器进入任何执行环境之前，会创建一个唯一的全局对象，初始化的全局对象包括以下属性：<br />
<br />
<strong>内置对象</strong>，如 Math,String,Date,parseInt等等，它们都是不可枚举的(DontEnum)。<br />
<br />
<strong>宿主属性</strong>，它自己可能会包含一个值为全局对象的属性，比如，在HTML 的DOM中，全局对象中的window属性，就是全局对象自己。<br />
<br />
当控制器进入了执行环境，ECMAScript运行的时候，全局对象可能还会被添加上一些额外的属性，一些之前已有的属性也有可能被改变。</div>
<div>&nbsp;</div>
<div><strong>This</strong></div>
<div><br />
所有活动的执行环境都会有一个this值，它依赖并取决于代码执行时的caller。<br />
<br />
同一个执行环境中的this值是不变的。<br />
&nbsp;</div>
<div>&nbsp;</div>
<div><strong>Arguments对象</strong></div>
<div><br />
当控制器进入到一个函数的执行环境中时，会创建一个arguments对象,初始过程如下：<br />
<br />
arguments对象的内部属性[[prototype]]，是原生对象prototype，初始值是Object.prototype<br />
<br />
创建callee属性，不可枚举(DontEnum)，其值为正在执行的函数对象，这使得匿名函数也可以进行递归。<br />
<br />
创建length属性，不可枚举(DontEnum)，其值为caller提供的实际参数数量。<br />
<br />
按少于length的正整数数量创建ToString(arg)属性，不可枚举(DontEnum)，第一个实际参数值对应为arg = 0，第二个对应为arg = 1，依此类推。当实际参数少于形参时，该属性会在活动对象中相应地共享它的值。意思就是说，改变此属性将改变活动对象中的属性值，反之亦然。</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong>进入一个执行环境时发生的那些事儿</strong></div>
<div><br />
每次调用函数或构造器都会进入一个新的执行环境，即使在一个函数递归地调用自己的时候亦是如此。每次return，都会退出这个执行环境。一个未捕捉的异常也可能退出一个或多个执行环境。<br />
<br />
当控制器进入到一个执行环境中时，作用域链即被创建和初始化，变量实例化也开始进行，this值也被确定下来。</div>
<div>&nbsp;</div>
<div><strong>Global代码</strong><br />
<br />
作用域链创建并初始，仅包含global对象。<br />
<br />
变量实例化进行的时候以global对象作为变量对象，属性为不可删除(DontDelete) 。<br />
<br />
This值为global对象。</div>
<div><br />
<strong>Eval代码</strong><br />
<br />
当控制器进入到eval代码的执行环境中时，先前活动的执行环境，引用到调用环境*，用来决定作用域链，变量对象和this值。如果没有调用环境，则所有这些都以全局代码形式进行处理。<br />
<br />
作用域链初始化时包含一个与调用环境相同的对象，并保持相同的顺序。这包含了通过with语句和catch子句添加到调用环境作用域链上的对象。<br />
<br />
变量实例化时使用调用环境下的变量对象。<br />
<br />
This值与调用环境下的this值一致。<br />
<br />
* 调用函数语句执行时的execution context就是calling context</div>
<div><br />
<strong>Function代码</strong><br />
<br />
作用域链初始化时先添加活动对象，然后再添加该函数对象[[Scope]]属性中存储的其他对象。* 闭包机制<br />
<br />
变量实例化执行时使用活动对象作为变量对象，属性为不可删除(DontDelete)。<br />
<br />
This的值为Caller，如果caller不是对象(或者是null)，则this值为global对象。</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong>With语句</strong><br />
<br />
with语句会在当前执行环境中的作用域链顶端添加一个计算对象，在这个扩展的作用域链执行完语句之后，随机复原之前的作用域链。<br />
<br />
With(表达式)语句的执行过程如下：<br />
<br />
1.评估表达式<br />
2.调用GetValue(Result(1))<br />
3.调用ToObject(Result(2))<br />
4.将Result(3)添加到 作用域链的顶端<br />
5.用第4步扩展的作用域链来评估语句<br />
6.使C=Result(5)，如果在第5步时有异常抛出，则C=(throw,V,empty)，V是这个异常（执行现在当作没有异常抛出继续进行）<br />
7.在作用域链中移除Result(3)<br />
8.返回C<br />
<br />
注意：当控制器离开该&ldquo;嵌入&rdquo;的语句时，无论是正常还是异常，作用域链都将被恢复。</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong>Catch子句</strong><br />
<br />
catch(标识符)块的执行过程如下：<br />
<br />
1.使C为通过catch传递进来的参数<br />
2.像new Object()一样创建一个新的对象<br />
3.在Result(2) 的那个对象上创建一个property，名字是标识符，值是C，不可删除<br />
4.将Result(2)添加到作用域链的顶端<br />
5.评估这个块语句<br />
6.将Result(2) 从作用域链中移除<br />
7.返回Result(5)</div>
<div>&nbsp;</div>
<div><strong>函数声明</strong><br />
<br />
function Identifier(FormalParameterList opt){FunctionBody}<br />
<br />
函数声明的解析过程如下：<br />
<br />
1.创建一个new Function对象， FormalParameterList指定参数，FunctionBody指定函数体。将当前正在运行的执行环境中的作用域链作为它的作用域。<br />
<br />
2.为当前的变量对象 创建一个名为Identifier的属性，值为Result(1)。</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong>匿名函数表达式</strong><br />
<br />
function(FormalParameterList opt){FunctionBody}<br />
<br />
匿名函数表达式的解析过程如下：<br />
<br />
1.创建一个new Function对象， FormalParameterList指定参数，FunctionBody指定函数体。将当前正在运行的执行环境中的作用域链作为它的作用域。<br />
<br />
2.返回Result(1)。</div>
<div>&nbsp;</div>
<div><strong>具名函数表达式</strong><br />
<br />
function Identifier(FormalParameterList opt){FunctionBody}<br />
<br />
具名函数表达式的解析过程如下：<br />
<br />
1.创建一个new&nbsp;Object对象<br />
2.将Result(1)添加到作用域链的顶端<br />
3.创建一个new Function对象，FormalParameterList指定参数，FunctionBody指定函数体。将当前正在运行的执行环境中的作用域链作为它的作用域。<br />
4.为Result(1)创建一个名为Identifier的属性，其值为Result(3)，只读，不可删除<br />
5.从作用域链中移除Result(1)<br />
6.返回Result(3)</div>
<div>&nbsp;</div>
<div><strong>创建函数对象</strong><br />
<br />
函数对象构造过程如下：<br />
<br />
<span style="color: #c0c0c0">1.如果已有对象E，它已有FunctionBody，且与现在给到的FunctionBody相等，则跳转到第13步<br />
</span>2. 创建一个新的ECMAScript native对象F<br />
3.设置F的[[Class]]为&ldquo;Function&rdquo;<br />
4.设置F的[[Prototype]]为原始的Function prototype对象<br />
5.设 置F的[[Call]](参见之后的Slide)<br />
6.设置F的[[Construct]]（参见之后的Slide）<br />
7.设置F的[[Scope]]为一个新的作用域链，它和当前作用域包含相同的对象<br />
8.设置F的lengeh属性值为形参数量，如果未定义参数，则为0。9.以new Object()表达式方式创建一个新的对象<br />
10.设置F的 constructor属性值为Result(9)<br />
11.设置F的prototype属性值为Result(9)<br />
12.返回F<br />
<span style="color: #c0c0c0">13.酌情（由实现者决定）跳转到第2步或第14步<br />
14.创建 一个新的ECMAScript native对象F，连接到 E，复制所有E和F的非内部属性*以使得它们与E和F的保持一致。<br />
15.设置F的[[Class]]属性值为&ldquo; Function&rdquo;<br />
16.设置F的[[Prototype]]属性值为原始的Function prototype对象<br />
17.设置F的[[Call]]属性<br />
18.设置F的[[Construct]]属性<br />
19. 设置F的[[Scope]]属性值为一个新的作用域链，它和当前作用域包含相同的对象<br />
20.返回F<br />
</span><br />
* 内部属性指的是所有以[[]]书写的属性</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong>创建函数对象</strong><br />
<br />
注意：<br />
<br />
每个function都会自动创建一个prototype属性，以使得它们可以当作构造器来使用。<br />
<br />
<span style="color: #c0c0c0">第1步，使得类似函数A中嵌套了一个不依赖于A的函数B的这种情况进行优化。在这种情形的实现中，允许在A每次被调用的时候，重用B这个对象。<br />
<br />
第13步决定是否执行此 优化。如果在某个实现中选择不，则会跳转到第2步。</span></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong>创建函数对象</strong><br />
<br />
连接对象(很多引擎都未去做这个实现) <br />
<br />
<span style="color: #c0c0c0">当两个或更多的Function对象连接时，它们具有如下特殊的行为：<br />
<br />
1.任何时候，对 象O创建或设置一个非内部属性时，通信机制会立即在其他所有与O连接的对象上做相同的操作。<br />
<br />
2.任何时候，对象O删除一个非内部属性，&nbsp;通信机制会立即在其他所有与O连接的对象上做相同的操作。<br />
<br />
3.如果对象O与P相连，它们可以通过==和===来进行比较。<br />
<br />
4.当对象O与P相连 ，且对象P与Q相连，则O与Q也会自动相连。<br />
<br />
注意：相连的对象除了它们各自不同的内部属性外，是很难进行区别的。而这些内部属性可能也只有[[Scope]]会不同。</span></div>
<div>&nbsp;</div>
<div><strong>调用函数对象</strong><br />
<br />
[[Call]]<br />
<br />
当函数对象F调用了[[Call]]属性，将执行以下步骤：<br />
<br />
1.将F的形参表、传递的参数列表，和this植入到一个新的执行环境<br />
<br />
2.评估F的FunctionBody<br />
<br />
3.退出在第1步植入的执行环境，恢复之前的执行环境<br />
<br />
4.如果Result(2).type是 throw,抛出Result (2).value<br />
<br />
5.如果Result(2).type是return，返回Result(2).value<br />
<br />
6.Result(2).type默认情况下，返回undefined</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong>new操作原理</strong><br />
<br />
[[Construct]]<br />
<br />
当函数对象F调用了[[Construct]]属性，将执行以下步骤：<br />
<br />
1.创建一个新的ECMAScript native对象<br />
2.将 Result(1)的[[Class]]属性值设为&ldquo;Object&rdquo;<br />
3.取得F的prototype属性值<br />
4.如果Result(3)是一个对象，将Result(1)的[[Prototype]]属性值设置为Result(3)<br />
5.如果Result(3)不是一个对象，将Result(1)的[[Prototype]]属性值设置为原始的Object prototype对象<br />
6.调用F的 [[Call]]属性，将Result(1)设置为this值，将[[Construct]]传递的参数当作参数列表<br />
7.如果Type(Result(6))是一个对象，返回Result(6) <br />
8.返回Result(1)</div>
<div>&nbsp;</div>
<div>DEMO:</div>
<div>&lt;script type=&quot;text/javascript&quot;&gt;</div>
<div>/*new操作原理（spiderMonkey引擎下测试）*/</div>
<div>&nbsp;</div>
<div>var a = function(sA,sH){</div>
<div><span>&nbsp;&nbsp;&nbsp; var x = &quot;x&quot;;</span></div>
<div><span>&nbsp;&nbsp;&nbsp; this.a = sA;</span></div>
<div><span>&nbsp;&nbsp;&nbsp; this.h = sH;</span></div>
<div><span>&nbsp;&nbsp;&nbsp; this.say = function(){alert(this.a+','+x)}</span></div>
<div>}</div>
<div>a.prototype.hi = function(){alert(this.h)}</div>
<div>&nbsp;</div>
<div>var createInstance = function(source){</div>
<div><span>&nbsp;&nbsp;&nbsp; var p = {}</span></div>
<div><span>&nbsp;&nbsp;&nbsp; var args = Array.prototype.slice.call(arguments,1);</span></div>
<div><span>&nbsp;&nbsp;&nbsp; p.__proto__ = source.prototype;</span></div>
<div><span>&nbsp;&nbsp;&nbsp; source.apply(p,args);</span></div>
<div><span>&nbsp;&nbsp;&nbsp; return p;</span></div>
<div>}</div>
<div>&nbsp;</div>
<div>var A = createInstance(a,&quot;A&quot;,&quot;hi A&quot;);</div>
<div>A.say();</div>
<div>A.hi();</div>
<div>&lt;/script&gt;</div>
<div>&nbsp;</div>
<div><strong>ECMAScript内部属性</strong></div>
<div>&nbsp;</div>
<div>[[Prototype]]<br />
This对象的原型，该属性值只会是一个object或null，所有的[[Prototype]] chain最终都都会通向到null。</div>
<div>[[Class]]<br />
指明This对象类别的字符串值</div>
<div>[[Value]]<br />
与This对象关联的内部状态信息</div>
<div>[[Get]](PropertyName)<br />
返回指定属性的值</div>
<div>[[Put]](PropertyName Value)<br />
设置指定的属性值</div>
<div>[[CanPut]](PropertyName)<br />
返回是否可以执行[[Put]]指定属性的操作的Boolean值</div>
<div>[[HasProperty]](PropertyName)<br />
返回对象是否存在指定的属性名的Boolean值</div>
<div>[[Delete]](PropertyName)<br />
移除对象指定的属性</div>
<div>[[DefaultValue]](Hint)<br />
返回对象的默认值，只能是原始值，不允许对象和引用。</div>
<div>[[Construct]] a list of argument values provied by the caller<br />
通过调用new操作符构造一个对象。</div>
<div>[[Call]] a list of argument values provied by the caller<br />
通过函数调用表达式执行与对象关联的代码。</div>
<div>[[HasInstance]](Value)<br />
返回一个Boolean值，表示This对象是否存在指定的委派（实例），仅对ECMAScript native中的Function对象实现。</div>
<div>[[Scope]] <br />
作用域链，用于表示一个函数对象执行时的环境。</div>
<div>[[Match]](String,Index)<br />
为正则表达式匹配和返回一个MatchResult的值。</div>
<div>&nbsp;</div>
<div><strong>ECMAScript Execution Context and Scope Chain</strong></div>
<div>&nbsp;</div>
<div><strong><img alt="ECMAScript Execution Context and Scope Chain" src="http://www.w3cgroup.com/attachments/month_1004/k201041113028.png" /></strong></div>
<div>&nbsp;</div>
<div>Scope Chain DEMO:</div>
<div>&lt;script type=&quot;text/javascript&quot;&gt;</div>
<div>var v = 'global';</div>
<div>&nbsp;</div>
<div>var x = function(v){</div>
<div>&nbsp;alert(v);</div>
<div>&nbsp;with({}){</div>
<div><span>&nbsp;&nbsp;&nbsp; v = 'w';</span></div>
<div>&nbsp;}</div>
<div>&nbsp;try{alert(me);}catch(e){}</div>
<div>};</div>
<div>&nbsp;</div>
<div>var y = function(){</div>
<div>&nbsp;alert(v);</div>
<div>};</div>
<div>&nbsp;</div>
<div>var z = function(){</div>
<div>&nbsp;var v = 'z';</div>
<div>&nbsp;y();</div>
<div>&nbsp;alert(v);</div>
<div>};</div>
<div>&nbsp;</div>
<div>var n = function(){</div>
<div>&nbsp;var i = 0;</div>
<div>&nbsp;var inner = function(){</div>
<div><span>&nbsp;&nbsp;&nbsp; alert(++i);</span></div>
<div>&nbsp;};</div>
<div>&nbsp;return inner;</div>
<div>};</div>
<div>&nbsp;</div>
<div>x();</div>
<div>&nbsp;</div>
<div>z();</div>
<div>&nbsp;</div>
<div>var fn = n();</div>
<div>&nbsp;</div>
<div>fn();</div>
<div>&lt;/script&gt;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong>ECMA-262参考资料</strong></div>
<div>ECMA-262 3rd Edition<br />
http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,% 20December%201999.pdf</div>
<div>&nbsp;</div>
<div>ECMA-262 5th Edition<br />
http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf</div>
<div>&nbsp;</div>
<div>What is Ecma International<br />
http://www.ecma-international.org/memento/index.html</div>
<div>&nbsp;</div>
<div><a target="_blank" href="http://www.w3cgroup.com/attachments/month_1003/ECMAScript概述.ppt">PPT下载：ECMAScript概述.ppt</a></div>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=292</link>
			<title><![CDATA[WEB2.0 in front-end engineering]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Wed,07 Apr 2010 22:14:26 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=292</guid>
		<description><![CDATA[<h2>WEB2.0 in front-end engineering</h2>
<h3>Agenda<br />
<br />
更简洁的用户操作<br />
<br />
更细化的领域分工<br />
<br />
更低的合作耦合度</h3>
<h4>用户</h4>
<p>WEB2.0因用户创造分享内容而兴起，就前端部分来讲，不得不将用户的感受纳入到考量的范围。</p>
<p>观察互联网发展趋势，为用户提供更简洁，明了的服务（功能）页面是越来越值得重视的。</p>
<p>由论坛到博客，博客到社交网络，社交网络到微博，这是一条很清晰的发展路线。</p>
<p>用户是&ldquo;懒惰&rdquo;的，不论我们做什么产品，对和用户直接打交道的前端来讲，<strong>保持一个简洁明了的使用方式</strong>，是非常重要的。</p>
<h4>开发人员</h4>
<p>WEB2.0的另一个较为显著的特征就是&ldquo;快&rdquo;。<br />
<br />
从有一个好点子开始，到推出这个产品，只要非常短的时间；<br />
<br />
用户的访问速度也更快，页面加载、数据传输，都可以在很短的时间内完成；<br />
<br />
要达到这些要求，对开发人员来讲，他们需要更细致的分工。<br />
<br />
DBA，架构师，后端开发，前端开发，用户体验设计，美工设计等等职能部门的细化是必不可少的。<br />
<br />
从某个部门内部甚至都可以进行分工的再细化，就如前端部分，在恰当的时机，可以更细化为：更关注语义化的、健壮的HTML架构的部分开发人员 更关注CSS兼容、更新的部分开发人员 更关注JavaScript性能优化的部分开发人员<br />
<br />
<strong>让每个人做自己最擅长的事</strong>，是我们值得学习的一种管理模式，这不仅对开发人员的职业规划有促进作用，更能为企业发展，达成World Class的开发团队夯实基础。</p>
<h4>开发人员</h4>
<p>为了达到从&ldquo;点子&rdquo;到&ldquo;产品&rdquo;的快，开发人员必须实现低耦合度的合作。</p>
<p>各部门同步开发，无疑是最能提升开发效率的，但这需要一系列的前提作为保障。</p>
<p>明确的需求，统一的开发、测试标准成为这一开发模式的重要前提！</p>
<p>就前端部分来讲，明确的需求和统一的开发、测试标准可以理解为UI给出的各页面最终设计效果图、交互效果图和UI Spec，这三部分必须作为前端开发和QA测试的统一标准。</p>
<p>后端部分可以更多的考虑数据API的开发，完全不需要考虑任何前端的结构（需要与前端部分达成数据需求意见）。</p>
<p><strong>前后端开发的解耦</strong>是WEB开发过程中的重要突破，我们应该全力去实现这种开发模式。</p>
<p><a target="_blank" href="http://www.w3cgroup.com/attachments/month_1003/Web2.0 in F2E.ppt">PPT下载：Web2.0 in F2E.ppt</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=291</link>
			<title><![CDATA[西湖印象]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[My Life]]></category>
			<pubDate>Tue,06 Apr 2010 22:13:11 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=291</guid>
		<description><![CDATA[<p>杭州景区还是名不虚传的，不过单逛西湖就有点无聊鸟，呵呵 ^_^</p>
<p><img alt="西湖古樟倒影" src="http://www.w3cgroup.com/attachments/month_1004/dy.jpg" /></p>
<p><img alt="雷峰塔" src="http://www.w3cgroup.com/attachments/month_1004/lft.jpg" /></p>
<p><img alt="垂柳" src="http://www.w3cgroup.com/attachments/month_1004/ls.jpg" /></p>
<p><img alt="垂柳" src="http://www.w3cgroup.com/attachments/month_1004/ls2.jpg" /></p>
<p><img alt="亭子" src="http://www.w3cgroup.com/attachments/month_1004/tz2.jpg" /></p>
<p><img alt="亭子" src="http://www.w3cgroup.com/attachments/month_1004/tz.jpg" /></p>
<p><img alt="宋义士武松墓" src="http://www.w3cgroup.com/attachments/month_1004/ws.jpg" /></p>
<p><img alt="西湖断桥" src="http://www.w3cgroup.com/attachments/month_1004/xh.jpg" /></p>
<p><img alt="樱花" src="http://www.w3cgroup.com/attachments/month_1004/yh.jpg" /></p>
<p><img alt="郁金香" src="http://www.w3cgroup.com/attachments/month_1004/yjx.jpg" /></p>
<p><img alt="郁金香" src="http://www.w3cgroup.com/attachments/month_1004/yjx2.jpg" /></p>
<p><img alt="黄色菊花" src="http://www.w3cgroup.com/attachments/month_1004/hjh.jpg" /></p>
<p><img alt="紫色菊花" src="http://www.w3cgroup.com/attachments/month_1004/zjh.jpg" /></p>
<p><img alt="紫色菊花" src="http://www.w3cgroup.com/attachments/month_1004/zjh2.jpg" /></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=290</link>
			<title><![CDATA[高效WEB开发团队建设]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Mon,29 Mar 2010 22:09:54 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=290</guid>
		<description><![CDATA[<p>高效WEB开发团队建设<br />
Charlie Du<br />
<br />
<strong>我们需要一个更高效的开发团队</strong><br />
<br />
为什么？<br />
<br />
向业界有影响力的开发团队看齐: 雅虎, 淘宝, 百度<br />
希望有一天我们也能够成为影响别人的团队！<br />
我们需要一个更高效的开发团队<br />
<br />
<strong>对团队成员的意义</strong><br />
<br />
提升成员自身专业技能<br />
让每一位成员专注做自己最擅长的事<br />
有利于成员形成较清晰的职业规划<br />
<br />
<strong>对公司的意义</strong><br />
<br />
提高工作效率，节约开支<br />
提高产品品质，增强竞争力<br />
提升公司专业形象，塑造业界有影响力的团队<br />
<br />
<strong>我们要如何来做？</strong><br />
<br />
合理的开发流程(主流程部分)<br />
团队组织结构及职责<br />
<br />
<br />
<strong>从需求开始</strong><br />
<br />
明确的需求是项目的基础，也是QA测试及项目交付的依据！<br />
所以，在整个开发流程中，我们将很大一部分时间用来明确项目需求，这是非常重要的。<br />
<br />
<strong>前后端分离</strong><br />
<br />
当我们有了明确的项目需求，并有了说明文档以及线框图或快速原型，我们就可以准备分发任务了。<br />
为了实现高效的开发，前后端分离是非常值得推荐的开发方式。<br />
前后端的分离，使得项目开发得以同步进行而互不影响。<br />
由于我更多的是从事前端的开发，所以后面会更多的介绍前端部分是如何运作的。<br />
<br />
<strong>前后端分离(意义)</strong><br />
<br />
一、开发工作更细化，有利于提高开发品质。<br />
二、各组成员得以全心投入到相对单一的工作上，对成员的技术提升有非常大的推动。<br />
三、磨合期结束后，有利于优化项目开发进度，缩减项目开发时间。<br />
四、团队整体实力将得到增强，有助于提高团队竞争力。<br />
<br />
<strong>前后端协作</strong><br />
<br />
在前后端开发实施过程中，会必不可少的出现一些问题，如双方需要的数据格式、数据类型等等都是经常会遇到的问题，以及后端在对前端交付的页面套数据时，也常常会遇到一些问题。<br />
为了实现双方更好的协作，我们需要制定一些双方都需要遵循的开发规范。<br />
<br />
<strong>思考及讨论：</strong><br />
<br />
我们目前是怎样的状况？<br />
<br />
<strong>为实现目标而努力</strong><br />
<br />
好事多磨，任何计划在实施过程中都会遇到种种苦难和阻力，不过我们相信，只要我们坚持，就一定能够实现！</p>
<h3><a target="_blank" href="http://www.w3cgroup.com/attachments/month_1003/%E9%AB%98%E6%95%88WEB%E5%BC%80%E5%8F%91%E5%9B%A2%E9%98%9F%E5%BB%BA%E8%AE%BE.ppt">高效WEB开发团队建设.ppt</a></h3>
<p>&nbsp;</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=289</link>
			<title><![CDATA[加速Javascript：DOM操作优化]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Mon,08 Mar 2010 17:11:48 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=289</guid>
		<description><![CDATA[<p>原文：《Speeding up JavaScript: Working with the DOM》</p>
<p>作者： KeeKim Heng, Google Web Developer</p>
<p>翻译：http://www.blogjava.net/emu/archive/2010/03/01/314185.html</p>
<p>在我们开发互联网富应用（RIA）时，我们经常写一些javascript脚本来修改或者增加页面元素，这些工作最终是DOM&mdash;&mdash;或者说文档对象模 型&mdash;&mdash;来完成的，而我们的实现方式会影响到应用的响应速度。</p>
<p>DOM操作会导致浏览器重解析(reflow)，这是浏览器的一个决定页面元素如何展现的计算过程。直接修改DOM，修改元素的CSS样式，修改浏 览器的窗口大小，都会触发重解析。读取元素的布局属性比如offsetHeithe或者offsetWidth也会触发重解析。重解析需要花费计算时间， 因此重解析触发的越少，应用就会越快。</p>
<p>DOM操作通常要不就是修改已经存在的页面上的元素，要不就是创建新的页面元素。下面的4种优化方案覆盖了修改和创建DOM节点两种方式，帮助你减 少触发浏览器重解析的次数。<br />
</p>
<p><span style="font-size: 18pt;"><strong>方案一：通过CSS类名切换来修改DOM</strong></span>&nbsp;</p>
<p>这个方案让我们可以一次性修改一个元素和它的子元素的多个样式属性而只触发一次重解析。</p>
<p>需求：</p>
<p>（emu注：原文作者写到这里的时候脑子显然短路了一下，把后面的Out-of-the-flow DOM  Manipulation模式要解决的问题给摆到这里来了，不过从示范代码中很容易明白作者真正想描述的问题，因此emu就不照翻原文了）</p>
<p>我们现在需要写一个函数来修改一个超链接的几个样式规则。要实现很简单，把这几个规则对应的属性逐一改了就好了。但是带来的问题是，每修改一个样式 属性，都会导致一次页面的重解析。</p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); width: 98%; font-size: 13px;"><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;selectAnchor(element)&nbsp;{<br />
&nbsp;&nbsp;element.style.fontWeight&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;'bold';<br />
&nbsp;&nbsp;element.style.textDecoration&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;'none';<br />
&nbsp;&nbsp;element.style.color&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;'#</span><span style="color: rgb(0, 0, 0);">000</span><span style="color: rgb(0, 0, 0);">';<br />
}</span></div>
<p>&nbsp;</p>
<p><strong>解决方案</strong></p>
<p>要解决这个问题，我们可以先创建一个样式名，并且把要修改的样式规则都放到这个类名上，然后我们给超链接添加上这个新类名，就可以实现添加几个样式 规则而只触发一次重解析了。这个模式还有个好处是也实现了表现和逻辑相分离。</p>
<p><br />
&nbsp;</p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); width: 98%; font-size: 13px;"><span style="color: rgb(0, 0, 0);">.selectedAnchor&nbsp;{<br />
&nbsp;&nbsp;font</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">weight:&nbsp;bold;<br />
&nbsp;&nbsp;text</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">decoration:&nbsp;none;<br />
&nbsp;&nbsp;color:&nbsp;#</span><span style="color: rgb(0, 0, 0);">000</span><span style="color: rgb(0, 0, 0);">;<br />
}<br />
<br />
</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;selectAnchor(element)&nbsp;{<br />
&nbsp;&nbsp;element.className&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;'selectedAnchor';<br />
}</span></div>
<br />
<strong><span style="font-size: 18pt;"><strong>方案二：在非渲染区修改DOM</strong> </span></strong>
<p>（emu注：作者在这里再次脑子短路，把DocumentFragment DOM  Generation模式的介绍提前到这里来了，emu只好再次发挥一下）<br />
上一个方案解决的是修改一个超链接的问题，当一次需要对很多个超链接进行相同修改的时候，这个方案就可以大显身手了。</p>
<p><strong>需求</strong></p>
<p>需求是这样的，我们要写一个函数来修改一个指定元素的子元素中所有的超链接的样式名（className）属性。要实现很简单，我们可以通过遍历每 个超链接并且修改它们的样式名来完成任务。但是带来的问题就是，每修改一个超链接都会导致一次重解析。</p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); width: 98%; font-size: 13px;"><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;updateAllAnchors(element,&nbsp;anchorClass)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;anchors&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;element.getElementsByTagName('a');<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,&nbsp;length&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;anchors.length;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;length;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;anchors[i].className&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;anchorClass;<br />
&nbsp;&nbsp;}<br />
}</span></div>
<br />
<p><strong>解决方案</strong></p>
<p>要解决这个问题，我们可以把被修改的指定元素从DOM里面移除，再修改所有的超链接，然后在把这个元素插入回到它原来的位置上。为了完成这个复杂的 操作，我们可以先写一个可重用的函数，它不但移除了这个DOM节点，还返回了一个把元素插回到原来的位置的函数。</p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); width: 98%; font-size: 13px;"><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);">*<br />
&nbsp;*&nbsp;Remove&nbsp;an&nbsp;element&nbsp;and&nbsp;provide&nbsp;a&nbsp;function&nbsp;that&nbsp;inserts&nbsp;it&nbsp;into&nbsp;its&nbsp;original&nbsp;position<br />
&nbsp;*&nbsp;@param&nbsp;element&nbsp;{Element}&nbsp;The&nbsp;element&nbsp;to&nbsp;be&nbsp;temporarily&nbsp;removed<br />
&nbsp;*&nbsp;@return&nbsp;{Function}&nbsp;A&nbsp;function&nbsp;that&nbsp;inserts&nbsp;the&nbsp;element&nbsp;into&nbsp;its&nbsp;original&nbsp;position<br />
&nbsp;*</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;removeToInsertLater(element)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;parentNode&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;element.parentNode;<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;nextSibling&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;element.nextSibling;<br />
&nbsp;&nbsp;parentNode.removeChild(element);<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(nextSibling)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parentNode.insertBefore(element,&nbsp;nextSibling);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parentNode.appendChild(element);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;};<br />
}</span></div>
<br />
<p>有了上面这个函数，现在我们就可以在一个不需要解析渲染的元素上面修改那些超链接了。这样只在移除和插入元素的时候各触发一次重解析。</p>
<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); width: 98%; font-size: 13px;"><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;updateAllAnchors(element,&nbsp;anchorClass)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;insertFunction&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;removeToInsertLater(element);<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;anchors&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;element.getElementsByTagName('a');<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,&nbsp;length&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;anchors.length;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;length;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;anchors[i].className&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;anchorClass;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;insertFunction();<br />
}</span></div>
<br />
<p><span style="font-size: large;"><strong>方案三：一次性的DOM元素生成</strong></span></p>
<p>这个方案让我们创建一个元素的过程只触发一次重解析。在创建完元素以后，先进行所有需要的修改，最后才把它插入到DOM里面去就可以了</p>
<p><strong>需求</strong></p>
<p>需求是这样的，实现一个函数，往一个指定的父元素上插入一个超链接元素。这个函数要同时可以设置这个超链接的显示文字和样式类。我们可以这样做：创 建元素，插入到DOM里面，然后设置相应的属性。这就要触发3次重解析。</p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); width: 98%; font-size: 13px;"><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;addAnchor(parentElement,&nbsp;anchorText,&nbsp;anchorClass)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;element&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;document.createElement('a');<br />
&nbsp;&nbsp;parentElement.appendChild(element);<br />
&nbsp;&nbsp;element.innerHTML&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;anchorText;<br />
&nbsp;&nbsp;element.className&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;anchorClass;<br />
}</span></div>
<br />
<p><strong>解决方案</strong></p>
<p>很简单，我们只要把插入元素这个操作放到最后做，就可以只进行一次重解析了。</p>
<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); width: 98%; font-size: 13px;"><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;addAnchor(parentElement,&nbsp;anchorText,&nbsp;anchorClass)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;element&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;document.createElement('a');<br />
&nbsp;&nbsp;element.innerHTML&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;anchorText;<br />
&nbsp;&nbsp;element.className&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;anchorClass;<br />
&nbsp;&nbsp;parentElement.appendChild(element);<br />
}</span></div>
<br />
<p>不过，要是我们想要插入很多个超链接到一个元素里面的话，那么这个做法还是有问题：每插入一个超链接还是要触发一次重解析。下一个方案可以解决这个 问题。</p>
<p><strong style="font-size: 18pt;">方案四：通过文档片段对象（DocumentFragment）创建一组元素</strong></p>
<p>这个方案允许我们创建并插入很多个元素而只触发一次重解析。要实现这点需要用到所谓的文档片段对象（DocumentFragment）。我们先在 DOM之外创建一个文档片段对象（这样它也就不需要解析和渲染），然后我们在文档片段对象中创建很多个元素，最后我们把这个文档片段对象中所有的元素一次 性放到DOM里面去，只触发一次重解析。</p>
<p><strong>需求</strong></p>
<p><br />
我们要写一个函数，往一个指定的元素上面增加10个超链接。如果我们简单的直接插入10个超链接到元素上面，就会触发10次重解析。</p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); width: 98%; font-size: 13px;"><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;addAnchors(element)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;anchor;<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">10</span><span style="color: rgb(0, 0, 0);">;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;anchor&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;document.createElement('a');<br />
&nbsp;&nbsp;&nbsp;&nbsp;anchor.innerHTML&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;'test';<br />
&nbsp;&nbsp;&nbsp;&nbsp;element.appendChild(anchor);<br />
&nbsp;&nbsp;}<br />
}</span></div>
<br />
<p><strong>解决方案</strong></p>
<p>要解决这个问题，我们要先创建一个文档片段对象，然后把每个新创建的超链接都插入到它里面去。当我们把文档片段对象用appendChild命令插 入到指定的节点时，这个文档片段对象的所有子节点就一起被插入到指定的元素里面，而且只需要触发一次重解析。<br />
</p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); width: 98%; font-size: 13px;"><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;addAnchors(element)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;anchor,&nbsp;fragment&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;document.createDocumentFragment();<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">10</span><span style="color: rgb(0, 0, 0);">;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;anchor&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;document.createElement('a');<br />
&nbsp;&nbsp;&nbsp;&nbsp;anchor.innerHTML&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;'test';<br />
&nbsp;&nbsp;&nbsp;&nbsp;fragment.appendChild(anchor);<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;element.appendChild(fragment);<br />
}</span></div>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=288</link>
			<title><![CDATA[转战杭州]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[My Life]]></category>
			<pubDate>Sun,28 Feb 2010 17:53:22 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=288</guid>
		<description><![CDATA[<p>终于，来到了杭州。</p>
<p>之前对这里是充满了很高的期望的。</p>
<p>晚上8点多到达，然后乘公车来到同事家。由于是晚上吧，感觉整个城市有点偏暗，另外，公车司机素质貌似与深圳那边的同行们有一定的差距，需要多多学习提高。</p>
<p>次日，随同事简单逛到了京杭大运河边上，看到河面上来往频繁的货轮和客轮，没想到，这条古运河仍然充满了活力，赞！</p>
<p>旁边是环球中心和浙江省博物馆，进到博物馆看看，布置的很有感觉，下次记得带相机去。</p>
<p>今天办理入职，一切顺利！^_^</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=287</link>
			<title><![CDATA[AutoSizeBox 自适应父节点大小的类]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Mon,01 Feb 2010 17:23:06 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=287</guid>
		<description><![CDATA[<p>在做WEB APP项目的时候，经常会遇到一些自适应大小的需求，简单实现了一个，使用需谨慎！</p>
<h1 class="hd">自适应父节点大小类 - ARBox</h1>
<div class="bd"><dl><dt><strong>使用此方法的DOM元素：</strong> </dt><dd>将自动适应其父节点的宽和高; </dd><dd>如果指定了width=[整数|百分数]和height的值，将按给定的值调整; </dd><dd>该元素将被自动设置成为overflow:hidden; </dd><dd>支持rows=&quot;25,*25&quot;和cols=&quot;20%,*&quot;属性 </dd><dd>如果设置了rows或cols，其childNodes将按相应的值自动调整 </dd><dd>尺寸调整过的子节点，同时也会被自动设置成为overflow:hidden; </dd></dl><dl><dt><strong>嵌套的设置：</strong> </dt><dd>嵌套与本类无关，需要另行编写相关队列实现 </dd><dd>可使用自定义属性（如level）进行抓取，按level优先级存入队列 </dd><dd>window resize的时候可以按队列顺序进行调整 </dd></dl><dl><dt><strong>注意：</strong> </dt><dd>请声明DTD </dd><dd>最好在使用了reset样式后使用 </dd><dd>请酌情使用或参考 </dd></dl></div>
<p>在线演示：<a target="_blank" href="http://www.jslab.org.cn/?tag=AutoSizeBox">http://www.jslab.org.cn/?tag=AutoSizeBox</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=286</link>
			<title><![CDATA[border none的兼容处理]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Mon,01 Feb 2010 15:31:29 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=286</guid>
		<description><![CDATA[<h2>最近为<a target="_blank" href="http://www.easyui.org.cn">easyui</a>添加了一个方法<a target="_blank" href="http://www.easyui.org.cn/#getMarginPaddingBorder">getmpb</a>，用来取DOM元素的Margin,Padding和Border。</h2>
<p>&nbsp;在处理border的时候遇到了浏览器兼容的问题，给我们&ldquo;找麻烦&rdquo;的是<strong>Opera</strong>同学！</p>
<p><strong>问题描述：</strong></p>
<p><strong>有DOM对象：dobj，当此对象未设置border样式的时候，我们通过dobj.currentStyle.borderWidth得到的值会是3，当我们设置此对象的border:none时，dobj.currentStyle.borderWidth仍然会是3。</strong></p>
<p>当然，在浏览器渲染的时候并不会因为此问题而将border显示出来，因为borderStyle和borderColor都没有设置。</p>
<p>可以考虑在以后的CSS书写中，将border:none更改为border:0，这样就可以保证各浏览器在JS取border值时的一致了。</p>
<p>在<a target="_blank" href="http://www.easyui.org.cn/#getMarginPaddingBorder">easyui.getmpb</a>中对opera的此问题单独做了修正，所以可以放心使用。^_^</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=285</link>
			<title><![CDATA[入手WII]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[My Life]]></category>
			<pubDate>Wed,27 Jan 2010 20:07:09 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=285</guid>
		<description><![CDATA[<p>&nbsp;一个偶然的机会，去到一家游戏机销售店，体验了一下WII的新超级玛利兄弟，后来又体验了一下体感操作的运动系列游戏，立即被它给吸引，入手一台，说是给儿子玩，怕是要和他抢着玩了！ ^_^</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=284</link>
			<title><![CDATA[重生]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[My Life]]></category>
			<pubDate>Mon,18 Jan 2010 17:57:34 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=284</guid>
		<description><![CDATA[<p>服务器杯具鸟一个月，另辟蹊径，重生！</p>
<p>最近更新了<a target="_blank" href="http://www.easyui.org.cn">EasyUI</a>及相关组件，<a target="_blank" href="http://www.easyui.org.cn/dhatv_demo.html">dhATV4</a>有重大更新！</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=283</link>
			<title><![CDATA[EasyChange兼容处理input控件值改变事件]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Wed,06 Jan 2010 16:47:12 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=283</guid>
		<description><![CDATA[<h1>EasyChange兼容处理input控件值改变事件</h1>
<dl><dt>兼容处理：</dt><dd>手动输入事件捕获：手动输入内容时会触发</dd><dd>复制粘贴事件捕获：复制粘贴内容时会触发</dd><dd>程序设置事件捕获：javascript程序动态设置内容时会触发</dd><dd>拖入事件捕获：选定内容拖入时会触发<br />
</dd></dl>
<p>原型代码：</p>
<p>var easychange = function(foochange){<br />
&nbsp;&nbsp;&nbsp; if(!foochange||foochange.constructor!=Function){return;}<br />
&nbsp;&nbsp;&nbsp; try{this.watch(&quot;value&quot;,function(id,oldval,newval){foochange(newval);return newval;});}catch(e){}<br />
&nbsp;&nbsp;&nbsp; this.setAttribute('oninput','('+foochange.toString()+')(this.value)');<br />
&nbsp;&nbsp;&nbsp; this.onpropertychange = function(){foochange(this.value);};<br />
&nbsp;&nbsp;&nbsp; this.onmousemove = function(){foochange(this.value);};<br />
&nbsp;&nbsp;&nbsp; this.onkeyup = function(){foochange(this.value);};<br />
};</p>
<p>在线演示：<a href="http://www.jslab.org.cn/?tag=easyChange" target="_blank">http://www.jslab.org.cn/?tag=easyChange</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=282</link>
			<title><![CDATA[JavaScript版Bresenham直线,圆,椭圆算法]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Tue,05 Jan 2010 16:03:12 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=282</guid>
		<description><![CDATA[<h1 style="line-height: 1.8">Bresenham图形算法JavaScript版本</h1>
<p><strong>/*Bresenham画圆算法*/<br />
</strong>var arc = function(x0,y0,r){/*起点坐标x0,y0,半径*/<br />
&nbsp;var p,x,y,i,ret = [];<br />
&nbsp;p = 3-2*r,x = 0,y = r,i = r;<br />
&nbsp;for(;x&lt;=y;){<br />
&nbsp;&nbsp;ret.push([x+i+x0,y+i+y0]);<br />
&nbsp;&nbsp;ret.push([-x+i+x0,-y+i+y0]);<br />
&nbsp;&nbsp;ret.push([-x+i+x0,y+i+y0]);<br />
&nbsp;&nbsp;ret.push([x+i+x0,-y+i+y0]);<br />
&nbsp;&nbsp;ret.push([y+i+x0,x+i+y0]);<br />
&nbsp;&nbsp;ret.push([-y+i+x0,x+i+y0]);<br />
&nbsp;&nbsp;ret.push([-y+i+x0,-x+i+y0]);<br />
&nbsp;&nbsp;ret.push([y+i+x0,-x+i+y0]);<br />
&nbsp;&nbsp;if(p&lt;0){<br />
&nbsp;&nbsp;&nbsp;p = p+4*x+6;<br />
&nbsp;&nbsp;}else{<br />
&nbsp;&nbsp;&nbsp;y--,p = p+4*(x-y)+10;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;x++;<br />
&nbsp;}<br />
&nbsp;return ret.slice(0);<br />
};</p>
<p><br />
<strong>/*Bresenham画椭圆算法*/</strong><br />
var ellipse = function(px,py,rx,ry){/*起点坐标px,py,x轴半径rx,y轴半径ry*/<br />
&nbsp;px = px+rx,py = py+ry;<br />
&nbsp;var x = 0,y = ry,rx2 = rx*rx,ry2 = ry*ry,ret = [];<br />
&nbsp;var dx = ry2/Math.sqrt(ry2+rx2),p = ry2-rx2*ry;<br />
&nbsp;while(dx&lt;=y){<br />
&nbsp;&nbsp;ret.push([px+x,py+y]);<br />
&nbsp;&nbsp;ret.push([px+x,py-y]);<br />
&nbsp;&nbsp;ret.push([px-x,py+y]);<br />
&nbsp;&nbsp;ret.push([px-x,py-y]);<br />
&nbsp;&nbsp;if(p&lt;=0){<br />
&nbsp;&nbsp;&nbsp;++x;<br />
&nbsp;&nbsp;}else{<br />
&nbsp;&nbsp;&nbsp;++x,--y;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;p = ry2*(x+1)*(x+1)+rx2*(y*y-y)-rx2*ry2;<br />
&nbsp;}<br />
&nbsp;p = ry2*(x*x+x)+rx2*(y*y-y)-rx2*ry2;<br />
&nbsp;while(y&gt;0){<br />
&nbsp;&nbsp;ret.push([px+x,py+y]);<br />
&nbsp;&nbsp;ret.push([px+x,py-y]);<br />
&nbsp;&nbsp;ret.push([px-x,py+y]);<br />
&nbsp;&nbsp;ret.push([px-x,py-y]);<br />
&nbsp;&nbsp;if(p&gt;=0){<br />
&nbsp;&nbsp;&nbsp;--y,p = p-2*rx2*y-rx2;<br />
&nbsp;&nbsp;}else{<br />
&nbsp;&nbsp;&nbsp;--y,++x,p = p-2*rx2*y-rx2+2*ry2*x+2*ry2;<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
&nbsp;ret.push([px+x,py]);<br />
&nbsp;ret.push([px-x,py]);<br />
&nbsp;return ret.slice(0);<br />
};</p>
<p><br />
<strong>/*Bresenham画直线算法*/<br />
</strong>var line = function(x1,y1,x2,y2){/*起点坐标x1,y1,终点坐标x2,y2*/<br />
&nbsp;var dx,dy,h,x,y,t,ret = [];<br />
&nbsp;if(x1&gt;x2){x1 = [x2,x2=x1][0],y1 = [y2,y2=y1][0];}<br />
&nbsp;dx = x2-x1,dy = y2-y1,x = x1,y = y1;<br />
&nbsp;if(!dx){<br />
&nbsp;&nbsp;t = (y1&gt;y2)?-1:1;<br />
&nbsp;&nbsp;while(y!=y2){ret.push([x,y]);y += t;}<br />
&nbsp;&nbsp;return ret.slice(0);<br />
&nbsp;}<br />
&nbsp;if(!dy){<br />
&nbsp;&nbsp;while(x!=x2){ret.push([x,y]);x++;}<br />
&nbsp;&nbsp;return ret.slice(0);<br />
&nbsp;}<br />
&nbsp;if(dy&gt;0){<br />
&nbsp;&nbsp;if(dy&lt;=dx){<br />
&nbsp;&nbsp;&nbsp;h = 2*dy-dx,ret.push([x,y]);<br />
&nbsp;&nbsp;&nbsp;while(x!=x2){<br />
&nbsp;&nbsp;&nbsp;&nbsp;if(h&lt;0){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h += 2*dy;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}else{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y++,h += 2*(dy-dx);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;x++,ret.push([x,y]);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}else{<br />
&nbsp;&nbsp;&nbsp;h = 2*dx-dy,ret.push([x,y]);<br />
&nbsp;&nbsp;&nbsp;while(y!=y2){<br />
&nbsp;&nbsp;&nbsp;&nbsp;if(h&lt;0){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h += 2*dx;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}else{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++x,h += 2*(dx-dy);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;y++,ret.push([x,y]);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;}else{<br />
&nbsp;&nbsp;t = -dy;<br />
&nbsp;&nbsp;if(t&lt;=dx){<br />
&nbsp;&nbsp;&nbsp;h = 2*dy+dx,ret.push([x,y]);<br />
&nbsp;&nbsp;&nbsp;while(x!=x2){<br />
&nbsp;&nbsp;&nbsp;&nbsp;if(h&lt;0){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h += 2*(dy+dx),y--;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}else{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h += 2*dy;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;x++,ret.push([x,y]);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}else{<br />
&nbsp;&nbsp;&nbsp;dy = -dy,dx = -dx,y = y2,x = x2,ret.push([x,y]),h = 2*dx+dy;<br />
&nbsp;&nbsp;&nbsp;while(y!=y1){<br />
&nbsp;&nbsp;&nbsp;&nbsp;if(h&lt;0){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h += 2*(dx+dy),x--;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}else{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h += 2*dx;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;y++,ret.push([x,y]);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
&nbsp;return ret.slice(0);<br />
};<br />
&nbsp;</p>
<p>参见：<a target="_blank" href="http://www.jslab.org.cn/?tag=Bresenham">Bresenham直线,圆,椭圆算法</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=281</link>
			<title><![CDATA[The Canvas 2D API 1.0 Specification]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Tue,05 Jan 2010 15:44:18 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=281</guid>
		<description><![CDATA[<h1>Canvas 2D API Specification 1.0</h1>
<!--:ZZZ Update: W3C Editor's Draft 25 August 2009 -->
<h2 class="no-num no-toc">W3C Editor's Draft 21 October 2009</h2>
<p><strong>The <dfn id="canvas-interface-element"><code>canvas interface</code></dfn> element</strong></p>
<pre class="idl">
interface <dfn id="canvaselement">CanvasElement</dfn> : <font color="#660099">Element</font> {
      attribute unsigned long <font color="#660099">width</font>;
      attribute unsigned long <font color="#660099">height</font>;

      Object <font color="#660099">getContext</font>(in DOMString contextId);//2d

      DOMString <font color="#660099">toDataURL</font>(optional in DOMString type, in any... args);
      //image/png, quality level 0.0 to 1.0 ...
};</pre>
<p><strong>The 2D Drawing Context</strong></p>
<pre class="idl">
interface <dfn id="canvasrenderingcontext2d">CanvasRenderingContext2D</dfn> {

  // back-reference to the canvas 
  readonly attribute <font color="#0000cc">HTMLCanvasElement</font> <font color="#660099">canvas</font>;

  // state 
  void <font color="#660099">restore</font>(); // pop state stack and restore state
  void <font color="#660099">save</font>(); 	  // push state on state stack 
        <!--
          // v4 we've also received requests for:
                  attribute boolean <span title="dom-context-2d-forceHighQuality">forceHighQuality</span> // (default false)
          // when enabled, it would prevent the UA from falling back on lower-quality but faster rendering routines
          // useful e.g. for when an image manipulation app uses <canvas> both for UI previews and the actual work
        -->
  // transformations (default transform is the identity matrix)
  void <font color="#660099">rotate</font>(in float angle);
  void <font color="#660099">scale</font>(in float x, in float y);

  void <font color="#660099">setTransform</font>(in float m11, in float m12, in float m21, in float m22, 
  in float dx, in float dy);

  void <font color="#660099">transform</font>(in float m11, in float m12, in float m21, in float m22, 
  in float dx, in float dy);

  void <font color="#660099">translate</font>(in float x, in float y);
        <!--
          // v4 we've also received requests for:
          void skew(...);
          void reflect(...); // or mirror(...)
        -->
  // compositing 
  attribute float <font color="#660099">globalAlpha</font>; // (default 1.0)
  attribute DOMString <font color="#660099">globalCompositeOperation</font>; // (default source-over)
        <!--
          // v4 we've also received requests for:
          - turning off antialiasing to avoid seams when patterns are painted next to each other
            - might be better to overdraw?
            - might be better to just draw at a higher res then downsample, like for 3d?
          - nested layers
            - the ability to composite an entire set of drawing operations with one shadow all at once http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2008-August/015567.html
        -->
  // colors and styles 
  attribute any <font color="#660099">fillStyle</font>; // (default black)
  attribute any <font color="#660099">strokeStyle</font>; // (default black)
  <font color="#660099">CanvasGradient</font> <font color="#660099">createLinearGradient</font>(in float x0, in float y0, in float x1, in float y1);

  <font color="#660099">CanvasGradient</font> <font color="#660099">createRadialGradient</font>(in float x0, in float y0, in float r0, in float x1, 
  in float y1, in float r1);

  <font color="#660099">CanvasPattern</font> <font color="#660099">createPattern</font>(in <font color="#0000cc">HTMLImageElement</font> image, in DOMString repetition);
  <font color="#660099">CanvasPattern</font> <font color="#660099">createPattern</font>(in <font color="#0000cc">HTMLCanvasElement</font> image, in DOMString repetition);
  <font color="#660099">CanvasPattern</font> <font color="#660099">createPattern</font>(in <font color="#0000cc">HTMLVideoElement</font> image, in DOMString repetition);

  // line st<span class="style1"><font style="background-color: #eeeeee">yles</font></span> 
  attribute DOMString <font color="#660099">lineCap</font>; // &quot;butt&quot;, &quot;round&quot;, &quot;square&quot; (default &quot;butt&quot;)
  attribute DOMString <font color="#660099">lineJoin</font>; // &quot;miter&quot;, &quot;round&quot;, &quot;bevel&quot;  (default &quot;miter&quot;)
  attribute float <font color="#660099">lineWidth</font>; // (default 1)
  attribute float <font color="#660099">miterLimit</font>; // (default 10)

  // shadows 
  attribute float <font color="#660099">shadowBlur</font>; // (default 0)
  attribute DOMString <font color="#660099">shadowColor</font>; // (default transparent black)
  attribute float <font color="#660099">shadowOffsetX</font>; // (default 0)
  attribute float <font color="#660099">shadowOffsetY</font>; // (default 0)

  // rects 
  void <font color="#660099">clearRect</font>(in float x, in float y, in float w, in float h);
  void <font color="#660099">fillRect</font>(in float x, in float y, in float w, in float h);
  void <font color="#660099">strokeRect</font>(in float x, in float y, in float w, in float h);

  // Complex shapes (paths) API 
  void <font color="#660099">arc</font>(in float x, in float y, in float radius, in float startAngle, in float endAngle,
  in boolean anticlockwise);

  void <font color="#660099">arcTo</font>(in float x1, in float y1, in float x2, in float y2, in float radius);
  void <font color="#660099">beginPath</font>();

  void <font color="#660099">bezierCurveTo</font>(in float cp1x, in float cp1y, in float cp2x, in float cp2y, in float x,
  in float y);

  void <font color="#660099">clip</font>();
  void <font color="#660099">closePath</font>();
  void <font color="#660099">fill</font>();
  void <font color="#660099">lineTo</font>(in float x, in float y);
  void <font color="#660099">moveTo</font>(in float x, in float y);
  void <font color="#660099">quadraticCurveTo</font>(in float cpx, in float cpy, in float x, in float y);
  void <font color="#660099">rect</font>(in float x, in float y, in float w, in float h);
  void <font color="#660099">stroke</font>();
  boolean <font color="#660099">isPointInPath</font>(in float x, in float y);

  // text 
  attribute DOMString <font color="#660099">font</font>; // (default 10px sans-serif)
  attribute DOMString <font color="#660099">textAlign</font>; // &quot;start&quot;, &quot;end&quot;, &quot;left&quot;, &quot;right&quot;,
  &quot;center&quot; (default: &quot;start&quot;)

  attribute DOMString <font color="#660099">textBaseline</font>; // &quot;top&quot;, &quot;hanging&quot;, &quot;middle&quot;,
  &quot;alphabetic&quot;, &quot;ideographic&quot;,&quot;bottom&quot; (default: &quot;alphabetic&quot;)

  void <font color="#660099">fillText</font>(in DOMString text, in float x, in float y, optional in float maxWidth);
  <font color="#660099">TextMetrics</font> <font color="#660099">measureText</font>(in DOMString text);
  void <font color="#660099">strokeText</font>(in DOMString text, in float x, in float y, optional in float maxWidth);<!-- v4DVT void <span title="dom-context-2d-fillVerticalText">fillVerticalText</span>(in DOMString text, in float x, in float y, optional in float maxHeight);
          void <span title="dom-context-2d-strokeVerticalText">strokeVerticalText</span>(in DOMString text, in float x, in float y, optional in float maxHeight); -->

  // drawing images 
  void <font color="#660099">drawImage</font>(in <font color="#0000cc">HTMLImageElement</font> image, in float dx, in float dy, optional in float dw,
  in float dh);

  void <font color="#660099">drawImage</font>(in <font color="#0000cc">HTMLImageElement</font> image, in float sx, in float sy, in float sw, in float
  sh, in float dx, in float dy, in float dw, in float dh);

  void <font color="#660099">drawImage</font>(in <font color="#0000cc">HTMLCanvasElement</font> image, in float dx, in float dy, optional in float dw,
  in float dh);

  void <font color="#660099">drawImage</font>(in <font color="#0000cc">HTMLCanvasElement</font> image, in float sx, in float sy, in float sw,
  in float sh, in float dx, in float dy, in float dw, in float dh);

  void <font color="#660099">drawImage</font>(in <font color="#0000cc">HTMLVideoElement</font> image, in float dx, in float dy, optional in float dw,
  in float dh);

  void <font color="#660099">drawImage</font>(in <font color="#0000cc">HTMLVideoElement</font> image, in float sx, in float sy, in float sw,
  in float sh, in float dx, in float dy, in float dw, in float dh);

  // pixel manipulation
  <font color="#660099">ImageData</font> <font color="#660099">createImageData</font>(in float sw, in float sh);
  <font color="#660099">ImageData</font> <font color="#660099">createImageData</font>(in <font color="#660099">ImageData</font> imagedata);
  <font color="#660099">ImageData</font> <font color="#660099">getImageData</font>(in float sx, in float sy, in float sw, in float sh);
  void <font color="#660099">putImageData</font>(in <font color="#660099">ImageData</font> imagedata,in float dx,in float dy,optional in float dirtyX,
  in float dirtyY, in float dirtyWidth, in float dirtyHeight);
};

interface <dfn id="canvasgradient">CanvasGradient</dfn> {
  // opaque object 
  void <font color="#660099">addColorStop</font>(in float offset, in DOMString color);
};

interface <dfn id="canvaspattern">CanvasPattern</dfn> {
  // opaque object
};

interface <dfn id="textmetrics">TextMetrics</dfn> {
  readonly attribute float <font color="#660099">width</font>;
};

interface <dfn id="imagedata">ImageData</dfn> {
  readonly attribute <font color="#660099">CanvasPixelArray</font> <font color="#660099">data</font>;
  readonly attribute unsigned long <font color="#660099">height</font>;
  readonly attribute unsigned long <font color="#660099">width</font>;
};

interface <dfn id="canvaspixelarray">CanvasPixelArray</dfn> {
  readonly attribute unsigned long <font color="#660099">length</font>;
  <font color="#660099">getter</font> octet (in unsigned long index);
  <font color="#660099">setter</font> void (in unsigned long index, in octet value);
};
}</pre>
<p>See also: <a target="_blank" href="http://dev.w3.org/html5/canvas-api/canvas-2d-api.html"><font color="#660099">http://dev.w3.org/html5/canvas-api/canvas-2d-api.html</font></a></p>
<h3><a target="_blank" href="http://www.easyui.org.cn/easycanvaspainter/painter.html">Easy Canvas Painter Demo</a></h3>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=280</link>
			<title><![CDATA[EasyUI新组件EasySlider]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Mon,04 Jan 2010 15:57:53 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=280</guid>
		<description><![CDATA[<h1><span style="font-size: 20px">EasySlider - EasyUI Components</span></h1>
<p><strong>依赖</strong> <br />
&nbsp; &nbsp; http://www.easyui.org.cn/easyui.js <br />
&nbsp; &nbsp; http://www.easyui.org.cn/easydragdrop.js <br />
<br />
<strong>实例化</strong> <br />
&nbsp; &nbsp; new easySlider(100,0,100,46,'left','easyslider/',dalpha); <br />
&nbsp; &nbsp; new easySlider(默认值，起始值，结束值，上下左右四个方向，滑块样式目录，父节点) <br />
<br />
<strong>事件</strong> <br />
&nbsp; &nbsp; ondrag <br />
&nbsp; &nbsp; 滑块实例.ondrag = function(n){}; <br />
&nbsp; &nbsp; 参数n由滑块对象自动传出，只要指定该形参即可使用。 <br />
<br />
<strong>方法</strong> <br />
&nbsp; &nbsp; setValue(整数值value) <br />
&nbsp; &nbsp; getValue() <br />
<br />
<strong>EasySlider在线演示：</strong><a title="http://www.easyui.org.cn/easyslider.html" href="http://www.easyui.org.cn/easyslider.html" target="_blank"><strong><font color="#002d93">http://www.easyui.org.cn/easyslider.html</font></strong></a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=279</link>
			<title><![CDATA[Javascript霓虹灯贺新年]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Mon,28 Dec 2009 16:17:04 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=279</guid>
		<description><![CDATA[<p>新年在即，2009年参与了CSDN编程游戏-新年烟火的编写，今年我们玩霓虹灯！</p>
<p>祝大家新年快乐！</p>
<p>Happy New Year!</p>
<p><a target="_blank" href="http://www.w3cgroup.com/code/neon.html">开启2010新年JavaScript霓虹灯!</a></p>
<p><a target="_blank" href="http://www.w3cgroup.com/code/fireworks.html">燃放2009新年JavaScript烟火!</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=278</link>
			<title><![CDATA[JavaScript Swap X Game实现原理]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Sat,12 Dec 2009 01:01:31 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=278</guid>
		<description><![CDATA[<h3>圣诞、元旦将至，简单写了一个小游戏来应应景。</h3>
<p><strong>先上图，简单制作了4种皮肤：圣诞、WIN32系统图标、中国风和CSDN水园头像代表 ^_^</strong></p>
<p><strong><a target="_blank" href="http://www.v-ec.com/games/swapx/default.htm"><img alt="javascript swap x game - xmas skin" border="0" src="http://www.w3cgroup.com/attachments/month_0912/92009121205657.jpg" /></a></strong></p>
<p><strong><a target="_blank" href="http://www.v-ec.com/games/swapx/default.htm"><img alt="javascript swap x game - win32 icon skin" border="0" src="http://www.w3cgroup.com/attachments/month_0912/u2009121205733.jpg" /></a></strong></p>
<p><strong><a target="_blank" href="http://www.v-ec.com/games/swapx/default.htm"><img alt="javascript swap x game - chinaz skin" border="0" src="http://www.w3cgroup.com/attachments/month_0912/r2009121205717.jpg" /></a></strong></p>
<p><strong><a target="_blank" href="http://www.v-ec.com/games/swapx/default.htm"><img alt="javascript swap x game - csdn skin" border="0" src="http://www.w3cgroup.com/attachments/month_0912/e2009121205745.jpg" /></a></strong></p>
<p><strong><a target="_blank" href="http://www.v-ec.com/games/swapx/default.htm"><img alt="javascript swap x game - csdn skin" border="0" src="http://www.w3cgroup.com/attachments/month_0912/y2009121205759.jpg" /></a></strong></p>
<p><strong><a target="_blank" href="http://www.v-ec.com/games/swapx/default.htm"><img alt="javascript swap x game - csdn skin" border="0" src="http://www.w3cgroup.com/attachments/month_0912/t2009121205815.jpg" /></a></strong></p>
<p><strong>Swap X</strong>，不知道要为这个游戏取个什么名字，貌似没有专门的名字，有的叫<strong>魔法寿司</strong>，有的叫<strong>碰碰球</strong>，不同的实现有不同的名字，只好通过它的游戏方式来给它命名了，通过交换两个东东来消除相同的部分，所以就叫它Swap X了。</p>
<p><strong>游戏规则：</strong></p>
<p>通过交换水平及垂直方向上的两个物件，如果交换后的行或列中有连续3个（视具体实现而定，有的是4个）相同的，则消除它们，然后填充消除的部分，继续游戏。</p>
<p>所以，在这个游戏中，我们至少要有一个能够找出这些相同物件的算法，而且，考虑到有时候消除后，游戏界面中可能不存在可以继续消除的玩法了，这时候，我们还会需要一个能够检测游戏界面中是否还能继续玩下去的算法，这个算法可以同时用在游戏提示上。比如，使用提示时，则提示玩家某个物件可以进行交换。</p>
<p>查找相同数据的算法仍然沿用了上一个游戏&ldquo;<a target="_blank" href="http://www.v-ec.com/games/drmario/default.htm">玛丽医生</a>&rdquo;中的算法（参见：<a target="_blank" href="http://www.jslab.org.cn/?tag=getsamelistfrommartix">http://www.jslab.org.cn/?tag=getsamelistfrommartix</a>），在本游戏中只做了一点点改变，即加上了起始维数。因为本游戏中的数据格式由两部分组成，hide区域数据和show区域数据。</p>
<p>整个游戏是一个完整的表格，通过对折，将上半部分划分为hide区域，下半部分划分为show区域。</p>
<p>hide区域被用作预存下一次需要掉落到show区域中被消除的空格中去的数据，此部分对玩家不可见。</p>
<p>show区域则作为玩家的操作界面。</p>
<p>为了保持数据的连贯性，在算法中，我们对这两个区域的数据还是视为整个表格的数据，以免未来在不同的数据栈中切换操作，所以，查找相同数据算法及后面的检测是否可以继续交换的算法都有一个起始维数用于对该数据进行切割，以取到游戏操作部分的数据。</p>
<p>由于本游戏使用Table元素作为游戏原型，所以在处理掉落及交换的时候，视觉效果不太好处理。虽然可以加上一些额外的补偿，不过由于偶比较懒，凑合着能玩，就没去做这部分优化了。</p>
<p>好了，一起来试试这个游戏吧：</p>
<p><a target="_blank" href="http://www.v-ec.com/games/swapx/default.htm">http://www.v-ec.com/games/swapx/default.htm</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=277</link>
			<title><![CDATA[JavaScript版后缀表达式(逆波兰式)24点算法]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Sat,05 Dec 2009 19:13:12 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=277</guid>
		<description><![CDATA[<h1 style="line-height: 1.5">利用后缀表达式（逆波兰式）算24点的JavaScript版算法</h1>
<p><em>思想：</em></p>
<p><strong>4个数字的排列，加上3个运算符的排列，使用后缀表达式的表现</strong>如下：</p>
<p>情形一：</p>
<p>1,2,3,4,+,-,* =&gt; 24*24*4</p>
<p>情形二：</p>
<p>1,2,3,+,4,-,* =&gt; 24*24*4</p>
<p>情形三：</p>
<p>1,2,3,+,-,4,* =&gt; 24*24*4</p>
<p>情形四：</p>
<p>1,2,+,3,-,4,* =&gt; 24*24*4</p>
<p>情形五：</p>
<p>1,2,+,3,4,-,* =&gt; 24*24*4</p>
<p>每种表现形式后面的24为4个数字的排列，4个运算符的排列，后面的4为运算符可能出现的4种情形，以第一种情况为例：</p>
<p>1,2,3,4,+,-,*</p>
<p>1,2,3,4,+,-,+</p>
<p>1,2,3,4,+,+,-</p>
<p>1,2,3,4,+,+,+</p>
<p>至此，大概的算法思想可以总结如下：</p>
<p><strong>声明数据栈ds，保存要计算数字的排列结果；</strong></p>
<p><strong>声明算符栈os，保存四则算符的排列结果；</strong></p>
<p><strong>遍历数据栈，每次按上面列出的后缀表达式数据格式，通过遍历算符栈进行整理组合，直到结束，即可得到所有的计算表达式。</strong></p>
<p><strong>将这些表达式求值，将符合要求（即等于24，由于计算精度问题，大于23.99的结果也算正确）的结果保留，最后还需要一个将后缀表达式转换为中缀表达式的过程。</strong></p>
<p>参见：</p>
<p><a target="_blank" href="http://www.w3cgroup.com/code/24.htm">JavaScript版后缀表达式(逆波兰式)24点算法实现</a></p>
<p><a target="_blank" href="http://www.w3cgroup.com/article.asp?id=276">编译原理-中缀表达式转后缀表达式(逆波兰式)</a></p>
<p><a target="_blank" href="http://www.w3cgroup.com/code/24_2.htm">生硬的全排列组合表达式实现24点算法</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=276</link>
			<title><![CDATA[编译原理-中缀表达式转后缀表达式(逆波兰式)]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Thu,03 Dec 2009 17:24:02 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=276</guid>
		<description><![CDATA[<h1 style="line-height: 1.5;">中缀表达式转后缀表达式(逆波兰式)算法，后缀表达式求值算法</h1>
<p>&nbsp;</p>
<pre>
3 + 4 * 5 - 6;
OS	DS
	3
+	3
+	34
*+	34
*+	345
+	345*
-	345*+
-	345*+6
	345*+6-


插入运算符 o 时，

如果优先级 o&gt;OS[0]，

则：遇到')'时，o2 = OS.shift(),DS.push(o2),DS.shift()，否则OS.unshift(o)；

否则o2 = OS.shift(),DS.push(o2),OS.unshift(o)，连续判断，直到OS[0]优先级&gt;o；


例

   
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #

1
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
  &uarr;
  OS       	DS
                   3
 
2
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
    &uarr;
  OS       	DS
   +              3
 
3
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
      &uarr;
  OS       	DS
   +              3 4

4
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
        &uarr;
  OS       	DS
   / 
   +              3 4

5
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
          &uarr;
  OS       	DS
   (
   / 
   +               3 4

6
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
            &uarr;
  OS       	DS
   (
   / 
   +               3 4 25

7
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
               &uarr;
  OS       	DS
   －
   (
   / 
   +               3 4 25

8
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
                 &uarr;
  OS       	DS

   (
   －
   (
   / 
   +               3 4 25

9
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
                   &uarr;
  OS       	DS
   (
   －
   (
   / 
   +               3 4 25 6


10
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
                     &uarr;
 
  OS       	DS
   *
   (
   －
   (
   / 
   +               3 4 25 6

11
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
                       &uarr;
  OS       	DS
  
   *
   (
   －
   (
   / 
   +               3 4 25 6 5

12
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
                         &uarr;
  OS       	DS
   －
   (
   / 
   +               3 4 25 6 5 *

12
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
                           &uarr;
  OS       	DS
   / 
   +               3 4 25 6 5 * -

13
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
                              &uarr;
  OS       	DS
   * 
   +               3 4 25 6 5 * - /

14
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
                                &uarr;
  OS       	DS
   * 
   +               3 4 25 6 5 * - / 8


15
  3 + 4 / ( 25 - ( 6 * 5 ) )  * 8 #
                                  &uarr;
  OS       	DS
                  3 4 25 6 5 * - / 8 * +
</pre>
<p>&nbsp;&lt;script type=&quot;text/javascript&quot;&gt;</p>
<p>&nbsp;</p>
<pre style="word-wrap: break-word;">
//中缀表达式转后缀表达式
var ie2se = function(mExp){
	var exp2array = function(exp){
		var ret = [];
		exp.replace(/([^\d])|(\d*)/g,function(s,a,b){if(a){ret.push(a);}if(b){ret.push(b)}});
		return ret.slice(0);
	};
	//将中缀表达式打散为数组形式
	var remExp = exp2array(mExp);
	//运算符栈和数据栈
	var OS = [],DS = [];
	//换算运算符优先级
	var r = /(?:([+-])|([*\/])|([\(\)]))/;
	var getPRI = function(o){
		r.test(o);
		return RegExp.$2?1:RegExp.$3?2:0;
	};
	var tmpItem = null,OSTop = null,pti = 0,ptt = 0;
	while(remExp.length){
		//取剩余表达式中第一个元素
		tmpItem = remExp.shift();
		OSTop = OS[0];
		if(isNaN(tmpItem)){//运算符
			pti = getPRI(tmpItem);
			ptt = getPRI(OSTop);
			if(pti&gt;ptt){//优先级高于OS[0]
				if(tmpItem!=')'){//运算符不是右括号
					OS.unshift(tmpItem);
				}else{
					DS.push(OS.shift());
					OS.shift();//丢掉'(';
				}
			}else{//优先级低于或等于OS[0]
				//循环判断，直至OS[0]优先级大于当前运算符
				while(OS.length&amp;&amp;OS[0]!='('&amp;&amp;pti&lt;=getPRI(OS[0])){
					DS.push(OS.shift());
				}
				OS.unshift(tmpItem);
			}
		}else{//数据
			DS.push(tmpItem);
		}
	}
	//剩余表达式为空后，将OS栈的元素都push到DS栈
	while(OS.length){DS.push(OS.shift());}
	return DS.slice(0);
};

//后缀表达式求值
var suffix_compute = function(suffixExp){
	var ret = suffixExp.slice(0);
	while(ret.length&gt;1){
		var idx = 0;//第一个运算符出现的位置
		for(var i=0;i&lt;ret.length;i++){if(isNaN(ret[i])){idx = i-2;break;}}
		//取出该位置前及其前两个元素
		var a = ret.splice(idx,1);
		var b = ret.splice(idx,1);
		var o = ret.splice(idx,1);
		//计算
		var e = eval('('+a+')'+o+'('+b+')');
		//计算结果插入到该位置
		ret.splice(idx,0,e);
	}
	return ret[0];
};

var me = '3+4/(25-(6*5))*8';
var se = ie2se(me);
var d = suffix_compute(se);
document.write('&lt;h3&gt;中缀表达式转后缀表达式计算结果：&lt;/h3&gt;'+me+' = '+eval(me)+'&lt;br/&gt;'+se+' = '+d);
&lt;/script&gt;</pre>
<p>&nbsp;</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=275</link>
			<title><![CDATA[ECMA-262中文版译文]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Thu,19 Nov 2009 15:54:27 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=275</guid>
		<description><![CDATA[<h1 style="line-height: 2">ECMA-262标准第3版-1999年11月</h1>
<h2>&nbsp;ECMA信息标准化和通信系统</h2>
<h3>&nbsp;ECMAScript语言说明</h3>
<p>联系方式： 电话：+41 22 849.60.00 传真：+41 22 849.60.01 网址：http://www.ecma.ch 邮箱：helpdesk@ecma.ch</p>
<p><strong>翻译：<a target="_blank" href="http://www.w3cgroup.com">W3CGROUP</a> 杜欢(dh20156, 2009年11月)&nbsp;</strong>&nbsp;</p>
<p>个人能力精力有限，欢迎大家批评指正，转载请注明出处！</p>
<p><strong>历史提要</strong></p>
<p>本标准的制定基于多个现有的技术，其中最著名的是JavaScript(Netscape)和JScript(Microsoft)。该语言是由当时在Netscape公司的Brendan Eich创造的，它第一次发布在该公司的Navigator2.0的浏览器中，并且在随后的所有版本浏览器中都有发布，微软公司在IE3.0的时候才开始引入并在以后的所有版本中使用它。</p>
<p>本标准的发展始于1996年11月。第一版在1997年6月被ECMA General Assembly采纳。</p>
<p>本标准在1998年4月通过快速通道提交到ISO/IEC JTC 1并被采纳为国际标准ISO/IEC 16262。第一版和第二版之间的编辑有着本质的变化。</p>
<p>本文档是标准第三版的定义，包括了强大的正则表达式，更好的字符串处理，新的控制语句，try/catch例外处理，更简洁明了的错误信息，格式化数字输出，并对即将到来的国际化工具和未来的语言增长进行了微调。</p>
<p>对该语言的工作还没有结束，科技委员会正在做具有重大意义的优化，包括在互联网上创建和使用脚本的机制，和其他的标准相互协调，比如W3C组织和无线应用协议论坛等等。</p>
<p>本标准在1999年11月被ECMA General Assembly接受采纳为ECMA-262第3版。</p>
<p><strong>目录</strong></p>
<p><a href="http://www.v-ec.com/dh20156/#1">1. 范围 </a><br />
<a href="http://www.v-ec.com/dh20156/#2">2. 一致性 </a><br />
<a href="http://www.v-ec.com/dh20156/#3">3. 参考 </a><br />
<a href="http://www.v-ec.com/dh20156/#4">4. 概述 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.1">4.1 WEB脚本 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.2">4.2 语言概述 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.2.1">4.2.1 对象 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3">4.3 定义 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.1">4.3.1 类型 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.2">4.3.2 原始值 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.3">4.3.3 对象 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.4">4.3.4 构造函数 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.5">4.3.5 原型 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.6">4.3.6 原生对象 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.7">4.3.7 内置对象 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.8">4.3.8 宿主对象 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.9">4.3.9 Undefined值 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.10">4.3.10 Undefined类型 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.11">4.3.11 Null值 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.12">4.3.12 Null类型 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.13">4.3.13 Boolean值 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.14">4.3.14 Boolean类型 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.15">4.3.15 Boolean对象 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.16">4.3.16 String值 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.17">4.3.17 String类型 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.18">4.3.18 String对象 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.19">4.3.19 Number值 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.20">4.3.20 Number类型 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.21">4.3.21 Number对象 </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.22">4.3.22 Infinity </a><br />
<a href="http://www.v-ec.com/dh20156/#4.3.23">4.3.23 NaN </a><br />
5. 符号约定 <br />
5.1 语法和词法 <br />
5.1.1 上下文无关文法 <br />
5.1.2 RegExp正则表达式的词汇和语法 <br />
5.1.3 数字、字符串语法 <br />
5.1.4 语法句法 <br />
5.1.5 语法符号 <br />
5.2 算法约定 <br />
6. 源文 <br />
7. 词法约定 <br />
7.1 Unicode 格式字符 <br />
7.2 空格 <br />
7.3 行尾 <br />
7.4 注释 <br />
7.5 特征 <br />
7.5.1 保留字 <br />
7.5.2 关键词 <br />
7.5.3 未来保留字 <br />
7.6 标识符 <br />
7.7 标点 <br />
7.8 字面量 <br />
7.8.1 Null字面量 <br />
7.8.2 Boolean字面量 <br />
7.8.3 Numeric字面量 <br />
7.8.4 String字面量 <br />
7.8.5 正则表达式字面量 <br />
7.9 自动插入分号 <br />
7.9.1 自动插入分号规则 <br />
7.9.2 自动插入分号示例 <br />
8. 类型 <br />
8.1 Undefined类型 <br />
8.2 Null类型 <br />
8.3 Boolean类型 <br />
8.4 String类型 <br />
8.5 Number类型 <br />
8.6 Object类型 <br />
8.6.1 property属性 <br />
8.6.2 内部propertys和methods <br />
8.7 引用类型 <br />
8.7.1 GetValue(V) <br />
8.7.2 PutValue(V,W) <br />
8.8 List类型 8.9 Completion类型 <br />
9. 类型转换 <br />
9.1 转为原始(primitive)类型 <br />
9.2 转为Boolean类型 <br />
9.3 转为Number类型 <br />
9.3.1 String类型转为Number类型 <br />
9.4 转为整型 <br />
9.5 转为32位整型 <br />
9.6 转为32位无符号整型 <br />
9.7 转为16位无符号整型 <br />
9.8 转为String类型 <br />
9.8.1 Number类型转为String类型 <br />
9.9 转为Object <br />
10. 执行环境 <br />
10.1 定义 <br />
10.1.1 函数对象 <br />
10.1.2 可执行代码类型 <br />
10.1.3 变量 <br />
10.1.4 作用域链和标识符确定 <br />
10.1.5 全局对象 <br />
10.1.6 活动对象 <br />
10.1.7 This <br />
10.1.8 Arguments对象 <br />
10.2 进入执行环境 <br />
10.2.1 全局代码 <br />
10.2.2 Eval代码 <br />
10.2.3 函数代码 <br />
11. 表达式 <br />
11.1 基本表达式 <br />
11.1.1 this关键字 <br />
11.1.2 标识符引用 <br />
11.1.3 字面量引用 <br />
11.1.4 Array初始化程序 <br />
11.1.5 Object初始化程序 <br />
11.1.6 分组操作 <br />
11.2 Left-Hand-Side表达式 <br />
11.2.1 Property访问器 <br />
11.2.2 new操作符 <br />
11.2.3 函数调用 <br />
11.2.4 参数列表 <br />
11.2.5 函数表达式 <br />
11.3 后缀表达式 <br />
11.3.1 后缀+ 运算符 <br />
11.3.2 后缀- 运算符 <br />
11.4 一元运算符 <br />
11.4.1 delete操作符 <br />
11.4.2 void操作符 <br />
11.4.3 typeof操作符 <br />
11.4.4 前缀+ 运算符 <br />
11.4.5 前缀- 运算符 <br />
11.4.6 一元+ 运算符 <br />
11.4.7 一元- 运算符 <br />
11.4.8 按位非运算符~ <br />
11.4.9 逻辑非运算符! <br />
11.5 乘除法运算 <br />
11.5.1 * 运算符 <br />
11.5.2 / 运算符 <br />
11.5.3 % 运算符 <br />
11.6 加减法运算 <br />
11.6.1 加法 + 运算符 <br />
11.6.2 减法 - 运算符 <br />
11.6.3 数字加减运算 <br />
11.7 位运算 <br />
11.7.1 左移 &lt;&lt; 运算符 <br />
11.7.2 右移 &gt;&gt; 运算符 <br />
11.7.3 无符号右移 &gt;&gt;&gt; 运算符 <br />
11.8 比较运算 <br />
11.8.1 小于 &lt; 运算符 <br />
11.8.2 大于 &gt; 运算符 <br />
11.8.3 小于等于 &lt;= 运算符 <br />
11.8.4 大于等于 &gt;= 运算符 <br />
11.8.5 抽象关系比较算法 <br />
11.8.6 instanceof运算符 <br />
11.8.7 in运算符 <br />
11.9 相等比较 <br />
11.9.1 相等运算符 == <br />
11.9.2 不等运算符 != <br />
11.9.3 抽象相等比较算法 <br />
11.9.4 严格相等运算符 === <br />
11.9.5 严格不等运算符 !== <br />
11.9.6 严格相等比较算法 <br />
11.10 二进制位运算 <br />
11.11 二进制逻辑运算 <br />
11.12 条件运算符 ?: <br />
11.13 分配运算 <br />
11.13.1 直接分配 = <br />
11.13.2 混合分配 op= <br />
11.14 逗号运算符 <br />
12 语句<br />
12.1 Block<br />
12.2 变量语句<br />
12.3 空语句<br />
12.4 表达式语句<br />
12.5 if语句<br />
12.6 循环语句<br />
12.6.1 do-while语句<br />
12.6.2 while语句<br />
12.6.3 for语句<br />
12.6.4 for-in语句<br />
12.7 continue语句<br />
12.8 break语句<br />
12.9 return 语句<br />
12.10 with语句<br />
12.11 switch语句<br />
12.12 标签语句<br />
12.13 throw语句<br />
12.14 try语句<br />
13. 函数定义<br />
13.1 定义<br />
13.1.1 等于语法操作<br />
13.1.2 连接对象<br />
13.2 创建函数对象<br />
13.2.1 [[Call]]<br />
13.2.2 [[Construct]]<br />
14. 程序<br />
15. ECMAScript原生对象<br />
15.1 全局对象<br />
15.1.1 全局对象值属性<br />
15.1.2 全局对象函数属性<br />
15.1.3 URI处理函数属性<br />
15.1.4 全局对象构造器属性<br />
15.1.5 全局对象其他属性<br />
15.2 Object对象<br />
15.2.1 Object构造函数调用<br />
15.2.2 Object构造器<br />
15.2.3 Object构造器属性<br />
15.2.4 Object原型对象属性<br />
15.2.5 Object实例属性<br />
15.3 Function对象<br />
15.3.1 Function构造函数调用<br />
15.3.2 Function构造器<br />
15.3.3 Function构造器属性<br />
15.3.4 Function原型对象属性<br />
15.3.5 Function实例属性<br />
15.4 Array对象<br />
15.4.1 Array构造函数调用<br />
15.4.2 Array构造器<br />
15.4.3 Array构造器属性<br />
15.4.4 Array原型对象属性<br />
15.4.5 Array实例属性<br />
15.5 String对象<br />
15.5.1 String构造函数调用<br />
15.5.2 String构造器<br />
15.5.3 String构造器属性<br />
15.5.4 String原型对象属性<br />
15.5.5 String实例属性<br />
15.6 Boolean对象<br />
15.6.1 Boolean构造函数调用<br />
15.6.2 Boolean构造器<br />
15.6.3 Boolean构造器属性<br />
15.6.4 Boolean原型对象属性<br />
15.6.5 Boolean实例属性<br />
15.7 Number对象<br />
15.7.1 Number构造函数调用<br />
15.7.2 Number构造器<br />
15.7.3 Number构造器属性<br />
15.7.4 Number原型对象属性<br />
15.7.5 Number实例属性<br />
15.8 Math对象<br />
15.8.1 Math值属性<br />
15.8.2 Math函数属性<br />
15.9 Date对象<br />
15.9.1 Date概述和内部操作定义<br />
15.9.2 Date构造函数调用<br />
15.9.3 Date构造器<br />
15.9.4 Date构造器属性<br />
15.9.5 Date原型对象属性<br />
15.9.6 Date实例属性<br />
15.10 RegExp(正则表达式)对象<br />
15.10.1 匹配模式<br />
15.10.2 匹配模式语义<br />
15.10.3 RegExp构造函数调用<br />
15.10.4 RegExp构造器<br />
15.10.5 RegExp构造器属性<br />
15.10.6 RegExp原型对象属性<br />
15.10.7 RegExp实例属性<br />
15.11 Error对象<br />
15.11.1 Error构造函数调用<br />
15.11.2 Error构造器<br />
15.11.3 Error构造器属性<br />
15.11.4 Error原型对象属性<br />
15.11.5 Error实例属性<br />
15.11.6 标准中用到的原生错误类型<br />
15.11.7 NativeError对象结构<br />
16. 错误<br />
附录A - 语法摘要<br />
附录B - 兼容性<br />
&nbsp;</p>
<p><strong>1.范围<a name="1"></a></strong></p>
<p>本标准用于定义ECMAScript脚本语言</p>
<p><strong>2.一致性<a name="2"></a></strong></p>
<p>任何遵照ECMAScript的实现，都必须完全支持本说明中描述的：类型，值，对象，属性，函数，程序语法和语义 (types,values,objects,properties,functions,program syntax,semantics)</p>
<p>任何遵照此国际标准的实现，都必须遵守使用Unicode标准（2.1或以后版本）去解释字符，以ISO/IEC 10646-1 第3级实现中的UCS-2或UTF-16作为编码方式。如果采用的ISO/IEC 10646-1的子集没有指定，它将会是BMP子集300，如果采用的编码方式没有指定，则采用UTF-16的编码方式。</p>
<p>任何遵照ECMAScript的实现，都允许提供一些附加的超过本文档中描述的：类型、值、对象、属性和函数(types, values,objects,properties,functions)，在一些特别的实现中，允许为本文档中描述的对象提供一些本文档中没有定义过的属性和属性值。</p>
<p>任何遵照ECMAScript的实现，都允许提供一些本文档中没有描述过的程序及正则表达式语法，在一些特别的实现中，允许支持在程序语法中使用本文档7.5.3中列出的未来保留关键字。</p>
<p><strong>3.参考<a name="3"></a></strong></p>
<p>ISO/IEC 9899:1996 Programming Languages-C,包括修正1和勘误表1和2。</p>
<p>ISO/IEC 10646-1:1993 Information Technology -- 通用多八位编码字符集(UCS)及它的修正和勘误部分。</p>
<p>Unicode公司(1996)，Unicode标准，版本2.0，ISBN：0-201-48345-9，加利福尼亚，Menlo Park，Addison-Wesley出版公司。</p>
<p>Unicode公司(1998)，Unicode技术报告#8：Unicode标准，版本2.1。</p>
<p>Unicode公司(1998)，Unicode技术报告#15：Unicode的标准化形式。</p>
<p>ANSI/IEEE标准754-1985：IEEE二进制浮点运算标准。纽约电气电子工程师协会(1985)。</p>
<p><strong>4.概述<a name="4"></a></strong></p>
<p>本章节包括对ECMAScript语言的非正式概述。</p>
<p>ECMAScript是一种面向对象(object-oriented)的编程语言，用于执行计算和操作在宿主环境中的计算机对象。这里定义的ECMAScript没有被设计为能够自给自足的计算，事实上，在本说明中，没有对要输入的外部数据和要输出的计算结果作出任何规定，相反，我们期望的计算环境是在本说明中描述的ECMAScript程序提供的那些不限于对象和其他的设施，而且，也有一些特别的环境，如宿主对象，对它的描述及行为都超过了本说明的范围，不过，可以知道的是，它们可能会提供一些可以由ECMAScript程序访问的属性和调用的函数。</p>
<p>脚本语言是一种编程语言，它用来操作、自定义、自动化现有系统中的设备。在这些系统中，有用的功能已经可以通过用户接口来使用，而脚本语言就是将这些功能暴露给程序控制的机制。这样，就可以说，现有系统提供了一个运行脚本语言完整功能需要的对象和设备的宿主环境。脚本语言是专门给专业和非专业的编程人员使用的，为了适应非专业的程序员，有些方面多少有些不太严格。</p>
<p>ECMAScript最初的设计是一种网页脚本语言，它为浏览器中网页更活跃提供一种机制，并且，在基于WEB的C/S结构中做呈现服务端计算的这部分操作。ECMAScript可以为各种宿主环境提供核心的脚本性能，因此，本文档指定的核心脚本语言是与所有那些特定宿主环境分离的。</p>
<p>在ECMAScript中的一些设施和其他一些在使用的编程语言类似，如Java和Self，在这些地方有所描述： Gosling,James,Bill Joy和Guy Steele，The Java Language Specification.1996年Addison Wesley出版社。 Ungar,David,Smith和Randall B，Self:The Power of Simplicity.OOPSLA 87会议论文第227-241页，1987年10月Orlando FL.</p>
<p><strong>4.1 网页脚本<a name="4.1"></a></strong></p>
<p>网页浏览器提供了一个ECMAScript的宿主环境，用以包含客户端计算。比如，它提供了windows,menus,pop-ups, dialog boxes,text areas,anchors,frames,history,cookies和input/output等对象。此外，该宿主环境还提供了一些绑定脚本代码到事件的方法，如焦点的改变，页面和图像的加载、卸载，错误、忽略，选区，表单提交，鼠标行为等等。脚本代码出现HTML代码中，显示出来的页面由用户接口元素和处理过的文本和图像组成。脚本代码和用户接口发生交互响应而不需要主程序。</p>
<p>网页服务为服务端计算提供了一个不同的宿主环境，包括的对象有requests,clients,files和锁定共享数据的机制。同时使用浏览器端脚本和服务端脚本，通过在客户端和服务端分散计算，使得为用户接口提供一种基于WEB的应用程序成为可能。</p>
<p>所有支持ECMAScript的WEB浏览器和服务，都有自己的宿主环境用于完成ECMAScript的执行环境。</p>
<p><strong>4.2 语言概述<a name="4.2"></a></strong></p>
<p>下面是ECMAScript的概要信息（部分），此概述并非标准中的概述。</p>
<p>ECMAScript是基于对象(object-based)的：基本语言，宿主提供对象，ECMAScript程序就是一个对象交互的聚合。 ECMAScript对象(object)的properties是一个无序的集合，有0个或多个属性(attributes)决定哪些property可用，比如，当某个property的ReadOnly属性被设置为true时，任何企图改变该property值的代码将没有效果。properties 是一个包含其他对象的容器，原始值(primitive values)或方法(methods)。原始值属于下列内置(built-in)类型中的一员：Undefined,Null,Boolean,Number和String；对象则是内置类型Object；方法是一个通过property关联到对象的函数。</p>
<p>ECMAScript定义了一个内置对象(built-in objects)集合，使得ECMAScript实体更完善。这些内置对象包括Global 对象，Object对象，Function对象，Array对象，String对象，Boolean对象，Number对象，Math对象，Date对象， RegExp对象和错误对象：Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError。</p>
<p>ECMAScript也定义了一个内置操作符的集合或者说不是，严格地说，是函数和方法。ECMAScript操作符包括了各种一元运算符、乘除运算符、加减法运算符、位移运算符、关系运算符、相等运算符、二元运算符、二元逻辑运算符、分配运算符和逗号运算符。</p>
<p>ECMAScript的语法类似Java的语法。ECMAScript语法宽松是为了使它能够成为更容易使用的脚本语言。比如，变量不需要申明类型也不需要为properties指定类型，函数定义也可以不需要出现在它们的调用语句之前。</p>
<p><strong>4.2.1 对象<a name="4.2.1"></a></strong></p>
<p>ECMAScript没有像C++，Smalltalk，Java等语言中的真正的类，但是支持构造器(constructors)，它在执行代码时创建对象，为对象分配内存并初始化它们全部或部分初始值和properties。所有的构造器都是对象，但不是所有对象都是构造器。每个构造器都有一个Prototype属性用于实现基于原型的继承(prototype-based inheritance)和属性共享(shared properties)。对象在构造器使用new表达式时被创建，比如，new String(&quot;A String&quot;)创建了一个新的字符串对象。不用new表达式去直接调用一个构造器，结果将依赖于这个构造器，比如，String(&quot;A String&quot;) 产生一个原始值String，而不是一个对象。</p>
<p>ECMAScript支持基于原型的继承。所有构造器都有一个相关联的原型，所有由构造器创建的对象都隐含一个到该原型的引用（称为对象原型），此外，一个原型可能有一个非空的、隐含的引用，到它的原型，所以，这又被称为是原型链(prototype chain)。当一个引用来自一个对象的property时，它会去该对象和它的原型链中查找与该property 同名的属性，换句话说，会先直接从该对象中检测是否存在这个同名的引用，如果有，则返回，否则，再从该对象的原型(prototype)中去检测是否存在该引用。</p>
<p>在基于类的面向对象语言里，通常，状态由实例持有，方法由类持有，继承只有结构和行为。在ECMAScript中，状态和方法由对象持有，结构、行为和状态都可以被继承。</p>
<p>对象通常都不会直接包含那些由原型包含共享的属性和值。描述见下图：</p>
<p><img alt="" src="http://www.w3cgroup.com/attachments/month_0911/u2009111917433.png" /></p>
<p>CF是一个构造函数（同时也是一个对象）。通过对它进行new表达式创建了5个实例对象：cf1,cf2,cf3,cf4,cf5。每个实例对象都包含有q1和q2两个属性。虚线表示隐含的原型关系，所以，比如，CF的原型是CFp，构造函数CF自己有两个属性P1和P2，它们对CFp,cf1,cf2,cf3,cf4,cf5都不可见。CFp的属性CFP1由cf1,cf2,cf3,cf4,cf5共享（不包括 CF），还有那些在CFp的隐含的原型链中找到的property name不是q1,q2或者CFP1的其他属性。注意，CF和CFp之间不存在隐含的原型联系。</p>
<p>不像基于类的对象语言，这里的属性可以由对象动态添加并赋值。因为，构造器不需要名字，或者给构造出的对象的所有或部分属性赋值。如上图，只要为CFp添加一个属性值即可由cf1,cf2,cf3,cf4,cf5共享。</p>
<p><strong>4.3 定义<a name="4.3"></a></strong></p>
<p>以下是ECMAScript中主要术语的非正式定义。</p>
<p><strong>4.3.1 Type<a name="4.3.1"></a></strong></p>
<p>type是数据值的集合</p>
<p><strong>4.3.2 Primitive Value<a name="4.3.2"></a></strong></p>
<p>原始值是Undefined,Null,Boolean,Number,String这些类型的成员。原始值是语言实现中底层可以直接表示的数据。</p>
<p><strong>4.3.3 Object<a name="4.3.3"></a></strong></p>
<p>对象是Object类型的成员。它所包含的所有属性成员，如原始值、对象或者函数，是一个无序的集合。对象属性成员放置的函数又被称为方法。</p>
<p><strong>4.3.4 Constructor<a name="4.3.4"></a></strong></p>
<p>构造器是一个函数对象用来创建和初始化对象。每个构造器都有一个关联的原型对象用来实现属性成员的继承和共享。</p>
<p><strong>4.3.5 Prototype<a name="4.3.5"></a></strong></p>
<p>ECMAScript中的原型是用来实现对象结构、状态和行为继承的。当一个构造器构造了一个对象，这个对象会隐含地引用到该构造器关联的原型，为了解析属性的引用。构造器的关联的原型可以通过程序表达式constructor.prototype 来引用。在某个共享的对象的原型上添加的属性值，通过继承，可以被所有其他对象共享。</p>
<p><strong>4.3.6 Native Object<a name="4.3.6"></a></strong></p>
<p>原生对象是由ECMAScript的实现提供的，独立于宿主环境。标准的原生对象会在本说明中定义。其中有些原生对像又是内置对象，其他的那些则可能在执行一个ECMAScript程序时产生。</p>
<p><strong>4.3.7 Built-in Object<a name="4.3.7"></a></strong></p>
<p>内置对象由ECMAScript的实现提供的，独立于宿主环境，出现在ECMAScript程序开始执行的时候。标准的内置对象会在本说明中定义，一些ECMAScript的实现可能有其他的说明和定义。所有的内置对象都是原生对象。</p>
<p><strong>4.3.8 Host Object<a name="4.3.8"></a></strong></p>
<p>宿主对象由给ECMAScript提供完整执行环境的宿主环境提供的。任何对象，不是原生对象，就是宿主对象。</p>
<p><strong>4.3.9 Undefined Value<a name="4.3.9"></a></strong></p>
<p>未定义值是一个原始值，当一个变量没有被分配值时使用。</p>
<p><strong>4.3.10 Undefined Type<a name="4.3.10"></a></strong></p>
<p>Undefined类型有一个正确的值，undefined。</p>
<p><strong>4.3.11 Null Value<a name="4.3.11"></a></strong></p>
<p>空值是一个原始值，它表示空的，没有的，或不存在的引用。</p>
<p><strong>4.3.12 Null Type<a name="4.3.12"></a></strong></p>
<p>Null类型有一个正确的值，null。</p>
<p><strong>4.3.13 Boolean Value<a name="4.3.13"></a></strong></p>
<p>布尔值是Boolean类型的成员，它只能是两个唯一值中的一个，true或false。</p>
<p><strong>4.3.14 Boolean Type<a name="4.3.14"></a></strong></p>
<p>Boolean类型表示一个逻辑实体，由两个唯一值组成。一个是true，另一个是false。</p>
<p><strong>4.3.15 Boolean Object<a name="4.3.15"></a></strong></p>
<p>Boolean对象是Object类型的成员，它是内置对象Boolean的实例。意思是，一个Boolean对象是通过Boolean构造器的 new表达式创建，提供一个boolean参数。结果对象有一个隐含的（未命名）原型boolean。一个Boolean对象支配一个 Boolean值。</p>
<p><strong>4.3.16 String Value<a name="4.3.16"></a></strong></p>
<p>字符串值是String类型的成员，它是一个有限的有序的，由0到16位无符号整数长度的值。注意：尽管每个值通常都表示一个单独的16位的UTF-16文本的单元，但该语言不会做出任何限制和要求当这个值不是 16位无符号整数的情况时。</p>
<p><strong>4.3.17 String Type<a name="4.3.17"></a></strong></p>
<p>String类型是所有字符串值的集合。</p>
<p><strong>4.3.18 String Object<a name="4.3.18"></a></strong></p>
<p>String对象是Object类型的成员，它是内置对象String的实例。意思是，一个String对象是通过String构造器的new 表达式创建，提供一个字符串参数。结果对象有一个隐含的（未命名）原型string。一个String对象可以支配一个字符串值，通过调用String构造器（参见15.5.1）。</p>
<p><strong>4.3.19 Number Value<a name="4.3.19"></a></strong></p>
<p>数字值是Number类型的成员，它是一个直接表示的数字。</p>
<p><strong>4.3.20 Number Type<a name="4.3.20"></a></strong></p>
<p>Number类型是表示数字的值的集合。在ECMAScript中，该集合表示IEEE754的64位双精度运算格式的值，包含一个特殊值&quot;Not-a-Number&quot;(NaN)，正无穷大和负无穷大。</p>
<p><strong>4.3.21 Number Object<a name="4.3.21"></a></strong></p>
<p>Number对象是Object类型的成员，它是内置对象Number的实例。意思是，一个Number对象是通过Number构造器的new 表达式创建，提供一个数字参数。结果对象有一个隐含的（未命名）原型number。一个Number对象可以支配一个数字值，通过调用Number构造器（参见15.7.1）。</p>
<p><strong>4.3.22 Infinity<a name="4.3.22"></a></strong></p>
<p>原始值Infinity表示一个正无穷大的数字，Number类型成员。</p>
<p><strong>4.3.23 NaN<a name="4.3.23"></a></strong></p>
<p>原始值NaN表示IEEE标准&quot;Not-a-Number&quot;值的集合，Number类型成员。</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=274</link>
			<title><![CDATA[如何使用PHP服务端代理抓取网页内容]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Fri,13 Nov 2009 00:06:53 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=274</guid>
		<description><![CDATA[<p>最近公司暂时断开外网，只开放公司自己所有的站点允许访问，说实在的，做WEB开发的断网，真是让人哭笑不得......</p>
<p>由于需要查找资料，只好简单写了一个PHP的服务端代理页面来用一下！</p>
<p>简单<strong>框架页面</strong>：</p>
<p>&lt;style type=&quot;text/css&quot;&gt;<br />
*{margin:0;padding:0;}<br />
html,body{overflow:hidden;}<br />
td{padding:0;vertical-align:top;}<br />
&lt;/style&gt;<br />
&lt;table width=&quot;100%&quot; height=&quot;100%&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot;&gt;<br />
&lt;tr&gt;<br />
&lt;td style=&quot;width:100%;height:25px;background:#d4d0c8;padding:5px 10px;&quot;&gt;<br />
&lt;form method=&quot;post&quot; action=&quot;action_get.php&quot; target=&quot;actioncontent&quot; style=&quot;margin:0;padding:0;&quot;&gt;<br />
&lt;input type=&quot;text&quot; id=&quot;targeturl&quot; name=&quot;targeturl&quot; style=&quot;width:100%;border:1px inset;margin:0;&quot; /&gt;<br />
&lt;/form&gt;<br />
&lt;/td&gt;<br />
&lt;td style=&quot;width:180px;height:25px;background:#d4d0c8;padding:5px 10px 5px 0;&quot;&gt;<br />
&lt;select style=&quot;width:180px;&quot;&gt;&lt;option value=&quot;&quot;&gt;Quick Links&lt;/option&gt;&lt;option value=&quot;http://www.google.com&quot;&gt;http://www.google.com&lt;/option&gt;&lt;option value=&quot;http://www.baidu.com&quot;&gt;http://www.baidu.com&lt;/option&gt;&lt;option value=&quot;http://www.bing.com&quot;&gt;http://www.bing.com&lt;/option&gt;&lt;/select&gt;<br />
&lt;/td&gt;<br />
&lt;/tr&gt;<br />
&lt;tr&gt;<br />
&lt;td colspan=&quot;2&quot;&gt;<br />
&lt;iframe name=&quot;actioncontent&quot; style=&quot;width:100%;height:100%;&quot;&gt;&lt;/iframe&gt;<br />
&lt;/td&gt;<br />
&lt;/tr&gt;<br />
&lt;/table&gt;<br />
&lt;script type=&quot;text/javascript&quot;&gt;<br />
window.onload = function(){<br />
&nbsp;&nbsp; &nbsp;document.getElementById('targeturl').focus();<br />
};<br />
var dform = document.getElementsByTagName('form')[0];<br />
var dselect = document.getElementsByTagName('select')[0];<br />
var dipt = document.getElementById('targeturl');<br />
dselect.onchange = function(){<br />
&nbsp;&nbsp; &nbsp;if(this.value!=''){<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; dipt.value = this.value;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; dform.submit();<br />
&nbsp;&nbsp; &nbsp;}<br />
};<br />
dform.onsubmit = function(){<br />
&nbsp;&nbsp; &nbsp;var dv = document.getElementById('targeturl');<br />
&nbsp;&nbsp; &nbsp;var sv = dv.value.replace(/\s/g,'');<br />
&nbsp;&nbsp; &nbsp;dv.value = sv;<br />
&nbsp;&nbsp; &nbsp;return true;<br />
};<br />
&lt;/script&gt;</p>
<p><strong>PHP代理页面</strong>：</p>
<p>&lt;?php<br />
//使用Snoopy的抓页功能<br />
include &quot;Snoopy.class.php&quot;;<br />
//目标URL<br />
$url = $_REQUEST['targeturl'];<br />
//下载类文件列表<br />
$download = array(<br />
&nbsp;&nbsp;&nbsp; 'pdf'=&gt;'application/pdf',<br />
&nbsp;&nbsp;&nbsp; 'rar'=&gt;'application/octet-stream',<br />
&nbsp;&nbsp;&nbsp; 'chm'=&gt;'application/octet-stream',<br />
&nbsp;&nbsp;&nbsp; 'ppt'=&gt;'application/vnd.ms-powerpoint',<br />
&nbsp;&nbsp;&nbsp; 'doc'=&gt;'application/msword',<br />
&nbsp;&nbsp;&nbsp; 'xls'=&gt;'application/vnd.ms-excel',<br />
&nbsp;&nbsp;&nbsp; 'exe'=&gt;'application/octet-stream',<br />
&nbsp;&nbsp;&nbsp; 'gif'=&gt;'image/gif',<br />
&nbsp;&nbsp;&nbsp; 'jpg'=&gt;'image/jpeg',<br />
&nbsp;&nbsp;&nbsp; 'jpeg'=&gt;'image/jpeg',<br />
&nbsp;&nbsp;&nbsp; 'png'=&gt;'image/png'<br />
);<br />
//取文件扩展名<br />
function getextend($file_name){<br />
&nbsp;$extend = pathinfo($file_name);<br />
&nbsp;$extend = strtolower($extend[&quot;extension&quot;]);<br />
&nbsp;return $extend;<br />
}<br />
//将所有传递过来的参数列出来<br />
$par = array();<br />
$GetPost = array_merge($_POST,$_GET);<br />
foreach($GetPost As $Key=&gt;$Value){<br />
&nbsp;if($Key!='targeturl'){<br />
&nbsp;&nbsp;$Value = str_replace(&quot;%25&quot;,&quot;%&quot;,$Value);<br />
&nbsp;&nbsp;array_push($par,($Key . &quot;=&quot; . $Value));<br />
&nbsp;}<br />
}<br />
//判断目标URL是否带有?（即是否带有参数）<br />
$cc = strpos($url,&quot;?&quot;) ? &quot;&amp;&quot; : &quot;?&quot;;<br />
//重组URL<br />
$geturl = !$par ? $url : $url.$cc.implode(&quot;&amp;&quot;,$par);<br />
//抓取重组后的URL页面内容<br />
$snoopy = new Snoopy;<br />
$snoopy-&gt;fetch($geturl);<br />
//检测当前文件是否为下载类型<br />
$sftype = getextend($url);<br />
$bdown = @$download[$sftype];<br />
//如果是，则下载该文件<br />
if($bdown){<br />
&nbsp;$query = $snoopy-&gt;results;<br />
&nbsp;header(&quot;Content-type: &quot;.$bdown);<br />
&nbsp;header(&quot;Content-Disposition:inline;filename=&quot;.$url);<br />
&nbsp;header('Cache-Control:must-revalidate,post-check=0,pre-check=0');<br />
&nbsp;header('Expires:0');<br />
&nbsp;header('Pragma:public');<br />
&nbsp;echo $query;<br />
&nbsp;exit;<br />
}<br />
//替换目标内容中脚本里有可能替换父窗口地址的代码<br />
$org = str_replace(&quot;top.location&quot;,&quot;top.title&quot;,$snoopy-&gt;results);<br />
//尝试转换目标内容编码到UTF-8<br />
$opt = iconv(&quot;gbk&quot;,&quot;utf-8&quot;,$org);<br />
//判断目标内容编码为GBK或UTF-8<br />
$ec = strlen($opt)?&quot;gbk&quot;:&quot;utf-8&quot;;</p>
<p>?&gt;<br />
&lt;script type=&quot;text/javascript&quot;&gt;<br />
//封闭运行，避免与后面内容中脚本混乱<br />
(function(){<br />
/*如果是js,css,txt类型文件，则直接输出，不做处理*/<br />
var sftype = '&lt;?php echo $sftype;?&gt;';<br />
if(/(?:js|css|txt)/i.test(sftype)){return;}<br />
var createIPH = function(name,value){if(!name){return;}if(/msie/i.test(navigator.appVersion)){return document.createElement('&lt;input type=&quot;hidden&quot; name=&quot;'+name+'&quot; value=&quot;'+value+'&quot;/&gt;');}else{var dfi = document.createElement('input');dfi.type = 'hidden';dfi.name = name;dfi.value = value;return dfi;}};<br />
//回显目标URL到父窗口文本框<br />
var dtu = top.document.getElementById('targeturl');<br />
if(dtu){dtu.value = '&lt;?php echo $geturl;?&gt;';}<br />
//目标URL及domain<br />
var sref = '&lt;?php echo $url;?&gt;';<br />
var sdomain = (/^(http:\/\/[^\/]*)/i.test(sref))?RegExp.$1:'';<br />
//插入外部样式<br />
var newStyleSheet = function(shref){<br />
&nbsp;&nbsp;&nbsp; var ds = document.createElement('link');<br />
&nbsp;&nbsp;&nbsp; ds.rel = 'styleSheet';<br />
&nbsp;&nbsp;&nbsp; ds.type='text/css';<br />
&nbsp;&nbsp;&nbsp; ds.href = shref;<br />
&nbsp;&nbsp;&nbsp; document.getElementsByTagName('head')[0].appendChild(ds);<br />
};<br />
//页面加载后执行下面的过程<br />
var process = function(){<br />
//抓取页面中外部样式链接<br />
var dstyle = document.getElementsByTagName('link'),ls = dstyle.length;<br />
//抓取页面中所有链接<br />
var dlink = document.getElementsByTagName('a'),la = dlink.length;<br />
//抓取页面中所有表单<br />
var dform = document.getElementsByTagName('form'),lf = dform.length;<br />
//抓取页面中所有图片<br />
var dimg = document.getElementsByTagName('img'),lm = dimg.length;<br />
//遍历所有外部样式链接，重新插入替换后的样式文件<br />
for(var i=0;i&lt;ls;i++){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; var shref = dstyle[i].href;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!shref){continue;}<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shref = shref.toString().replace(/^http:\/\/www\.w3cgroup\.com(?:\/geturl)?/i,sdomain);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; var newhref = (/^http/i.test(shref))?'http://www.w3cgroup.com/geturl/action_get.php?targeturl='+shref:'http://www.w3cgroup.com/geturl/action_get.php?targeturl='+sdomain+'/'+shref.replace(/^\/*/,'');<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; newStyleSheet(newhref);<br />
}<br />
&nbsp;//遍历所有链接，替换它们的href地址<br />
&nbsp;for(i=0;i&lt;la;i++){<br />
&nbsp;var src = dlink[i].href.toString().replace(/^http:\/\/www\.w3cgroup\.com(?:\/geturl)?/i,sdomain);<br />
&nbsp;var oargs = getArgs(src),ahref = [];<br />
&nbsp;//UTF-8编码参数值<br />
&nbsp;for(var d in oargs){<br />
&nbsp;&nbsp;if(!d||d=='filename'||!oargs[d]){continue;}<br />
&nbsp;&nbsp;ahref.push(d+'='+encodeURIComponent(encodeURI(oargs[d])));<br />
&nbsp;}<br />
&nbsp;var ghref = ahref.length?oargs.filename+'?'+ahref.join('&amp;'):oargs.filename;<br />
&nbsp;//重设链接地址<br />
&nbsp;dlink[i].href = 'http://www.w3cgroup.com/geturl/action_get.php?targeturl='+ghref;<br />
&nbsp;}<br />
&nbsp;//遍历所有表单，替换它们的action地址<br />
&nbsp;for(i=0;i&lt;lf;i++){<br />
&nbsp;//抓取表单action并处理<br />
&nbsp;var src = dform[i].action.toString().replace(/^http:\/\/www\.w3cgroup\.com(?:\/geturl)?/i,sdomain);<br />
&nbsp;if(!(/^http/.test(src))){src = (/^\/.*$/.test(src))?(sdomain+src):(sdomain+'/'+src);}<br />
&nbsp;//创建一个隐藏域targeturl，值为上面处理的src地址<br />
&nbsp;var dfi = createIPH('targeturl',src);<br />
&nbsp;dform[i].appendChild(dfi);<br />
&nbsp;//创建一个隐藏域ie，值为utf-8，纯属为搜索引擎使用<br />
&nbsp;var dfi2 = createIPH('ie','utf-8');<br />
&nbsp;dform[i].appendChild(dfi2);<br />
&nbsp;//重设表单提交目标窗口<br />
&nbsp;dform[i].target = 'actioncontent';<br />
&nbsp;//重设表单action地址<br />
&nbsp;dform[i].action = 'http://www.w3cgroup.com/geturl/action_get.php';<br />
&nbsp;//重设表单onsubmit事件，用来UTF8编码字段值<br />
&nbsp;dform[i].onsubmit = function(){<br />
&nbsp;&nbsp;var dlms = this.elements,l = dlms.length-1,pn = '',pt = '',pv = '';<br />
&nbsp;&nbsp;for(var i=0;i&lt;l;i++){<br />
&nbsp;&nbsp;&nbsp;pn = dlms[i].name,pt = dlms[i].type,pv = dlms[i].value;<br />
&nbsp;&nbsp;&nbsp;if(!pn||pn=='targeturl'||pn=='ie'){continue;}<br />
&nbsp;&nbsp;&nbsp;if(pt=='submit'||pt=='reset'||pt=='button'){<br />
&nbsp;&nbsp;&nbsp;&nbsp;dlms[i].value = encodeURIComponent(pv);<br />
&nbsp;&nbsp;&nbsp;}else{<br />
&nbsp;&nbsp;&nbsp;&nbsp;dlms[i].value = encodeURIComponent(encodeURI(pv));<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;};<br />
&nbsp;}<br />
//遍历所有图片，重新载入<br />
for(i=0;i&lt;lm;i++){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; var src = dimg[i].src;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!src){continue;}<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; src = src.toString().replace(/^http:\/\/www\.w3cgroup\.com(?:\/geturl)?/i,sdomain);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; var newsrc = (/^http/i.test(src))?'http://www.w3cgroup.com/geturl/action_get.php?targeturl='+src:'http://www.w3cgroup.com/geturl/action_get.php?targeturl='+sdomain+'/'+src.replace(/^\/*/,'');<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dimg[i].src = newsrc;<br />
}<br />
};<br />
//绑定该过程到window.onload<br />
if(document.attachEvent){window.attachEvent('onload',process);}else{window.addEventListener('load',process,false);}<br />
})();<br />
&lt;/script&gt;<br />
//脚本放在输出内容前，避免内容中可能出现脚本错误而导致我们要做的事情被废掉<br />
//输出抓到的目标页面内容<br />
&lt;?php echo $scontent;?&gt;</p>
<p><strong>在这个小作品中，我编写了一个重要的<a target="_blank" href="http://www.jslab.org.cn/?tag=easyUTF8">JavaScript函数easyUTF8，它可以很方便地在JavaScript脚本中将GBK编码的内容转换为UTF-8编码</a>。</strong></p>
<p><strong>我们还处理了一下表单中添加项目的兼容问题，注意看createIPH函数，在IE中创建的表单项内容，在指定name和value时可能会出现我们不希望的结果，这在DHTML手册中已经有过描述了。</strong></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=273</link>
			<title><![CDATA[一个好的网页需要什么]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Tue,03 Nov 2009 08:52:25 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=273</guid>
		<description><![CDATA[<div class="content">
<div id="wsc">
<p>作者：<a target="_blank" href="http://dev.opera.com/author/1477930">mnfrancis</a> &middot; 2008年7月8日</p>
<ul style="list-style-type: none;">
    <li><a href="http://www.w3cgroup.com/article.asp?id=271">上一篇：信息架构&mdash;&mdash;规划一个Web站点</a></li>
    <li><a href="http://www.w3cgroup.com/article.asp?id=274">下一篇：色彩理论</a><a href="http://kb.operachina.com/wsc/#toc"><br />
    </a></li>
</ul>
<h2>序言</h2>
<p>接着上一篇文章，在本篇文章中，我们将考察The Dung Beatles乐队网站的内容，以了解好的Web站点和网页需要包含些什么要素。</p>
<p>你们尚不需要去研究网站和网页的基础代码，而只需考察不同的网页，思考其中应该包括哪些要素，并思考一些关键性的问题，如一致性、可用性和可访问性。本篇文章的目录如下：</p>
<ul>
    <li><a href="http://www.v-ec.com/dh20156/#homepage">主页</a>
    <ul>
        <li><a href="http://www.v-ec.com/dh20156/#whatdoesthismean">对我们的网站来说，这意味着什么？</a></li>
    </ul>
    </li>
    <li><a href="http://www.v-ec.com/dh20156/#navigation">导航</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#commonelements">网站上的其他一些通用元素</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#context">上下文关系非常重要</a>
    <ul>
        <li><a href="http://www.v-ec.com/dh20156/#relevantcontent">相关内容</a></li>
        <li><a href="http://www.v-ec.com/dh20156/#headings">标题</a></li>
    </ul>
    </li>
    <li><a href="http://www.v-ec.com/dh20156/#usability">可用性</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#accessibility">可访问性</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#summary">总结</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#exercises">练习题</a></li>
</ul>
<h2 id="homepage">主页</h2>
<p>很多人倾向于认为&ldquo;让我们从多数用户首先访问的页面－主页开始，这符合逻辑吧？&rdquo;</p>
<p>这听起来符合逻辑，但其实并不是这样的。过分着重于主页，是一个人们常犯的错误。网站的主页常成为一个大杂烩，试图概括网站的所有内容，无所不包。</p>
<p>让我们看一个此类主页的实例吧，那就是 <em>MSN 网站的主页</em>（见图1）。这个主页罗列了过多的内容和链接，从旅游到电视，从交友约会到指导，从小配件到绿化产品的信息，十分庞杂，都试图引起你的注意。</p>
<p><img src="http://kb.operachina.com/files/msn.gif" alt="The MSN home page has a ludicrous number of links on it" /></p>
<p class="article_comment">图1：MSN网站的主页&mdash;罗列的链接太多！</p>
<p>这种&ldquo;将一切想得到的东西都放在上面&rdquo;的主页，可能适合那些大型网站，但如果我们这个乐队网站的主页也这样的话，无疑是不恰当的，会流失很多本来可以吸引到的用户。</p>
<p>还有一个普遍的误解就是，主页一定是访问网站的人所看到的第一个页面。如果这些网站访问者已了解到乐队的网址，或是从广告传单、招贴画或是乐队徽章上看到乐队的网址，然后在浏览器中键入乐队的网址，确实有可能首先看到的就是网站的首页。</p>
<p>但是更可能出现的情况是，网站访问者是基于搜索结果来访问网站的。如果他们搜索乐队的名称，很可能（但不一定）看到的最靠前的搜索结果是乐队网站的 主页。不过在其他情况下，例如他们搜索&ldquo;模仿Beatles乐队的音乐会&rdquo;，看到的第一个搜索结果可能是&ldquo;巡演日期&rdquo;网页；再比如他们搜索&ldquo;摩斯乔市的乐 队&rdquo;，看到的第一个搜索结果就可能是&ldquo;关于TDB乐队&rdquo;网页，这是因为该网页提到了乐队是来自摩斯乔市的，而主页里就没有提到这一点。</p>
<p>《纽约时报》的网站在一篇关于决定停止向访问旧内容的用户收费的文章中提到，他们网站的访问者的行为已近发生改变，到底是什么样的改变呢，文中写道：</p>
<blockquote>
<p>&hellip;越来越多的读者都是通过搜索引擎和其他网站上的链接来访问我们网站的，而不再是直接访问NYTimes.com。以这种间接方式访问网站的读者， 就无法访问那些需要付费才能看到的文章，他们与那些直接访问网站的忠实用户相比，愿意支付订阅费的可能性就要小一些。取消对访问旧内容的收费，是一个让用 户可以访问更多的网页并提高网站广告收入的机会。</p>
</blockquote>
<h3 id="whatdoesthismean">对我们的网站来说，这意味着什么？</h3>
<p>这意味着你需要将内容进行分割，放在单个的网页内。你应该思考网站的访问者将如何找到他们真正在寻找的内容和信息，或者说，一旦他们开始在网站漫游，他们想访问的下一个网页是什么。</p>
<p>尽管很多人都试图在主页上放置过多的内容，但实际上更好的做法是把主页用作突出显示网站其他网页的内容及导向访问这些网页的一个页面。将主页和网站 其他页面一样处理，并赋予它一个确定的目的(即显示更新，提供一个网站概观，仅简要介绍乐队，让访问者继续访问其他页面，等等)。主页还需要有指向其他页 面的导航栏，并显示网站的品牌。</p>
<p>下面我们将更深入地学习这些内容。</p>
<h2 id="navigation">导航</h2>
<p>如何对一个网站进行导航，是网站设计中最关键的因素之一（甚至可能是最关键的）。你应当确定网站的主要栏目页，并在主导航栏中显示。</p>
<p>关于网站导航同样存在一个普遍的错误观念（你们可能已听说过），那就是让访问者在获取信息时不要超过三次点击。正是这种错误观念的广泛传播，使得一 些网站上出现最糟糕和最复杂的导航。作为实例，你们可以去看看很多购物或价格比较网站，他们总是倾向于在页面上放置尽可能多的链接，试图使用户在购买什么 之前，尽量减少点击次数，以免他们离开并去访问竞争对手的网站。但这种做法导致的结果很可能就是：罗列的信息过多，反倒使用户不能有效地获取和使用这些信 息。太多的选择和太少的选择一样都会让人无所适从。</p>
<p>其实只要有从一个链接通向下一个页面的明确路径，显示用户正在通向最终要访问的页面的正常过程之中，用户是会继续深入访问网站的。</p>
<p>基于上一篇文章中讲述的信息架构，TDB乐队网站的主导航栏应当包括指向以下部分/页面的链接，&ldquo;Store（商店）&rdquo;页面、&ldquo;About（关于我 们）&rdquo;页面、&ldquo;Contact（与我们联系）&rdquo;页面、&ldquo;The Music（音乐）&rdquo;页面、&ldquo;Band News（乐队新闻）&rdquo;页面，以及一个&ldquo;返回主页&rdquo;的链接，并不需要包含指向如&ldquo;Tour Dates（巡演日期）&rdquo;、&ldquo;Lyrics（歌词）&rdquo;等页面的链接。指向这些页面的链接应当仅放在相应的网页内，也就是说，任何需要从某一个歌词页面直接 跳转到&ldquo;Tour Dates（巡演日期）&rdquo;页面的访问者，都将可以被导航到&ldquo;Band News（乐队新闻）&rdquo;页面，然后再链接到&ldquo;Tour Dates（巡演日期）&rdquo;页面。</p>
<p>要想创建出成功的网站导航栏，一个最关键的方面是&ldquo;一致性&rdquo;。看下面图2所示的页面，在页面上方的导航栏中显示了一些链接如指向&ldquo;Home（主 页）&rdquo;, &ldquo;Articles（文章）&rdquo;, &ldquo;Forums（论坛）&rdquo;等页面的链接。在dev.opera 这个站点的其他页面，显示的导航栏都是一样的。导航指向显示你目前在网站的哪个位置，并提供指向该栏目内具体内容的链接。举例来说，点击导航栏上的 &ldquo;Articles（文章）&rdquo;标签，将带你到&ldquo;文章&rdquo;栏目的主页面，其中包含一些指向最近发表的文章的链接，以及一系列指向分栏目如 &ldquo;Accessibility（可访问性）&rdquo;、&ldquo;CSS&rdquo; 、&ldquo;Mobile（移动设备）&rdquo;等的链接（见图2）。</p>
<p><img src="http://kb.operachina.com/files/devo.gif" alt="The dev opera dot com navigation is constant wherever you are on the site" /></p>
<p class="article_comment">图2: The dev.opera.com的导航栏在网站所有页面内都保持了一致性。</p>
<h2 id="commonelements">网站上的其他一些通用元素</h2>
<p>除导航栏外，通常还有其他一些通用元素要在网站的各个页面内都显示。</p>
<p>绝大多数网站都有一些标示所有权的品牌图像、网站标识或标头。例如，Yahoo!网站中几乎每一个页面，在其左上方都有一个网站标识，其中附加有你正在访问的页面所属的大栏目的名称，如&ldquo;Travel（旅游）&rdquo;、&ldquo;Movies（电影）&rdquo;、&ldquo;Autos（汽车）&rdquo;等等。</p>
<p>页面的顶部标题部分(横跨页面顶部)可以不仅仅包含网站标识，还可以包含或附加上主导航栏。此外，加上搜索框也并不少见，这可以让用户直接搜索网站的内容和信息，而不用通过使用菜单和链接来导航。你应该在你的网站的每个页面，都包括所有或大部分这些通用元素。</p>
<p>页脚部分(页面最下端的部分)应包含一些额外的信息，如版权声明，以及指向有用的辅助页面（如&ldquo;About This Site（关于本网站）&rdquo;、&ldquo;Terms &amp; Conditions（使用条款和条件）&rdquo;、&ldquo;Contact Us（联系我们）&rdquo;)的链接等。</p>
<p>配色、页面布局、图形和图标的使用、版面设置和图像，创造出作为网站有机组成部分的一个网页的整体形象，这里&ldquo;一致性&rdquo;是关键。让网页的外观和布置 保持一致性，有助于保持网站的一体性，并创造出一种熟悉感。这样你就知道你正在访问的页面与此前访问的该网站的网页是相互联系的，都是网站的有机组成部 分，因为这些页面呈现出的视觉形象就是相互联系的。当你在设计网站时，应当牢记这点，不要让网站内的各个页面看起来就不一致。</p>
<p>在我们的TDB乐队网站内，页面的顶部标题部分将包括乐队的标识和名称，以强化访问者对乐队的认知度，让他们在访问各个页面时，都意识到是在阅读关 于乐队的各种信息。页脚部分将包括网站及网站内歌词、图片、试听歌曲等的版权信息，以及指向&ldquo;联系我们&rdquo;、&ldquo;预订演唱会门票&rdquo;等页面的链接。</p>
<h2 id="context">上下文关系非常重要</h2>
<p>每个页面，尽管包含所有这些通用元素，本身还是应该是独一无二的。一个好的网页应该有效地履行一个或少数几个专门的功能。</p>
<h3 id="relevantcontent">相关内容</h3>
<p>要制作出非常优秀的网页，一个关键因素就是既要将内容分割，又要让他们彼此相关。各项内容既必须分别放置在各个不同的页面（这些页面具有各不相同的URL地址），又必须有逻辑性地前后联系（在网站内和页面内都是如此），这样才能便于被找到。</p>
<p>以乐队将举行的演唱会信息为例，尽管可以在每个页面上都放置一个&ldquo;将举行的演唱会&rdquo;模块，但还是应当将该项信息放在一个独立的页面中。一个简单的， 链接到&ldquo;巡演日期&rdquo;页面的&ldquo;下一场演唱会&rdquo;模块，也可以有效地宣传该项信息，而不用处处都复制信息内容（这样可能把用户和搜索引擎都搞糊涂）。</p>
<h3 id="headings">标题</h3>
<p>下一次你们读报时，请仔细看看报纸的内容和版式设计。特别注意有一些报道篇幅更长，配有突出显示的字体和图片，标题也更醒目。这样做的目的是，如果你时间很紧而只想了解重大新闻的话，就可以立即发现哪些是重大新闻。</p>
<p>这一原则同样适用于网页。一个页面内每部分的内容都应有一个标题，以显示这部分内容在页面内的相对重要性（这部分内容是从属于上一部分呢，还是是与之同等重要？）</p>
<p>举例来说，在本篇文章的这个部分有两个段落标题&ldquo;相关内容&rdquo;和&ldquo;标题&rdquo;，它们都位于&ldquo;上下文关系&rdquo;这个大标题之下，显示它们都是从属于大标题之下的小标题。</p>
<h2 id="usability">可用性</h2>
<p>可用性是指一个网站能被用户以可以预期到的合理方式所使用。</p>
<p>设想一下以下几种情况：在你上一个新闻门户网站阅读一篇新闻时，在阅读前必须要在该网站注册；在你在网上预订飞机票或火车票时，还需要花两分钟通过 电话向订票人员解释你的行程；在你输入一个邮件地址或信用卡号码时，网站只是告诉你输入格式错误；搜索发送回的结果中没有有用的条目，或是一个网站在其首 页没有一个搜索工具。</p>
<p>以上都是网站可用性不好的例子，这源于没有考虑网站用户的需要。而在你构建和设计网站时，如果把网站用户的需要放在中心位置，就很有可能创建出令用户满意的好网站。</p>
<p>创建可用性好的网站并不是一件容易的事，这方面的很多知识都只能得之于经验。你可以记下其他网站可用性不好的地方，以避免重蹈覆辙。测试网站可用性最好的办法还是观察用户的实际使用体验。一旦你创建好一个网站，请从以下多个方面观察用户的使用体验：</p>
<ul>
    <li>用户能找到他们寻找的网页吗?</li>
    <li>对用户输入的搜索主题词，搜索工具给出了正确的结果吗?</li>
    <li>图像/音频/视频能在用户使用的浏览器中正常运行吗？</li>
    <li>用户是否有对可用性不满意的地方？</li>
    <li>用户感到满意和高兴的地方又在哪里？</li>
</ul>
<p>专业公司对由其承担进行的网站可用性测试会收取很高的费用，但你可以选择非正式的测试方式，如让你的朋友和家人告诉你他们使用你创建的网站的体验，这样也可以让你很好地了解到一些你尚未注意到的网站存在的问题。这就是所谓当局者迷，旁观者清的道理。</p>
<h2 id="accessibility">可访问性</h2>
<p>对网站可访问性最常见的误解就是仅将其理解为&ldquo;让盲人能访问网站&rdquo;，其实可访问性是一个对更多的人都有影响的问题。</p>
<p>&ldquo;辅助技术&rdquo;这一术语用于描述任何帮助人们与其使用的计算机更为有效地互动的辅助设备或硬件。你们可能马上会想到供盲人使用的屏幕阅读器，或是供无 法使用鼠标或键盘的人使用的语音输入设备。但是眼镜呢？其实对近视的人来说，所戴的眼镜也是一种&ldquo;辅助技术&rdquo;，但是他们中绝大部分人不会认为自己是残疾 人。</p>
<p>意识到很多使用互联网用户可能面临的问题，对制作出好的网页是非常重要的。不要想当然地就做出很多假定，如网站用户就一定有鼠标，就一定可以看到你使用的图像，就都安装了Flash播放器等。</p>
<p>在考虑网站的可访问性时，除要考虑那些需要使用&ldquo;辅助技术&rdquo;的人外，还要考虑其他一些人如用手机上网的用户。现在的手机还不能很好地支持 Flash（即使有Flash功能），例如苹果公司的iPhone 就不具有支持Flash的功能（也许以后也不会有），虽然在其他方面用iPhone浏览网页的效果和在苹果计算机上用桌面版本的Safari浏览器浏览网 页的效果差不多（Opera手机浏览器也不支持Flash）。一些新技术如Opeara Mini手机浏览器，可以为上网的低电量手机重写网页，使网页体积变得更小，对绝大部分用户来说，网页中的图像在手机浏览器中也会被显示得小得多，这意味 着用户可能无法获取网页中任何依赖于微妙的细节的内容。</p>
<p>在我们这个乐队网站的例子中，你应该意识到如果使用了很多图像（乐队照片），则必须描述图像的内容。如果你在页面中使用了Flash音乐播放器，以 让人们可以听到乐队的歌曲，你同时也应该创建直接指向歌曲的链接，以让那些未安装Flash播放器的人也可以以他们选择的方式听到这些歌曲。</p>
<h2 id="summary">总结</h2>
<p>在本篇文章中，我讲述了你们在开始实际创作网页时，需要牢记的一些重要概念，以使网页具有更好的可用性，能为更多的人访问，并能更为顺畅地运行。在以后的课程中，我们将详细讲述所有这些在本文中已提到的重要概念。</p>
<h2 id="exercises">练习题</h2>
<ul>
    <li>在做本篇文章所附的练习题时，你只需上网浏览一些你最喜爱的网站，试着以从本篇文章中学到的知识检视这些网站，并回答以下这些问题：</li>
    <li>这些网站具有一致的页面顶端部分、页脚部分和导航栏吗？</li>
    <li>观察你在网站各页面浏览时，导航是如何变化的。</li>
    <li>注意去发现网站是否有让你感到不便使用或让你迷惑的地方，如果有，请提出你的解决办法。</li>
    <li>如果可能的话，请关闭你使用的浏览器支持图像显示或支持JavaScript的功能，或是使用手机上网访问一个网站，与你使用计算机访问同一网站的体验做一个比较。</li>
</ul>
<ul style="list-style-type: none;">
    <li><a href="http://www.w3cgroup.com/article.asp?id=271">上一篇：信息架构&mdash;&mdash;规划一个Web站点</a></li>
    <li><a href="http://www.w3cgroup.com/article.asp?id=274">下一篇：色彩理论</a><a href="http://kb.operachina.com/wsc/#toc"><br />
    </a></li>
</ul>
<h2>作者简介</h2>
<p><img alt="Picture of the article author Mark Norman Francis" src="http://kb.operachina.com/files/norm.jpg" style="float: right; margin-left: 10px;" /></p>
<p>Mark Norman Francis 早在万维网诞生前，就在从事互联网领域的工作了，一直持续到现在。目前他是全球最大网站Yahoo! 的前端设计师，负责制定Web开发的最佳习惯、代码标准和质量标准。</p>
<p>在加入Yahoo!前，他先后在Formula One Management（F-1管理公司）、Purple Interactive （紫色互动公司）、伦敦城市大学从事过多种工作，包括Web开发、后端CGI编程和系统架构等。他的博客地址为：<a target="_blank" href="http://marknormanfrancis.com/">http://marknormanfrancis.com/</a>。</p>
<p id="license">本文采用的授权是<a target="_blank" rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/">创作共用的&ldquo;署名-非商业性使用-相同方式共享 2.5 通用许可&rdquo;</a>。</p>
</div>
</div>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=272</link>
			<title><![CDATA[语义化的HTML与搜索引擎优化]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Thu,29 Oct 2009 09:47:10 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=272</guid>
		<description><![CDATA[<h2>Semantic HTML and Search Engine Optimization(how to be a POSH SEO)<br />
语义化的HTML与搜索引擎优化(如何编写纯语义的HTML进行搜索引擎优化)</h2>
<p>By: <a href="http://dev.opera.com/author/636657" target="_blank">Joost.De.Valk</a><br />
Translate: <a href="http://www.w3cgroup.com" target="_blank">W3CGroup dh20156</a></p>
<h3>Introduction<br />
简介</h3>
<p>So what is POSH? No, it's not just some new clothing fashion hype amongst web designers - POSH is the acronym for Plain Old Semantic HTML. The term Semantic HTML is used for a variety of things, but it has it's origin in one objective: creating (X)HTML documents using semantic elements and attributes, as opposed to using presentational HTML. The term POSH was coined because a group of highly respected web designers wanted to have a short mnemonic to easily capture the essence of the concept of Semantic HTML.<br />
<br />
什么是POSH?它可不是网页设计师们谈论的服装、时尚,POSH是plain old Semantic HTML的缩写。Semantic HTML可以用在很多地方，不过，它的本意是创建(X)HTML文档中，使用语义化的对象或属性，而不用表象（只为显示效果）的HTML。POSH的产生，来自一群令人追崇的网页设计师,他们希望能够写出简短、易记，能够使人一看就知道其意义的语义化HTML。<br />
<br />
In this article, I talk about why you should use POSH, exactly what you need to do to implement it (many of you are probably doing this already, and a few of you might not even realize it!) and how you can optimize it to improve SEO for your site. I also take a brief look at Microformats at the end of the article.<br />
<br />
在这篇文章中，我会讲述为什么要使用POSH，你应该如何正确地去做（可能有一些你们已经在做，有一些你还不了解）以及如何去改善你的站点的SEO。我会在文章后稍微看一下微格式部分。</p>
<h3>Why Should I Use Semantic HTML?<br />
为什么要使用语义化的HTML？</h3>
<p>You could just say: &quot;because it's the right thing for the web,&quot; but it's benefits go far beyond that. For instance, it makes it easier for screenreaders to interpret in an order that will make sense to users with visual impairments.<br />
<br />
你也许会说：&ldquo;因为它对WEB有好处&rdquo;，然而，它的好处远不止于此。比如，它使得屏幕阅读器更容易使用，这对那些视觉障碍的用户将非常有意义。<br />
<br />
Secondly, SEO and Semantic HTML are close friends. They might sometimes have conflicts of interest, which we'll get to later on in this document, but over all, they're friends. The purpose of SEO is to help search engine spiders better understand what a page is about and therefore categorize them better. Since a search engine spider basically has even less capabilities than a screenreader, it needs even more guidance in determining a page's structure and topic. Good semantic HTML provides just that structure.<br />
<br />
其次，SEO对语义化的HTML更亲睐。他们可能有时候会有一些冲突（我们将在后面看到），但是，语义化HTML仍然是对SEO非常友好。SEO的目的是帮助搜索引擎更好地理解一个页面讲述的是什么主题以便更好地对它进行分类。既然搜索引擎都只有这些基础功能，更何况是屏幕阅读器。它们需要在页面结构和主题确定时给予更多的提示。好的语义化HTML将会是很好的支持。<br />
<br />
Semantic HTML tries to convey meaning through the words and the tags on a page. Try thinking of it this way: the content on the page is the words you speak. The tags provide the structure, the intonation, the pauses and even the looks on your face. Basically, your tags are half your message.<br />
<br />
语义化的HTML会试图将页面上标签与标签中的内容联系起来。你可以试着这样去想：页面上的内容是你需要念出来的，而标签提供了一种结构，语调，停顿等辅助信息，基本上，标签起到了另一半信息的作用。</p>
<h3>Site Structure<br />
站点结构</h3>
<p>In my <a href="http://dev.opera.com/articles/view/intelligent-site-structure-for-better-se/" target="_blank">previous article on dev.opera.com</a> I talked about site structures, with the aim of providing a clear way for search engines to discover which page on your site discusses which topic - this can be further improved by using Semantic HTML.<br />
<br />
在我发表在<a href="http://dev.opera.com/articles/view/intelligent-site-structure-for-better-se/" target="_blank">dev.opera.com上的前一篇文章</a>里，我谈过了站点结构，目的是为了提供给搜索引擎一个更清晰的更好的方法来发现你站点中哪一页上谈论哪一话题，这个可以通过使用语义化HTML来实现。</p>
<h3>Page Structure<br />
页面结构</h3>
<p>A page consists of a title, one or more headings, and content. This content can contain paragraphs of text, lists, quotes, images and tables. All these types of information have their own designated tag(s). We will treat all those tags, starting with the headings. Use this page about sortable tables as an example to follow along with for the coming points.<br />
<br />
一个页面会由一个主标题，一个或多个内容标题，和内容来组成。内容部分可以包括段落，列表，引用，图片和表格。所有的这些资料都会有它们特定的标签。我们将一个一个来分析，先从内容标题(headings)开始。用一个排序表格的页面来做例子。</p>
<h3>Headings,from h1 to h6<br />
内容标题，从h1到h6</h3>
<p>A good document has headings and subheadings, because headings make it easier to determine the topic of a page. These headings can range in importance from h1 to h6. To be honest, I never use h5 and h6 myself. I usually have only one h1 tag on a content page; on portal pages, blog homepages for instance; you can have multiple h1's, for all your articles for example. From a semantic perspective that might be weird, from an SEO perspective, it's great.<br />
<br />
一个好的文档应该有主标题和副标题，因为它们可以更容易帮助确定一篇文章的主题。这些标题可以按重要性分为h1到h6.老实说，我自己从来不用h5和h6,经常只在页面内容中使用h1。在一些门户页面，比如说博客首页，你可以为你的每一篇文章使用一个h1，虽然这从语义上来讲可能不太合适，但从SEO的角度来看，这实在太棒了。<br />
<br />
Strict semanticists sometimes suggest that you should only have one h1, two h2's, 3 h3's etc. I don't agree with that, as I think it's very normal for a document to have more than two h2's, in fact, this document has a lot more of them, and I think it's very well structured.<br />
<br />
严格的语义学家有时会建议你只使用1个h1，2个h2，3个h3等等，不过，我不太赞同，我认为，一个文档中很容易会存在两个以上的h2，事实上，这篇文档中就有许多，我觉得它们组织的很好。<br />
<br />
Very often, designers who have heard a bit about Semantic HTML will fit the name of a site in the header into an h1 tag. On the homepage of a site, that might be a very wise decision. On every other page within your site, you probably have a specific topic, which might be related to your site's name but doesn't have to be. On those sub pages, that topic should be in the h1 tag, and it's wise to put the name of your site into an h4 tag or maybe even a span.<br />
<br />
经常，设计师们会听到语义化HTML将一个站点的名称放在一个h1标签中更适合。在站点首页，那可能是很棒的决定。在其他页面，你可能会有一些具体的主题，可能与你的站点名称有关或者没有，在这些页面上，主题可以放到h1标签，站点名称可以放到一个h4标签或者span标签内。<br />
<br />
Search engines give the words used in the various headings more weight in determining the topic of a page. The keyword your page is optimized for should appear at least once in an h1 tag, and related keywords should be used in the other headings, as illustrated in Figure 1.<br />
<br />
搜索引擎给那些在headings标签内帮助确定页面主题的字词更高的权重。你页面上要优化的关键词应该将它们放在至少一个h1标签内，其他相关关键词应该放在其他的headings标签内，如图1.<br />
<br />
<img alt="" src="http://www.v-ec.com/dh20156/file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/moz-screenshot-1.jpg" /><img alt="" src="http://www.v-ec.com/dh20156/file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/moz-screenshot-2.jpg" /><img alt="" src="http://www.v-ec.com/dh20156/file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/moz-screenshot-3.jpg" /></p>
<p><img alt="Sample web site sceenshot showing sensible use of keywords in headings" src="http://dev.opera.com/articles/view/semantic-html-and-search-engine-optimiza/headingsExample.png" /></p>
<p>Figure 1:Include keywords in your page headings to improve SEO for your page.<br />
图1：在页面上用headings包含关键词以改善SEO</p>
<h3>Images<br />
图像</h3>
<p>Images are used in all sorts of ways within documents, and you should apply the proper semantics to them. The only really useful semantic variable on an img tag is the alt attribute, and it should only be used if the image adds meaning to the document. If the image is there only for decorative purposes, leave the altattribute empty. Otherwise, describe what the image is showing in the alt attribute.<br />
<br />
图像在一个文档中以各种不同的方式使用着，你需要给它们应用上一些适当的语义。在img标签上真正有用的语义变量就是alt属性，它仅用在图像在文档中注明它所表达的含义的时候。如果某些图像仅仅是为了装饰的目的，那么可以使alt为空，否则，都需要指明它们的alt属性值。<br />
<br />
If you're using images to replace text, because you want the text to look nicer (image replacement,) make sure that you're using normal text in your HTML, and that you replace that text with images by using CSS. You have to do this because both people with visual impairments and search engines cannot read the text in your images. My own preferred method of doing this is through applying the image with CSS background-image, and then hiding the HTML text using a large text-indent (about -1000px or so does the trick.) Be careful though: the text in the image should be exactly the same as the text in your document. If it's not, you risk losing a lot of ranking value from the search engines.<br />
<br />
如果你要以图换字，使得文字看起来更漂亮（用图片替换），请务必在你的HTML代码中也写上正常的文字，而且，你需要使用CSS来将图像替换相应的文字。这样做的目的是因为要兼顾到那些视觉障碍的人，并且搜索引擎无法读取图像里的文字。我的首选方法是使用background-image来显示这个图片，然后使用一个很大的text-indent(比如-1000px或其他能达到效果的值）来隐藏文字。注意：图像中的文字应该和文档中的文字完全一样，否则，你将冒上被搜索引擎降低排名的风险。</p>
<h3>Abbreviations and acronyms<br />
缩写和首字母组合词</h3>
<p>You're bound to do it as a web designer - I do it in this article several times - using acronyms or abbreviations. When you do, make sure you provide the written out version of the term using abbr or acronym tags. That's good for your keyword density too!<br />
<br />
作为一名网页设计师，你一定会使用到，我在这篇文章里就用了好几次，使用首字母组合词或缩写。当你使用它们的时候，请将术语写到abbr或acronym标签里并在它们的title属性中写出该术语的全称。这对增加你的关键词密度同样有益。</p>
<h3>Tables<br />
表格</h3>
<p>We all know why using tables for layout out web sites is bad, and we also know what they are supposed to be used for - displaying tabular data. Just using basic tables is a big step in the right direction, but there are a number of ways in which you can improve your tables' semantic value, thereby improving your site's SEO further:<br />
<br />
我们都知道为什么用表格来呈现页面布局是不和谐的，我们知道，表格应该用来显示表格式数据。只使用它这个基本的功能是正确的，不过，有一些方法可以用来改善表格的语义，改进SEO。<br />
<br />
- Use table headings(th) for your table's headings(it's really that easy)<br />
- 为表格中的标题使用标题标签(th，这很容易)<br />
<br />
- If you can,use the thead,tbody and tfoot sections to properly section your table<br />
- 如果可以，使用thead,tbody和tfoot进行对你的表格进行合理的划分<br />
<br />
- provide a caption for your table,describing what's in it<br />
- 为表格提供一段说明标题写在caption标签里<br />
<br />
The caption and the table headings would be a good,and usually natural place to use some of your document's keywords.<br />
caption和th可以很自然的放置一些文档关键词，很和谐。</p>
<h3>Emphasizing your meaning<br />
强调你要表达的意思</h3>
<p>Remember I said earlier that tags should be the emotion of your text? This is where the real emotion comes in: you can provide emphasis to certain words using em or strong. In the old days, people used b and i for that, but these tags are no longer encouraged, since they imply a specific styling, whereas HTML should only describe structure/meaning (all style should be created using CSS, of course.)<br />
<br />
还记得我之前说过标签会让你的文字带有情感么？你可以这样：将要强调的字词放在em或strong标签内。在以前，人们常常使用b和i标签来做，但这些标签是不建议使用的，因为，这些标签仅仅是为了实现特别的样式，而HTML要的应该是结构描述和意义（所有的样式应该由CSS来完成。）<br />
<br />
Search engines give more weight to any words marked up using any of these four tags. Overusing them can do more harm than good, and actually cause a loss of emphasis, but if treated with care, they can apply an extra dimension to your documents.<br />
<br />
搜索引擎会给这四个标签内的文字更高的权重，不过，如果滥用，将弊大于利，而且，反而会影像要强调的内容，但是，如果妥善应用，这会为你的文档增色不少。</p>
<h3>A few words on (i)frames<br />
简单讲一下(i)frames</h3>
<p>It's quite simple:don't use them.Search engines don't get them,and screenreaders have quite a hard time using them as well.<br />
很简单：别用它们。搜索引擎根本不去抓取它们，而且，屏幕阅读器在读取它们时非常费劲。<br />
&nbsp;</p>
<h3>Conflicts of interest<br />
利与弊</h3>
<p>All of the above rules can be bent a little of course, which is a good thing, as sometimes it's necessary to keep everyone at your organization happy. Say your boss wants a page to have a zappy marketing title you'd rather not have, because it doesn't exactly describe what's on the page, and pushes your most important keyword to the second heading. If you're in a competitive area, it might be wise to make the page look like that for your boss, yet use an h2 for the first heading, and an h1 for the second.<br />
<br />
以上这些规则多少会感觉有些别扭，然而，好的东西有时候对维持你们单位成员的幸福非常有必要。比如，你老板希望一个页面能有个吸引人的销售标题，而你宁可不要，因为，它不能完全地描述这个页面上的内容，而且这会将你认为最重要的关键词要放在第二个标题内。但是，如果你们行业竞争激烈，你老板那样做是很明智的，页面上还要用一个h2标签放第一个标题，一个h1标签放第二个。<br />
<br />
The same goes for iframes and images. If someone really wants you to put a certain block of content on a specific well-ranking page, but you don't want to risk losing focus, you could of course put that content into an iframe or image, and choose not to provide an alternative.<br />
<br />
这种矛盾同样适用于iframes和images.如果有人一定要你在一个排名特别好的页面上插入一些打断的内容而你又不想冒降级的风险，你可以选择将这些内容放在一个iframe里或者一张图片里。<br />
<br />
These decisions are up to you in the end - normal semantics should be the basis of your design, and the conflicts should only arise when you're really optimizing your pages.<br />
<br />
最终的决定在你，正常的语义学应该基于你的设计，而真正的利益冲突会在你真正对自己的页面进行优化时才出现。</p>
<h3>Not so simple semantic HTML - Microformats<br />
不那么简单的语义化HTML - 微格式</h3>
<p>Microformats are also semantic HTML, but they are not exactly simple! At the moment, search engines are hardly using microformats in their algorithms, but that might change. The hCard especially (the HTML version of the vCard) has some very easy and obvious uses for search engines, and I suspect that they will start using those within the next couple of years. You can apply intelligent extra semantics within Microformats using the basic set of HTML elements - for example, a good way of marking up your address hCard is by using the address tag as a container!<br />
<br />
微格式也是语义化的HTML，但是它们却不那么容易。现在，搜索引擎算法还很难理解微格式，但是，这可能会得到改变。hCard（vCard版本的HTML）有很多简单易用的东西针对搜索引擎，我想它们将在随后的数年里使用它们。你可以使用额外的可增强理解的语义化微格式HTML元素，比如，一种好的标识你的地址的hCard会使用address标签来包含。</p>
<h3>Conclusion<br />
总结</h3>
<p>By using semantic HTML to mark up your pages, you can create pages that are more accessible, both to people with disabilities, as well as to search engines. Good semantic markup helps search engines to determine what the topic of a page is, and if used together with a good site structure, allows you pushy up your web site rankings!<br />
<br />
在你的页面上使用语义化HTML，你可以使得它们更易访问，对那些视力障碍的人们和搜索引擎都有好处。好的语义化HTML可以帮助搜索引擎确定页面的主题，如果你同时有一个好的站点结构，这将使得你的网站排名得到提高。<br />
<br />
This article is licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.5/" target="_blank">Creative Commons Attribution, Non Commercial - Share Alike 2.5 license</a>.</p>
<p>本文采用的授权是<a href="http://creativecommons.org/licenses/by-nc-sa/2.5/" target="_blank">创作共用的&ldquo;署名-非商业性使用-相同方式共享 2.5 通用许可&rdquo;</a>。</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=271</link>
			<title><![CDATA[信息架构——规划一个Web站点]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Wed,28 Oct 2009 14:55:08 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=271</guid>
		<description><![CDATA[<div class="content">
<div id="wsc">
<p>作者：<a href="http://dev.opera.com/author/1072078" target="_blank">Jonathan Lane</a> &middot; 2008年7月8日</p>
<ul style="list-style-type: none;">
    <li><a href="http://www.w3cgroup.com/article.asp?id=270">上一篇：Web标准所包括的模块HTML、CSS和JavaScript</a></li>
    <li><a href="http://www.w3cgroup.com/article.asp?id=273">下一篇：一个好的网页需要什么？</a><a href="http://kb.operachina.com/wsc/#toc"><br />
    </a></li>
</ul>
<h2>序言</h2>
<p>一般说来，规划一个Web站点（或任何项目）都是一件有点麻烦的工作。对于一个Web站点应该怎样构建，每个人都有自己的意见，而且这些意见之间常 存在冲突。在构建任何Web站点时，你的首要目标都应该是构建一个对将要使用站点的用户有用的Web站点。也就是说，如果你要构建的是针对某一特定人群的 Web站点，只有这个人群的意见才是重要的。而其他如你的老板的意见，拥有软件工程博士学位的人的意见，甚至你的个人偏好，都不是真的重要。</p>
<p>在本篇文章中，我将讲述规划一个Web站点的前期阶段，以及一门一般被称为&ldquo;信息架构&rdquo;（其简写为IA）的学科。主要内容包括你的目标受众是哪些 人，他们需要从一个Web站点获取什么样的信息和服务，以及你应该怎样构建一个站点，以向他们提供这些信息和服务。我将讲述需要放置在Web站点上的信 息，如何拆分信息，以及这些被拆分的信息如何相互联系。内容分节如下：</p>
<ul>
    <li><a href="http://www.v-ec.com/dh20156/#siteplanning">你需要规划你要构建的Web站点 </a>
    <ul>
        <li><a href="http://www.v-ec.com/dh20156/#introducingtheidea">&ldquo;The Dung Beatles&rdquo;乐队简介</a></li>
        <li><a href="http://www.v-ec.com/dh20156/#sitemaps">画出网站地图 </a></li>
        <li><a href="http://www.v-ec.com/dh20156/#namingpages">为网页命名 </a></li>
        <li><a href="http://www.v-ec.com/dh20156/#addingdetail">添加一些细节 </a></li>
    </ul>
    </li>
    <li><a href="http://www.v-ec.com/dh20156/#summary">总结</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#exercises">练习题 </a></li>
</ul>
<h2 id="siteplanning">你需要规划你要构建的Web站点</h2>
<p>你们可能遇到这样的Web项目，不进行任何前期构想和规划，就直接开始让你投入工作，不过这只是例外，而不是常态。以下我们将以一个被称为&ldquo;The Dung Beatles&rdquo;的虚构乐队为例，看看我们怎么帮助这个乐队规划其Web站点。我们将先大致了解一下这个乐队，找出他们建站希望达到的目标，以及他们希望 在其Web站点上展示那些信息。然后我们就开始为该乐团的信息构造一个结构框架。</p>
<h3 id="introducingtheidea">&ldquo;The Dung Beatles&rdquo;乐队简介</h3>
<p>The Dung Beatles乐队(简称TDB乐队)遇到了一个问题。他们是萨斯喀彻温省摩斯乔市最当红的模仿Beatles（披头士乐队）的乐队，但他们还需要在今年 夏天即将举行的北美巡演中提高乐队的知名度。他们计划在加拿大和美国各地巡演，但他们在本城之外就几乎无人知晓了。如果有某种方式，让他们花费较少的金钱 就可以为众多的Beatles迷知晓，那就好了。</p>
<p>TDB乐队很幸运，有一种叫做万维网的技术可以帮助他们实现这个目标，因此他们迅速决定建立一个自己的网站。TDB乐队需要通过自己的网站推广他们的北美巡演，建立起一个粉丝群，并提高乐队的知名度。你们将针对他们的想法，看是否能为他们的网站制订一份规划。</p>
<p>你安排了一次与这个新客户的面谈，以具体了解他们的需求并确定建站的时间要求和费用。在面谈开始时，你首先提议讨论网站的目标和目的，以了解这个乐队希望通过这个网站实现什么样的目标。</p>
<p>TDB 乐队开始谈论他们将进行的北美巡演，以及他们希望向每一个巡演地点的所有Beatles迷传达什么样的信息。现在已经是2月了，他们计划在5个月内就启动他们的巡演。</p>
<p>在此打住一下! 一个网站本身是不会自动产生访问流量和宣传自己的。通过和乐队的交谈，你已知道该网站的主要目标是为TDB乐队的粉丝提供一个网上家园，通过该网站他们就 能够了解乐队最新的新闻、巡演的日期和地点。通过这些粉丝的传播，以及其他一些广告宣传手段，新用户将访问这个网站，在网站上下载乐队的单曲、观看乐队的 照片（化妆照），以及确认他们将在什么时间、什么地点观看到乐队的现场演出。</p>
<p>乐队的负责人Raul McCoffee指出，如果能通过销售一些乐队的CD和其他商品为巡演筹集一些额外的资金的话，那就太好不过了。你已经大致了解了乐队和其建站目标，快速勾画出访问网站的人可能的需求。这还只是初步的创意阶段，基本上还没有涉及到规划网站的结构。</p>
<p>可以把将要访问乐队网站的人分为两大类：TDB乐队已有的粉丝；还不太确定是否会成为乐队粉丝的人。你决定以不同的方式满足这两大类人群的需求：对 潜在粉丝，是向他们&ldquo;推销&rdquo;乐队；对已有的粉丝，是强化他们对乐队的&ldquo;沉迷&rdquo;。这两大类人群各自需要在网站上寻找哪些信息？图1就勾画出网站访问者需要哪 些信息的轮廓，基于这个轮廓，你就可以规划网站需要哪些页面，以及这些页面如何相互链接起来。</p>
<p><img src="http://kb.operachina.com/files/article6_1.gif" alt="a rough sketch of what your web site should contain" /></p>
<p class="article_comment">图1：网站访问者需要哪些信息</p>
<p>你确定好建站预算，并同意在一个月内推出网站。你答应在一两天后回访乐队，向他们提交建站工作的计划。</p>
<h3 id="sitemaps">画出网站地图</h3>
<p>在这个阶段，很多人会提出一个网站地图，它看起来与组织结构图相似。网站地图通常显示网站每个页面的名称，以及它们在网站总体结构中是如何相互链接 起来的。就我个人来说，我会在网站地图中提供稍微详细一些的信息，包括每个页面的目的和内容。例如，一个页面可能被标注为&ldquo;主页&rdquo;，但&ldquo;主页&rdquo;到底是什么 呢？是仅打出&ldquo;欢迎访问我们的网站&rdquo;字样的页面呢，还是一个内容更为丰富，包含新闻条目和吸引人的图片的页面呢？请花费几分钟时间，思考以上那个信息轮廓 图将具体转化为哪些页面，每个页面要包含哪些内容。请动手画出网站地图。</p>
<p>现在我们来看一个网站组织结构图的示例。图2是一个我根据和乐队的讨论结果，画出的一个乐队网站的组织结构图：</p>
<p><img src="http://kb.operachina.com/files/article6_2.gif" alt="the first iteration of the site structure" /></p>
<p class="article_comment">图2：初步的网站结构图。</p>
<p>这个图已确定无疑地包含了所需要的所有页面，但尚未将页面分类。它只是列出了一大堆页面，其名称尚未经仔细推敲。下一步的工作就是将页面分成几个大类，分类的结果如图3所示：</p>
<p><img src="http://kb.operachina.com/files/article6_3.gif" alt="the site structure grouped more logically" /></p>
<p class="article_comment">图3：修订后的网站结构图。</p>
<p>在修订后的网站结构图中，我做了一些改进工作。&ldquo;乐队新闻&rdquo;页面让TDB乐队可发布想和其粉丝分享的任何信息。即使在他们的夏季巡演结束后，&ldquo;巡演 日期和地点&rdquo;页面已不再相关，他们还是可以在&ldquo;乐队新闻&rdquo;页面发布信息。这里采用了blog（博客）形式，使乐队的粉丝可以在此发表各种评论，有助于建立 起一个以TDB乐队为主题的网络社区。新闻和巡演事件可能是最热门的讨论话题，因此就把这两个主题划分在同一个组。此外，&ldquo;News（新闻）&rdquo;是一个更简 洁、更具有概括性的词，有助于浏览页面寻找信息的人，更快地找到页面。</p>
<p>新的&ldquo;关于The Dung Beatles乐队&rdquo;页面，包括进了每位乐队成员的传记以及他们的图片。访问这个页面，就可以点击访问每位乐队成员的传记。正如我们以上说的那样，页面标 题最好使用更简洁、更具有概括性的词，而&ldquo;About（关于）&rdquo;这个词就是很多网站都经常使用的一个页面标题词。网站访问者不论是想了解一家公司，一种产 品或服务，还是某一个人，通常都会在&ldquo;About（关于）&rdquo;页面中寻找相关信息。</p>
<p>最后，&ldquo;Discography（唱片分类目录）&rdquo;是一个专业术语，了解这个词确切含义的人，可能要少于了解&ldquo;音乐&rdquo;这个词含义的人。此 外，&ldquo;Discography（唱片分类目录）&rdquo;这个页面可以包含一些额外的内容，如某一首歌曲的灵感来源、历史等。在讲述了一些关于如何简单明确地为页 面命名后，我们将学习如何为每个页面添加一些更详细的信息。</p>
<h3 id="namingpages">为网页命名</h3>
<p>在设计网站的过程中，为网页命名是最重要的步骤之一。这不仅是因为通过网页名称，访问者可以顺畅地访问网站，而且是因为网页的名称是决定使用搜索引擎找到网站的难易度的重要因素（在本课程中，我们会多次提到搜索引擎优化）。</p>
<p>一般而言，在确定一个网页的重要程度时，搜索引擎查看包括在一个网页中的文本、该网页的URL地址，以及指向那个网页的链接。为你的网页赋予简单明确的名称和URL地址，有助于搜索引擎准确地描述网页。</p>
<p>我举一个例子。假设你们是一家汽车公司，有一款叫做&ldquo;The Speedster &rdquo;（速行者）的车。你已建立了一个汽车推广网站，其中有一个网页用于列出该车型的现有车型特点。你如何命名这个网页呢，是&ldquo;车型特点&rdquo;、 &ldquo;现有车型特点、&ldquo;Speedster车的特点&rdquo;，或是&ldquo;车型特色&rdquo;呢?我认为 &ldquo;Speedster车的特点&rdquo;是最恰当的名称。它指明了该网页包含的内容，这样可以将改标题放在页面上方最显眼的位置（便于搜索引擎将之编入索引），甚 至可以使网页内容和URL地址更匹配(如使用这样一个URL地址：&ldquo;www.autocompany.com/speedster/speedster- features/&rdquo;)。</p>
<h3 id="addingdetail">添加一些细节</h3>
<p>在这个阶段，你没有必要确定每一个细节，但你至少需要给出每一个页面的简要描述。在你确定了网站的结构后，给出所需网页的数量，以及每个网页的简要描述。图4就是我对乐队网站主页的简要描述 (在课后的练习题中，有一道题就是参照图4，给出其他页面的简要描述)。</p>
<p><img src="http://kb.operachina.com/files/article6_4.gif" alt="page details for the home page" /></p>
<p class="article_comment">图4：主页的页面详细描述。</p>
<p>你只需要简要地描述页面的主旨即可，不必详细描述页面的功能，你制作网页所使用的技术，以及页面布局和设计。你这样做的目的是向客户传达你的网页构想，使你能全面思考每一个要点。</p>
<p>在这个阶段，你有可能发现你规划了太多的网页，不能为每个网页找到相应的内容。在创建网页之间的层级时，你有可能被搞得心烦意乱。例如，如果乐队成 员只是想发布一段关于他们自己的介绍，就不需要为每位乐队成员都创建单独的&ldquo;传记&rdquo;网页，而可以把每个成员非常简短的个人介绍集中到一个网页上。</p>
<h2 id="summary">总结</h2>
<p>在本篇文章中，我们讲述了如何规划一个Web站点的总体结构。在下一篇文章中，你们将学习从网页层次看，要构建出一个好的Web站点，需要包含哪些 要素，以及这些要素的具体配置。8、9、10三篇文章，将讲述网页的视觉设计。因此，在构建Web站点时，请遵照以下三个步骤（在每一个阶段都与客户沟 通，确认他们对每个阶段的工作都满意）：</p>
<ol>
    <li>首先，确定Web站点的内容，并确定如何将这些内容组织进网页中。</li>
    <li>其次，确定Web站点各个需要实际使用的功能。</li>
    <li>最后，在开始编写Web站点的代码前，先要进行视觉设计，如确定页面布局、配色方案等。</li>
</ol>
<h2 id="exercises">练习题</h2>
<ul>
    <li>参照图1，编制一个汽车网站（选择任何一种汽车，现实的或想象的）的信息轮廓图。</li>
</ul>
<ul>
    <li>网站访问者想要了解哪些信息?</li>
    <li>在现有的汽车网站中，你认为哪些信息栏目是不可或缺的，哪些又是显得多余的?</li>
</ul>
<ul>
    <li>整理信息轮廓图，思考什么样的页面分组才合适。</li>
    <li>在规划一个网站时，研究同类网站有时也是很有用的。搜索一个模仿型乐队的网站，查看网站提供的信息和栏目。我们的网站遗漏了什么吗？</li>
    <li>参照图4，为我已提到的乐队网站的其他页面编制同样的页面详细描述图。</li>
</ul>
<ul style="list-style-type: none;">
    <li><a href="http://www.w3cgroup.com/article.asp?id=270">上一篇：Web标准所包括的模块HTML、CSS和JavaScript</a></li>
    <li><a href="http://www.w3cgroup.com/article.asp?id=273">下一篇：一个好的网页需要什么？</a><a href="http://kb.operachina.com/wsc/#toc"><br />
    </a></li>
</ul>
<h2>作者简介</h2>
<p><img style="float: right; margin-left: 10px;" src="http://kb.operachina.com/files/Jonlane.jpg" alt="Picture of the article author Jonathan Lane" /></p>
<p>Jonathan Lane 是 Industry Interactive（工业互动）公司的总裁，该公司是一家从事Web开发及Web应用程序开发的公司，位于加拿大不列颠哥伦比亚省梅恩岛。他曾在Lethbridge大学的课程再开发中心工作过多年，担任该中心Web项目的协调人。</p>
<p>他的博客地址为：<a href="http://www.flyingtroll.com/" target="_blank">http://www.flyingtroll.com/</a> 。目前他正在开发 Mailmanagr 软件&mdash;Basecamp 项目管理应用程序的一个 e-mail 界面。</p>
<p id="license">本文采用的授权是<a href="http://creativecommons.org/licenses/by-nc-sa/2.5/" rel="license" target="_blank">创作共用的&ldquo;署名-非商业性使用-相同方式共享 2.5 通用许可&rdquo;</a>。</p>
</div>
</div>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=270</link>
			<title><![CDATA[Web标准所包括的模块HTML、CSS和JavaScript]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Mon,26 Oct 2009 11:38:29 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=270</guid>
		<description><![CDATA[<div class="content">
<div id="wsc">
<p>作者：<a target="_blank" href="http://dev.opera.com/author/1072078">Jonathan Lane</a> &middot; 2008年7月8日</p>
<ul style="list-style-type: none;">
    <li><a href="http://www.w3cgroup.com/article.asp?id=269">上一篇：互联网是如何运转的？</a></li>
    <li><a href="http://www.w3cgroup.com/article.asp?id=271">下一篇：信息架构&mdash;&mdash;规划一个Web站点</a><a href="http://kb.operachina.com/wsc/#toc"><br />
    </a></li>
</ul>
<h2>序言</h2>
<p>在上一篇文章，我们已粗略了解了网页的三大构造块：HTML（或XHTML），CSS和JavaScript。现在我们再深入了解和考察这三大构造块，了解和考察它们各自的功能及它们之间如何相互作用而创建出Web站点的。本篇文章的内容如下：</p>
<ul>
    <li><a href="http://www.v-ec.com/dh20156/#whyseparate">为什么要将HTML、CSS、JavaScript这三者分离?</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#markup">标记，每个网页的基础</a>
    <ul>
        <li><a href="http://www.v-ec.com/dh20156/#xhtml">什么是XHTML?</a></li>
        <li><a href="http://www.v-ec.com/dh20156/#validation">什么是校验?</a></li>
    </ul>
    </li>
    <li><a href="http://www.v-ec.com/dh20156/#css">使用CSS添加样式</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#javascript">使用JavaScript向网页中添加行为</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#example">一个示范网页</a>
    <ul>
        <li><a href="http://www.v-ec.com/dh20156/#index">index.html</a></li>
        <li><a href="http://www.v-ec.com/dh20156/#styles">styles.css</a></li>
    </ul>
    </li>
    <li><a href="http://www.v-ec.com/dh20156/#exercises">总结</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#exercises">练习题</a></li>
</ul>
<h2 id="whyseparate">为什么要将HTML、CSS、JavaScript这三者分离?</h2>
<p>这是人们通常问的关于Web标准的第一个问题。既然可以仅使用HTML就完成网页的内容编写、样式设定（使用HTML的Font元素）和页面布局 （使用HTML表格），那为什么还必须使用XHTML/CSS（层叠样式表）呢？在过去，人们在设计网页时常使用一些不好的方法如用HTML表格来进行页 面布局等，就是现在都还有很多人仍在使用这些不好的方法（但你们绝对不应该这样做），这也就是我们要推出本课程的原因之一。在本课程中，我们不会讲述这些 过时的方法。以下是一些你需要抛弃那些过时的方法，取而代之以使用CSS和HTML的有力理由：</p>
<ol>
    <li><strong>代码的效率</strong>：你放在服务器上的文件越大，下载文件需要的时间就越长，一些上网的人可能支付的费用也就越高（现 在一些人仍然是按下载的megabyte（兆字节）数支付网费的）。因此你希望避免出现这种情况：在每一个HTML文件中都包含大量的样式和页面布局信 息，从而浪费带宽。你可以选择另一种好得多的方式，即在HTML文件中使用最精简的代码，而把样式和页面布局信息包含进CSS文件中。你们可以在网页设计 站点A List Apart Slashdot上的一篇文章（<a target="_blank" href="http://www.alistapart.com/articles/slashdot/">the A List Apart Slashdot rewrite article</a>）中找到使用这一方法的一个实例，在该篇文章中，作者以一个非常受欢迎的Web站点为例，用XHTML/CSS重写了该站点的网页代码。</li>
    <li><strong>易于维护</strong>：接着上一点讲，如果页面的样式和布局信息保存在单独的CSS文件中，那么你在想改变站点的外观时，仅需要在单独的CSS文件中做出更改即可。难道你会更愿意在站点的每一个网页中一处一处地去更改样式和布局信息吗？我想不会。</li>
    <li><strong>可访问性</strong>：上网用户中那些视力受损的人，可以使用一种叫&ldquo;屏幕阅读器&rdquo;的特殊软件，通过耳朵听而不是眼睛看来 访问网页，也就是说，屏幕阅读器将网页的内容读给他们听。此外，如果语义化的网页编写得好，也有助于有运动障碍的人使用语音输入软件无障碍地访问网页。与 使用屏幕阅读器的用户用键盘命令来导航标题、链接、表单等类似，使用语音输入软件的用户用语音命令来导航标题、链接、表单等。在这些情况下，以语义化的 HTML（结构和表现相分离的HTML）编写的网页文件，就可以让这些用户更容易导航，且网页文件中的信息也更有可能被这些用户找到。换句话说，访问网页 &ldquo;内容&rdquo;的速度越快则越好。由于屏幕阅读器无法读取闭锁在图像中的文本，也会被一些所使用的JavaScript搞糊涂，因此你务必确保网页的关键内容可 以被每一个人访问。</li>
    <li><strong>设备兼容性</strong>：由于XHTML页面只是纯标记，没有附加样式信息，它就可以针对具有不同特点（如屏幕尺寸等）的设备而被重新格式化，只需要应用一种另外的样式表即可，具体做法有好几种（请访问dev.opera.com上关于移动Web开发的文章（<a target="_blank" href="http://dev.opera.com/articles/mobile/">mobile articles on dev.opera.com</a>），了解具体的做法）。同时，CSS本身也可以让你为不同的呈现方式和媒体类型（如在屏幕上阅读网页，打印网页，在移动设备上阅读网页等）规定不同的样式表。</li>
    <li><strong>网络爬虫/搜索引擎</strong>：你肯定希望用户通过Google等搜索引擎，能更容易地找到你的网页。搜索引擎使用一种 专门的软件，即所谓&ldquo;爬虫&rdquo;，通读你的网页。如果由于你在编写网页时的失误，如未将标题按标题来定义等，爬虫就难于发现你的网页的内容，或是会错误地解释 哪些才是重要的内容，那么你的网页在搜索结果中的排名就会大受影响。</li>
    <li><strong>这样做是良好的习惯</strong>：这听起来有点像只是我个人的意见，但实际上你请教任何通晓Web标准的专业Web开发员或设计师，他们都会告诉你 ，将内容、样式和行为这三者分离，是开发Web应用程序的最佳方式。</li>
</ol>
<h2 id="markup">标记，每个网页的基础</h2>
<p>HTML和XHTML是由包含属性（attribute）的元素（element）组成的标记语言（有些是可选的，有些则是强制性的）。这些元素用于标记文档中各种不同类型的内容，并规定每部分的内容在Web浏览器中怎样被渲染（例如标题、段落、表格、符号列表等）。</p>
<p>正如你们预想的那样，元素定义内容类型，而属性定义这些元素的附加信息，例如识别元素的ID，或一个链接指向的位置。你必须牢记一点，标记应该尽可能地语义化，即应该尽可能精确地描述内容的功能。图1就是一个典型的(X)HTML 元素的剖析图。</p>
<p><img src="http://kb.operachina.com/files/article4_1.gif" alt="A typical HTML element" /></p>
<p class="article_comment">图1：(X)HTML元素的剖析图。</p>
<p>HTML和XHTML的差别究竟在哪里呢？</p>
<h3 id="xhtml">什么是XHTML?</h3>
<p>XHTML（可扩展超文本标记语言）中&ldquo;X&rdquo;的含义是&ldquo;可扩展的&rdquo;。初学者最爱问的一个问题是：&ldquo;我是该用HTML呢，还是XHTML？两者之间到底有什么差别呢？&rdquo;其实它们的功能是大体一样的，两者最大的差别是在结构上。见表1列出的HTML和XHTML的主要差别。</p>
<table>
    <tbody>
        <tr>
            <th>HTML</th>
            <th>XHTML</th>
        </tr>
        <tr>
            <td>元素和属性是大小写不敏感的，<code>&lt;h1&gt;</code>等同于<code>&lt;H1&gt;</code>。</td>
            <td>元素和属性是大小写敏感的，都以小写形式书写。</td>
        </tr>
        <tr>
            <td>一些元素不需要结束标签（例如paragraphs, <code>&lt;p&gt;</code>），而另一些元素（被称为空元素）禁止用结束标签(例如images, <code>&lt;img&gt;</code>)。</td>
            <td>
            <p>所有元素都必须有结束标签（例如 <code>&lt;p&gt;A paragraph&lt;/p&gt;</code>）。空元素的格式是，在起始标签中包含一个斜杠（例如，<code>&lt;hr&gt;&lt;/hr&gt; and &lt;hr  /&gt;</code>是等同的）。</p>
            <p>如果你将XHTML文件用作text/html, 则必须对所有被定义为&ldquo;空&rdquo;的元素使用简写语法，并在  /&gt;前加上一个空格。对任何未被定义为&ldquo;空&rdquo;的元素，即使其中无任何内容，也必须使用完整格式的标记（有单独的起始标签和结束标签)。</p>
            </td>
        </tr>
        <tr>
            <td>一些属性值可不在引号中。</td>
            <td>属性值必须要在引号中。</td>
        </tr>
        <tr>
            <td>一些属性可简写（如 <code>&lt;option selected&gt;</code>）。</td>
            <td>所有属性都必须使用完整的属性格式（如 <code>&lt;option selected=&quot;selected&quot;&gt;</code>）。</td>
        </tr>
        <tr>
            <td>服务器须以 <code>text/html</code> 这种媒体类型将HTML发送到客户端。</td>
            <td>XHTML须使用 <code>application/xhtml+xml</code> 这种媒体类型，但也可使用 <code>application/xml</code>，<code>text/xml</code> 或 <code>text/html</code>。如果使用 <code>text/html</code>，则必须遵循 <a target="_blank" href="http://www.w3cgroup.com/article.asp?id=252">HTML 兼容性指导原则</a>，因为这样浏览器将把其当作HTML处理（并使用错误恢复来解释语言之间的差别）。</td>
        </tr>
    </tbody>
</table>
<p class="article_comment">表1：HTML和XHTML的差别。</p>
<p>正如我已经说过的那样，你不用太担心写的是HTML还是XHTML。你只要严格遵照本课程所有文章给出的建议去做，并使用一种HTML文档类型（<a target="_blank" href="http://kb.operachina.com/node/29">关于文档类型，参见本课程第14篇文章</a>），你就不会犯什么大错。</p>
<h3 id="validation">什么是校验？</h3>
<p>由于HTML和XHTML是制订的标准（就这点而论，CSS也是制订的标准），万维网联盟（W3C）创制了一个被称为&ldquo;校验器 &rdquo;（validator）的好工具，它可以自动检查你制作的网页，并指出你所写的代码可能有的问题/错误（如遗漏结束标签或遗漏属性的引号等）。HTML 校验器可在线获取（网址：<a target="_blank" href="http://validator.w3.org/">http://validator.w3.org/</a>），它将自动侦测你使用的是HTML还是XHTML，以及你使用的是哪一种文档类型。如果你想检查你的CSS，适用的校验器也可在线获取（网址：<a target="_blank" href="http://jigsaw.w3.org/css-validator/">http://jigsaw.w3.org/css-validator/</a>）。</p>
<p>欲了解关于校验更多的信息，见本课程第24篇文章（尚未发布）。欲了解关于文档类型更多的信息，见<a target="_blank" href="http://kb.operachina.com/node/29">第14篇文章</a>。</p>
<h2 id="css">使用CSS添加样式</h2>
<p>层叠样式表（CSS）让你可以很好地控制文档的格式设定和布局。使用CSS，你可以改变或添加颜色、背景、字体大小、样式，甚至可以在网页内不同的 位置对元素进行定位。使用CSS来应用样式，主要有三种方式：一、 重定义一个元素；二、对一个ID应用一种样式；三、对一个类应用一种样式。下面我将分别讲述一下这三种方式：</p>
<ol>
    <li>
    <p>重定义一个元素。通过定义向元素添加样式的规则，你可以改变任何(X)HTML 元素的显示方式。如果你希望文档中所有段落都是双倍行距，并且是绿色的，你可以在CSS中添加如下所示的样式表声明：</p>
    <pre><code>p {<br />  line-height: 2;<br />  color: green;<br />}</code></pre>
    <p>现在任何包围在&lt;p&gt;&lt;/p&gt;标签之间的内容，其行高都将增加一倍，并将变为绿色。</p>
    </li>
    <li>
    <p>定义一个ID。你可以赋予一个元素以一个id属性，以在一个网页中识别该元素（在一个网页中，每一个ID只能使用一次）。例如，<code>id=&quot;navigation_menu&quot;</code>。这样你就可以很好地控制页面的格式设定。例如，如果你希望某一段落是双倍行距，并以绿色文本强调显示，则可以赋予它以一个ID：</p>
    <pre><code>&lt;p id=&quot;highlight&quot;&gt;Paragraph content&lt;/p&gt;</code></pre>
    <p>然后对它应用一种CSS规则，如下所示：</p>
    <pre><code>#highlight {<br />  line-height: 2;<br />  color: green;<br />}</code></pre>
    <p>这样做，该CSS规则仅会应用于网页内那个其 <code>id</code> 属性为 <code>highlight</code> 的段落（#是CSS惯例中用于指明ID的符号）。</p>
    </li>
    <li>
    <p>定义一个类。类与ID类似，它与ID的区别仅在于在每个网页你可以有多个相同的类。接着我们那个双倍行距的例子讲，如果你希望一个网页中的头两个段落为双倍行距且突出显示，你可以向它们添加类，如下所示：</p>
    <pre><code>&lt;p class=&quot;highlight&quot;&gt;Paragraph content&lt;/p&gt;<br />&lt;p class=&quot;highlight&quot;&gt;The content of the second paragraph&lt;/p&gt;</code></pre>
    <p>然后对它们应用一种CSS规则，如下所示：</p>
    <pre><code>.highlight {<br />  line-height: 2;<br />  color: green;<br />}</code></pre>
    <p>在以上例子中，<code>highlight</code> 是一个类，而不是一个 ID（.是CSS惯例中用于指明&ldquo;类&rdquo;的符号）。</p>
    </li>
</ol>
<p>以下的那个示范网页，将让你了解更多关于CSS如何样式化HTML的知识。我们将在即将发布的第22篇文章中更详细地讲述CSS。</p>
<h2 id="javascript">使用JavaScript向网页中添加行为</h2>
<p>最后再来看JavaScript，它是一种用于向网页中添加行为的脚本语言，可以用于检验你输入某一个表单里的数据的有效性（告诉你其格式正确与 否），提供拖放功能，改变漂浮广告的样式，使页面元素如菜单等动起来，处理按钮功能等等。最新的JavaScript是这样工作的：找到一个目标HTML 元素，然后对该元素进行一些处理。这和应用CSS差不多，不过两者的运行方式、语法等，则有相当大的差别。</p>
<p>JavaScript是比HTML和CSS更为复杂和庞大的主题，在目前这个学习阶段，我们还是尽量不去学习太复杂高深的主题，因此在以下这个示范网页中，我们不讨论JavaScript。实际上你们要在本课程的后期阶段才会学习JavaScript。</p>
<h2 id="example">一个示范网页</h2>
<p>在本篇文章中，有很多细节知识我并未讲述，不过请放心，在这个网页设计教程中，我们以后会一一讲述这些知识的。现在我将给你们看一个真实的示范网页，以让你们大致了解在以后的课程中将要学到一些什么知识，增加学习兴趣。</p>
<p>以下这个网页是一个参考网页，你们可以把它用作在你们撰写的文章（如一篇关于Web开发团队的团体动力学的论文，或是一篇关于美国人使用宽带互联网 情况的报告）末尾罗列参考文献的参考。请注意一点，如果你是一个严守学术写作的标准的人，我会告诉你这个示例使用的是APA（美国心理学协会）的文献引用 标准。点击这里，<a target="_blank" href="http://dev.opera.com/articles/view/4-the-web-standards-model-html-css-a/article4_examples.zip">下载代码</a>。</p>
<h3 id="index">index.html</h3>
<pre><code>&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;<br />  &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;<br /><br />&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;<br />&lt;head&gt;<br />  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;  /&gt;<br /><br />  &lt;title&gt;References&lt;/title&gt;<br />  &lt;style type=&quot;text/css&quot;&gt;<br /><br />    @import url(&quot;styles.css&quot;);<br />  &lt;/style&gt;<br />&lt;/head&gt;<br /><br />&lt;body&gt;<br />  &lt;div id=&quot;bggraphic&quot;&gt;&lt;/div&gt;<br />  &lt;div id=&quot;header&quot;&gt;<br />    &lt;h1&gt;References&lt;/h1&gt;<br /><br />  &lt;/div&gt;<br />  &lt;div id=&quot;references&quot;&gt;<br />    &lt;cite class=&quot;article&quot;&gt;Adams, J. R. (2008). The Benefits of Valid Markup: A Post-Modernistic Approach to Developing Web Sites. &lt;em&gt;The Journal of Awesome Web Standards, 15:7,&lt;/em&gt; 57-62.&lt;/cite&gt;<br />    &lt;cite class=&quot;book&quot;&gt;Baker, S. (2006). &lt;em&gt;Validate Your Pages.... or Else!.&lt;/em&gt; Detroit, MI: Are you out of your mind publishers.&lt;/cite&gt;<br /><br />    &lt;cite class=&quot;article&quot;&gt;Lane, J. C. (2007). Dude, HTML 4, that's like so 2000. &lt;em&gt;The Journal that Publishes Genius, 1:2, &lt;/em&gt; 12-34.&lt;/cite&gt;<br />    &lt;cite class=&quot;website&quot;&gt;Smith, J. Q. (2005). &lt;em&gt;Web Standards and You.&lt;/em&gt; Retrieved May 3, 2007 from <a href="http://www.webstandardsandyou.com/">Web standards and you</a>.&lt;/cite&gt;<br /><br />  &lt;/div&gt;<br />  &lt;div id=&quot;footer&quot;&gt;<br />    &lt;p&gt;The content of this page is copyright &copy; 2007 &lt;a href=&quot;mailto:jonathanlane@gmail.com&quot;&gt;J. Lane&lt;/a&gt;&lt;/p&gt;<br />  &lt;/div&gt;<br /><br />&lt;/body&gt;<br />&lt;/html&gt;</code></pre>
<p>我将不会逐行剖析这个文件，以后课程中的很多示例也会这样处理的。不过要点我还是会给你们指出来的，以下就是一些要点：</p>
<p>第1行，是所谓文档类型声明，或简称为doctype。在本示例中，这个网页的文档类型是XHTML 1.0 Transitional。文档类型规定你所写的标记必须遵循的一套规则，并可进行校验。关于文档类型的更多信息，见<a target="_blank" title="article 14 covers doctypes" href="http://kb.operachina.com/node/29">第14篇文章</a>。</p>
<p>第5－7行，将一个CSS文件导入这个网页，也就是说，该CSS文件中包含的CSS将应用于该网页中的各个元素。在下一节，你们可以看到对该网页进行格式设定的CSS文件的内容。</p>
<p>我已为每一种类型的参考文献指定了不同的&ldquo;类&rdquo;，这样我就可以对每一种类型的参考文献应用一种样式，例如，在每一个参考文献的右边我都添加上了不同的颜色，以便于浏览该参考文献列表。</p>
<p>现在来看看样式化HTML的CSS。</p>
<h3 id="styles">styles.css</h3>
<pre><code>body {<br />  background: #fff url('images/gradbg.jpg') top left repeat-x;<br />  color: #000;<br />  margin: 0;<br />  padding:0;<br />  border: 0;<br />  font-family: Verdana, Arial, sans-serif; font-size: 1em;<br />}<br /><br />div {<br />  width: 800px;<br />  margin: 0 auto;<br />}<br /><br />#bggraphic {<br />  background: url('images/pen.png') top left no-repeat;<br />  height: 278px;<br />  width: 362px;<br />  position: absolute;<br />  left: 50%;<br />  z-index: 100;<br />}<br /><br />h1 {<br />  text-align: center;<br />  text-transform: uppercase;<br />  font-size: 1.5em;<br />  margin-bottom: 30px;<br />  background: url('images/headbg.png') top left repeat;<br />  padding: 10px 0;<br />}<br /><br />#references cite {<br />  margin: 1em 0 0 3em;<br />  text-indent: -3em;<br />  display: block;<br />  font-style: normal;<br />  padding-right: 3px;<br />}<br /><br />.website {<br />  border-right: 5px solid blue;<br />}<br /><br />.book {<br />  border-right: 5px solid red;<br />}<br /><br />.article {<br />  border-right: 5px solid green;<br />}<br /><br />#footer {<br />  font-size: 0.5em;<br />  border-top: 1px solid #000;<br />  margin-top: 20px;<br />}<br /><br />#footer a {<br />  color: #000;<br />  text-decoration: none;<br />}<br /><br />#footer a:hover{<br />  text-decoration: underline;<br />}</code></pre>
<p>在设置这个网页的样式时，我略微有点渲染过度，比如添加了一些嵌套背景效果，以向你们展示使用CSS可以达到的一些效果。</p>
<p>第1行为文档设定一些默认样式，如文本和背景颜色、文本周围加入的边框的宽度等。有些人不愿花时间去设定这些默认样式。确实即使你不设定默认样式， 现在多数浏览器都将应用它们自己的默认样式，但自己设定一些默认样式是一个好的习惯，因为这样做可以让你更好地控制你的Web站点在不同的浏览器中如何被 显示。</p>
<p>在下一行中，我把网页设定为800px（像素）宽（尽管我也可以在此规定一个页面根据浏览器窗口的大小而扩大/缩小的百分比）。我在此处使用这种边距（margin）设置，是为了确保页面内容在窗口的中心显示。</p>
<p>下面让我们转向看这个网页的背景图像（通过使用background: url 这一背景声明而实现的）。我在这个网页上添加了3个背景元素：第1个是横跨页面顶部的斜面，呈现出好看的青色；第2，我使用了一个半透明的钢笔PNG图 像，以和它之上的文本形成足够的对比，并将斜面衬托得更好看一些（半透明的PNG图像在Internet Explorer 6或更低的版本中无法正常显示，但在每一种最新式的浏览器中都能很好地显示，关于如何解决IE6无法正常显示半透明PNG图像这一问题，见 <a target="_blank" href="http://code.google.com/p/ie7-js/">Dean Edward's IE-fixing JavaScript</a> （Dean Edward的文章，《用于修补IE的JavaScript》），该文章还讨论了如何处理IE6在CSS支持方面存在的问题。第3，使用了另一个半透明的PNG图像作为页面标题的背景，它增强了标题部分的对比度，并产生一种嵌套的效果。</p>
<p>示范网页的显示效果如图2所示。</p>
<p><img alt="The finished example" src="http://kb.operachina.com/files/article4_2.jpg" /></p>
<p class="article_comment">图2：应用样式后示范网页的显示效果</p>
<h2 id="summary">总结</h2>
<p>XHTML, CSS和JavaScript并不神秘，它们都是Web演进的自然产物。如果你已具有一些HTML方面的知识，完全不用丢弃。你所具有的所有HTML知识，依然很有用，你所需要做的只是以与过去不同的方式来处理一些事情，并在写标记时更仔细一些而已。</p>
<p>使用Web标准进行Web开发，除可以让你把Web开发工作做得更好以外，本身也是很有意义的。一些人不愿意使用Web标准进行Web开发，其理由 是：这样做很耗时，而且必须费很大力气进行能跨浏览器显示的页面布局。对此我们可以提出这样的反驳：使用非基于Web标准的方法进行页面布局，就能让网页 能跨设备并在未来更高版本的浏览器中正常显示吗？你怎么就能肯定你所写的非基于Web标准的标记，可以在Opera 12.0, Firefox 5.0和 IE 10.0上都能显示？除非你遵循一些规则，否则是不可能做到的。</p>
<h2 id="exercises">练习题</h2>
<ul>
    <li>类和ID的差别是什么?</li>
    <li>XHTML, CSS 和JavaScript，在Web站点中所起的作用分别是什么？</li>
    <li>以示范网页的index.html文件为素材，单独使用CSS改变页面的格式设定(我建议使用文本编辑器如Notepa或Text Wrangler编辑文件的代码)。不要对HTML进行任何更改。
    <ul>
        <li>为不同类型的参考文献添加图标（即为文章、书籍和互联网资源添加不同的图标）。先创作图标，然后单独使用CSS，使图标显示在不同类型的参考文献旁边。</li>
        <li>隐藏页面底部的版权信息。</li>
        <li>改变标题的外观，使之更醒目。</li>
    </ul>
    </li>
    <li>为使示范网页能在手机浏览器上正常显示，你能做些什么工作？</li>
</ul>
<ul style="list-style-type: none;">
    <li><a href="http://www.w3cgroup.com/article.asp?id=269">上一篇：互联网是如何运转的？</a></li>
    <li><a href="http://www.w3cgroup.com/article.asp?id=271">下一篇：信息架构&mdash;&mdash;规划一个Web站点</a><a href="http://kb.operachina.com/wsc/#toc"><br />
    </a></li>
</ul>
<h2>作者简介</h2>
<p><img style="float: right; margin-left: 10px;" src="http://kb.operachina.com/files/Jonlane.jpg" alt="Picture of the article author Jonathan Lane" /></p>
<p>Jonathan Lane 是 Industry Interactive（工业互动）公司的总裁，该公司是一家从事Web开发及Web应用程序开发的公司，位于加拿大不列颠哥伦比亚省梅恩岛。他曾在Lethbridge大学的课程再开发中心工作过多年，担任该中心Web项目的协调人。</p>
<p>他的博客地址为：<a target="_blank" href="http://www.flyingtroll.com/">http://www.flyingtroll.com/</a> 。目前他正在开发 Mailmanagr 软件&mdash;Basecamp 项目管理应用程序的一个 e-mail 界面。</p>
<p id="license">本文采用的授权是<a target="_blank" rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/">创作共用的&ldquo;署名-非商业性使用-相同方式共享 2.5 通用许可&rdquo;</a>。</p>
</div>
</div>
<p>&nbsp;</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=269</link>
			<title><![CDATA[互联网是如何运转的？]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Fri,23 Oct 2009 15:10:49 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=269</guid>
		<description><![CDATA[<div class="content">
<div id="wsc">
<p>作者：<a target="_blank" href="http://dev.opera.com/author/1072078">Jonathan Lane</a> &middot; 2008年7月8日</p>
<ul style="list-style-type: none;">
    <li><a href="http://www.w3cgroup.com/article.asp?id=268">上一篇：互联网和Web的历史，以及Web标准的演化</a></li>
    <li><a href="http://www.w3cgroup.com/article.asp?id=270">下一篇：Web 标准所包括的模块&mdash;&mdash;HTML、CSS 和 JavaScript</a><a href="http://kb.operachina.com/wsc/#toc"><br />
    </a></li>
</ul>
<h2>序言</h2>
<p>偶尔你们会有机会了解一件事情的来龙去脉和其中的内幕，今天你就很幸运，因为我将带你领略当今最热门，同时也可能是你已经熟悉了的技术：万维网。</p>
<p>本篇文章讲述万维网的基本技术，包括：</p>
<ul>
    <li>超文本标记语言（HTML）</li>
    <li>超文本传输协议（HTTP）</li>
    <li>域名解析系统（DNS）</li>
    <li>Web服务器和Web浏览器</li>
    <li>静态和动态内容</li>
</ul>
<p>以上这些内容都是一些最基本的知识，尽管它们对你构建一个更好的Web站点没有太大帮助，但却有助于你使用专业的语言向客户和其他人讲述Web。正 如电影《音乐之声》里那个睿智的保姆所说的：&ldquo;当我们学习阅读时，从ABC开始；而当学习唱歌时，从Do Re Mi开始&rdquo;。在本篇文章中，我将讲述计算机是如何使用HTTP和TCP/IP协议在互联网上通信的，然后再讲述创建网页需要的各种不同语言。本章的内容如 下：</p>
<ul>
    <li><a href="http://www.v-ec.com/dh20156/#internetcommunication">计算机如何通过互联网通信？</a>
    <ul>
        <li><a href="http://www.v-ec.com/dh20156/#requestresponse">剖析请求/响应周期</a></li>
    </ul>
    </li>
    <li><a href="http://www.v-ec.com/dh20156/#contenttypes">内容的类型</a>
    <ul>
        <li><a href="http://www.v-ec.com/dh20156/#plaintext">纯文本</a></li>
        <li><a href="http://www.v-ec.com/dh20156/#webstandards">Web标准</a></li>
        <li><a href="http://www.v-ec.com/dh20156/#dynamicpages">动态网页</a></li>
        <li><a href="http://www.v-ec.com/dh20156/#proprietaryformats">需要其它程序或插件的格式 </a></li>
    </ul>
    </li>
    <li><a href="http://www.v-ec.com/dh20156/#staticdynamic">静态网站与动态网站的比较</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#summary">总结</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#exercises">练习题</a></li>
</ul>
<h2 id="internetcommunication">计算机如何通过互联网通信？</h2>
<p>值得庆幸的是，我们使计算机易于使用。在万维网上，绝大多数网页都是使用同一种语言，即HTML（超文本标记语言）编写的，并且使用一种通用的协 议，即HTTP（超文本传输协议）进行传输的。HTTP是常用的互联网规范，它允许一台Window计算机和正在运行着最新版本Linux操作系统的计算 机实现无障碍的通信。通过使用Web浏览器（它是一种解释HTTP，并将HTML渲染为人类可读格式的软件），你就可以在任意地点、任意设备上（包括手 机、PDA、游戏机等），阅读在任意计算机上以HTML创作的网页。</p>
<p>尽管编写网页的语言相同，但接入互联网的各种设备要能和网络相互通信，却需要有一些规则。这和在教室里学习，问问题要举手的规矩一样，HTTP为互联网确立了这些基本规则。由于有了HTTP，一台客户计算机（如你的计算机）就知道，它就是那台向<strong>服务器</strong>发出某个网页访问请求的计算机。服务器就是存放Web站点的计算机。当你在浏览器中键入一个网址，服务器就会收到你的请求，找到你想访问的网页，然后将该网页发回到你的计算机，这时网页就会在你的浏览器上显示出来了。</p>
<h3 id="requestresponse">剖析请求/响应周期</h3>
<p>以上我已讲述了使计算机能在互联网上通信所需的几个部分，现在我再详细谈谈HTTP的请求/响应周期。为能更有效地掌握一些重要的概念，请遵照以下步骤动手操作一下。</p>
<ol>
    <li>
    <p>每一次请求/响应，都从在Web浏览器的地址栏上键入统一资源定位符（URL）开始，比如 http://dev.opera.com。请打开浏览器，键入一个URL。</p>
    <p>也许你们还不知道，Web浏览器实际上并不是使用URL向服务器请求Web站点的，而是使用<strong>互联网协议</strong>或称<strong>IP地址</strong>（它们和电话号码或邮政编码相似，是用来识别服务器的）。举例来说，http://dev.opera.com这个站点的IP地址就是213.236.208.98。</p>
    </li>
    <li>
    <p>请打开一个新的浏览器标签页或窗口，键入 http://www.apple.com，然后按回车键；然后再键入 http://17.149.160.10/ 并按回车键，你会发现到的是同一个Web站点。试着在地址栏键入 http://213.236.208.98 并按回车键，这其实也是指向一个服务器地址，但你的浏览器上会显示&ldquo;禁止访问&rdquo;错误信息（错误403），这是因为你未被允许访问这个服务器的真实根目录。</p>
    <p>http://www.apple.com 基本上等于是 http://17.149.160.10/ 的别名，但为什么要使用这个别名呢？这是因为人们更容易记住文字，而不是一长串数字。将字母组成的域名解析为数字表示的IP地址，是通过域名解析系统（DNS）实现的。DNS实际上是所有连接到互联网上计算机的自动目录。当你在浏览器的地址栏键入 http://dev.opera.com 并按回车键后，该网址就被发送到一个域名服务器上，由这个服务器去找到相对应的IP地址。由于连接到互联网的计算机数量非常庞大，不是每一台DNS服务器都有一个所有在线机器的列表，因此就有这样一个系统，确保你的请求可以发往正确的服务器，以完成你的请求。</p>
    <p>因此DNS系统就查找 www.opera.com 站点，找到所请求页面的IP地址17.149.160.10，然后把这个IP地址发送回你的Web浏览器。</p>
    <p>你的计算机向位于指定IP地址的计算机发出请求，等待得到响应。如果一切顺利的话，服务器会向客户端发出一条消息说&ldquo;一切都正常&rdquo;（见图1），然后将网页发送到客户端。这类消息被包含在<strong>HTTP 报头</strong>中。</p>
    <p><img src="http://kb.operachina.com/files/article3_1.gif" alt="successful request response cycle" /></p>
    <p class="article_comment">图一: 在这种情况下，一切都正常，服务器传输回正确的网页。</p>
    <p>如果出现了问题，例如你键入的URL不正确，则会传输回<strong>HTTP 错误</strong>信息，并显示在你的浏览器上，错误404&ldquo;网页未找到&rdquo;，就是你可能遇到的常见错误信息。</p>
    </li>
    <li>
    <p>试着键入 http://dev.opera.com/joniscool.html，这个网页不存在，因此你的浏览器上就会显示服务器传输回的错误404信息。试 试再键入几个不同的Web站点上不存在的网页的网址， 你会发现传输回来的404错误页面各有不同。这是因为一些Web开发员只是让Web服务器传输回默认的错误页面，而另一些Web开发员则编写了自定义的错 误页面。这是一项高级技术，未包含在本课程的范围内，不过我们希望在即将发布的一篇文章中包含这一内容。</p>
    <p>最后，说一下有关URL的事情，通常你键入的指向某个站点的第一个URL，在其末尾是没有真正的文件名的（如 http://www.mysite.com/），随后你访问的页面，在其URL的末尾有些有文件名，有些则没有。其实你访问的都是真正的文件，只是有时 Web开发员会通过在Web服务器上的设置，让服务器不在URL中显示文件名，这样做通常可以让人们更容易记住URL，使访问站点的用户获得更好的体验。 这是一项高级技术，也未包含在本课程的范围内。我们将在后面的文章中，讲述向服务器上载文件以及文件/文件夹目录结构的内容。</p>
    </li>
</ol>
<h2 id="contenttypes">内容的类型</h2>
<p>以上我已为大家讲述了HTTP请求/响应，现在我将讲述你在互联网上可以看到的不同内容。我把内容划分为四大类：纯文本、Web标准、动态网页，及需要其它程序或插件的格式。</p>
<h3 id="plaintext">纯文本</h3>
<p>在互联网发展的早期阶段，那时还没有任何Web标准或插件，互联网上主要就是图像和纯文本（扩展名为.txt的文件）。当一个纯文本文件被放到互联网上，浏览器只是按原样显示，不进行任何处理。现在大学的站点上，你常常都还能看到纯文本文件。</p>
<h3 id="webstandards">Web标准</h3>
<p>构成万维网的基石就是3个主要的Web标准：HTML（或XHTML&mdash;&mdash;可扩展超文本标记语言，在本文中我将交替使用HTML和XHTML）、CSS、JavaScript。</p>
<p>对于沟通这个用途来说，超文本标记语言是个恰如其分的名字。HTML用于将文档划分为不同的部分，规定文档的内容和结构，并定义每部分的含义（它包含你在网站看到的所有文本等内容），同时，它使用元素来标识页面中的不同部分。</p>
<p>层叠样式表（CSS）使你可以完全控制一个HTML元素如何被显示。CSS很简单，例如，使用样式表声明，可将所有段落改为双倍行距（line- height（行高）: 2em;），或让所有二级标题变为绿色（color: green;）。将页面结构从页面格式中分离出来，会带来非常多的好处，在下一篇文章中我们将详细地讲述。为示范将HTML和CSS结合起来使用所带来的 效果，请看图2，在图2的左边显示的是一些纯HTML，未添加任何格式设定；而右边显示的是应用了一些CSS样式后完全相同的HTML。</p>
<p><img src="http://kb.operachina.com/files/article3_2.gif" alt="successful request response cycle" /></p>
<p class="article_comment">图2： 左边是纯HTML，右边是应用了CSS的HTML。</p>
<p>最后，JavaScript 为你的Web站点提供了动态功能。你可以写一些将在客户计算机上运行的JavaScript小程序，而不用在服务器上安装任何特别的软件。 JavaScript能让你可以向你的Web站点增添一些基本的功能和交互，但它也有局限性，因此我们下面就要谈谈服务器端的编程语言和动态网页。</p>
<h3 id="dynamicpages">动态网页</h3>
<p>有时当你在浏览互联网时，你会看到一些网页的扩展名不是.html ，而可能是.php、.asp、.aspx、.jsp，或其它奇怪的扩展名。它们都是动态网页技术的例子，动态网页技术可用于创建具有动态代码部分的网 页，代码部分将根据从数据库、表格、或其它数据源之中输入的数值，显示不同的结果。我们将在下面的部分比较一下静态网页和动态网页。</p>
<h3 id="proprietaryformats">需要其它程序或插件的格式</h3>
<p>由于Web浏览器只设计用来解析和显示一些特定的技术，如Web标准等，因此如果你请求的地址指向了一个复杂的文件格式，或是包含了某个需要特定插件的网页，那么插件会被要求下载到你的计算机。而如果你的浏览器已安装了该插件，那么此网页会被所需插件所支持并打开。例如：</p>
<ol>
    <li>
    <p>如果你遇到Word文档、Excel文件、PDF、压缩文件（例如ZIP或SIT 文件）、复杂的图像文件（如Photoshop PSD），或浏览器不认识的其它复杂文件，浏览器通常会问你是否想下载或是打开文件。 这两种方式效果其实是一样的，只是后一种方式，将使浏览器先下载该文件，然后由可以打开该文件的应用程序（如果已安装了的话）打开文件。</p>
    </li>
    <li>
    <p>如果你遇到的页面含有Flash 电影、MP3或其它格式的音频文件、MPEG或其它格式的视频文件，浏览器将用已安装的插件来播放它们。如果所需的插件并未安装，则浏览器要么显示一个用于安装所需插件的链接，要么将文件下载下来，再通过桌面应用程序来打开文件。</p>
    </li>
</ol>
<p>当然，这里也存有一些灰色地带，如SVG（可伸缩矢量图）是一个Web标准，可以在一些浏览器中直接打开，如Opera浏览器。但不能在另外一些浏 览器（如Internet Explorer）中直接打开，因为IE需要一个插件来解析SVG。许多的浏览器都将匹配预装插件，因此你也许不会注意到哪些内容是通过插件显示的，而哪 些内容是通过浏览器直接被显示的。</p>
<h2 id="staticdynamic">静态网站与动态网站的比较</h2>
<p>什么是静态网站和动态网站，二者之间有什么差别？与一盒巧克力相似，东西都在里面。</p>
<p>静态Web站点是指这样一种网站，其中的内容、HTML和图形始终都是静态的，任何访问者看到的都是一样的页面，除非创建网站的人决定手动更改存在服务器上的网站副本。我们在本文中讲述的主要是这类静态Web站点。</p>
<p>而在一个动态Web站点上，在服务器上的内容是一样的，但除了包含有HTML外，网站还包含有动态代码，可以显示不同的数据，取决于你向网站输入的信息。让我们看一个例子吧，通过你的Web浏览器访问www.amazon.com，搜索5种不同的产品。亚马逊网站实际上并未将5个不同的网页发送给你，而是将一个相同的网页发送给你了5次，但每次发送给你的网页都带有加入的动态信息。这些不同的信息储存在一个数据库中，在请求时提取相关信息并发送给Web服务器，以插入动态网页。</p>
<p>需要注意的另一件事情是，为创建动态Web站点，必须在服务器上安装特别的软件。一方面普通的静态HTML文件将以.html这一扩展名保存；而那 些除了包含HTML内容，还包含有特别动态代码的文件，将以特殊的扩展名进行保存（如PHP文件通常就具有.php这一文件扩展名）。通过这些特殊的扩展 名，Web服务器得知，它们在被发送到客户端之前，需要进行额外的处理（例如从数据库中插入数据等）。</p>
<p>现在有很多动态编程语言可供选择，比如我上面提到的PHP，另外比如Python、Ruby on Rails、 ASP.NET、Coldfusion等。实际上所有这些动态编程语言基本上都具有相同的能力，例如与数据库对话、校验输入表格的信息等，不过它们还是有 轻微的差异，有各自的优点和缺点。要问哪种最好，还要哪个最适合你。</p>
<p>在本课程中，我们将不再进一步讲述动态编程语言，不过如果你希望深入了解动态编程语言，我在下面列出了一些可对你有帮助的资源：</p>
<ul>
    <li>Rails: Fernandez, Obie. (2007), The Rails Way. Addison-Wesley Professional Ruby Series.</li>
    <li><a target="_blank" href="http://www.rubyonrails.org/screencasts">Rails screencasts</a></li>
    <li>PHP: Powers, David (2006), PHP Solutions: Dynamic web development made easy, friends of ED.</li>
    <li><a target="_blank" href="http://www.php.net/docs.php">PHP Online documentation</a></li>
    <li>ASP.NET: Lorenz, Patrick. (2003). ASP.NET 2.0 Revealed. Apress.</li>
    <li>ASP.NET: <a target="_blank" href="http://asp.net/">online ASP.NET documentation and tutorials.</a></li>
</ul>
<h2 id="summary">总结</h2>
<p>在本篇文章中，我向大家讲述了互联网是如何工作的。虽然它只是就本课程包含的很多主题泛泛地讲述了一番，但还有很有用的，因为通过将所有这些主题大 致梳理一遍，可以看到它们之间是如何联系在一起的，又是如何共同工作的。关于HTML、CSS 和JavaScript，还有很多实际的语法要学习。在下一篇文章中，我们将重点讲述用于Web开发的&ldquo;Web标准&rdquo;所包括的几部分，即HTML、CSS 和JavaScript，并讲述一下网页代码。</p>
<h2 id="exercises">练习题</h2>
<ul>
    <li>给出HTML和HTTP的简明定义，并说明二者之间的差别。</li>
    <li>说明Web浏览器的功能。</li>
    <li>花5－10分钟上网，试着找出一些不同类型的内容，如纯文本、图像、HTML、动态网页（如PHP 和 .Net网页--.aspx）、PDF、Word文件、Flash电影等。访问其中一些内容，并思考你的计算机是如何显示这些内容的。</li>
    <li>静态网页和动态网页的差别是什么？</li>
    <li>找一个HTTP错误代码列表，列出其中5种，并解释每个错误代码的意思。</li>
</ul>
<ul style="list-style-type: none;">
    <li><a href="http://www.w3cgroup.com/article.asp?id=268">上一篇：互联网和Web的历史，以及Web标准的演化</a></li>
    <li><a href="http://www.w3cgroup.com/article.asp?id=270">下一篇：Web 标准所包括的模块&mdash;&mdash;HTML、CSS 和 JavaScript</a><a href="http://kb.operachina.com/wsc/#toc"><br />
    </a></li>
</ul>
<h2>作者简介</h2>
<p><img style="float: right; margin-left: 10px;" src="http://kb.operachina.com/files/Jonlane.jpg" alt="Picture of the article author Jonathan Lane" /></p>
<p>Jonathan Lane 是 Industry Interactive（工业互动）公司的总裁，该公司是一家从事Web开发及Web应用程序开发的公司，位于加拿大不列颠哥伦比亚省梅恩岛。他曾在Lethbridge大学的课程再开发中心工作过多年，担任该中心Web项目的协调人。</p>
<p>他的博客地址为：<a target="_blank" href="http://www.flyingtroll.com/">http://www.flyingtroll.com/</a> 。目前他正在开发 <a target="_blank" href="http://www.mailmanagr.com/">Mailmanagr</a> 软件&mdash;Basecamp 项目管理应用程序的一个 e-mail 界面。</p>
<p id="license">本文采用的授权是<a target="_blank" rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/">创作共用的&ldquo;署名-非商业性使用-相同方式共享 2.5 通用许可&rdquo;</a>。</p>
</div>
</div>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=268</link>
			<title><![CDATA[互联网和Web的历史，以及Web标准的演化]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Thu,22 Oct 2009 15:21:03 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=268</guid>
		<description><![CDATA[<div id="node-17" class="node node-book">
<div class="info">
<p>Posted <abbr class="created" title="2008-12-10T12:37:25+0800">12/10/2008 - 12:37</abbr> by Lewis</p>
<div class="btn-tags">
<ul class="links inline">
    <li class="taxonomy_term_33 first last"><a href="http://kb.operachina.com/taxonomy/term/33" rel="tag" title="">网络标准教程</a></li>
</ul>
</div>
</div>
<div class="content">
<div id="wsc">
<p>作者：<a href="http://dev.opera.com/author/1477930">mnfrancis</a> &middot; 2008年7月8日<a href="http://kb.operachina.com/?q=node/14"><br />
</a></p>
<ul style="list-style-type: none;">
    <li><a href="http://www.w3cgroup.com/article.asp?id=269">下一篇：互联网是如何工作的？</a><a href="http://kb.operachina.com/wsc/#toc"><br />
    </a></li>
</ul>
<h2>序言</h2>
<blockquote>
<p>&ldquo;请问陛下，我们该从哪里出发呢？&rdquo;</p>
<p>&ldquo;从起点出发&rdquo;，国王严肃地回答说：&ldquo;一直前行，直到终点再停下。&rdquo;</p>
<p><em>&mdash;刘易斯&bull;卡罗尔《爱丽丝漫游奇境》</em></p>
</blockquote>
<p>我们做任何事都有一个起点，我们这个课程就从回顾历史开始吧。在以下部分，我将简要回顾互联网、万维网（World Wide Web），以及Web标准（我们课程的主题）的历史和演化过程。我认为了解互联网和Web标准的演化是很有用的，也很有趣。我的介绍很简要，不是长篇大 论，可帮助你快速入门。如果我提到的任何术语你还不熟悉的话，请不用担心。如果这些术语是学习Web开发过程中很重要的术语，则会在后面的专题文章中给出 定义的，此外你也可用Google查询它们的含义。如果你已经很熟悉互联网和万维网的历史，可以直接跳到<a href="http://www.v-ec.com/dh20156/#comingofstandards">Web标准</a>的部分。本篇文章的内容目录如下：</p>
<ul>
    <li><a href="http://www.v-ec.com/dh20156/#internetorigins">互联网的起源</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#webcreation">万维网的诞生</a>
    <ul>
        <li><a href="http://www.v-ec.com/dh20156/#browserwars">浏览器之争</a></li>
    </ul>
    </li>
    <li><a href="http://www.v-ec.com/dh20156/#comingofstandards">Web标准的诞生</a>
    <ul>
        <li><a href="http://www.v-ec.com/dh20156/#w3cformation">W3C（万维网联盟）的成立</a></li>
        <li><a href="http://www.v-ec.com/dh20156/#webstandardsproject">Web标准组织</a></li>
        <li><a href="http://www.v-ec.com/dh20156/#riseofstandards">Web标准的兴起</a></li>
    </ul>
    </li>
    <li><a href="http://www.v-ec.com/dh20156/#summary">总结</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#furtherreading">延伸阅读</a></li>
    <li><a href="http://www.v-ec.com/dh20156/#exercisequestions">练习题</a></li>
</ul>
<h2 id="internetorigins">互联网的起源</h2>
<p>1957年10月4日，一个改变世界的事件发生了，那就是苏联成功地将第一颗人造卫星（名为Sputnik 1号）送入了地球轨道。这件事震惊了世界，尤其是让美国感到十分震惊，因为美国也正在进行发射人造卫星的计划，但尚未完成。</p>
<p>受到苏联首先成功发射人造卫星的刺激，美国政府认为有必要成立一个研究和开发新的尖端科技的机构，于是就成立了国防部高级研究计划局（ARPA）。迄今为止，国防部高级研究计划局最有名的（无疑是得到最广泛应用的）研究计划也许就是建立互联网了。</p>
<p>1960年，心理学家和计算机科学家Joseph Licklider发表了一篇名为《人机共生》的论文，在这篇论文中首次提出将计算机联网，以用于信息的储存和检索的构想。1962年，时任国防部高级研 究计划局信息处理办公室负责人的Joseph Licklider，建立了一个推进计算机研究的小组，中心工作就是围绕他1960年提出的将计算机联网的构想开展研究。</p>
<p>1967年10月，研究小组提出了构建这样一个计算机网络，被称为&ldquo;阿帕网&rdquo;（ARPANET）的计划，随后在1969年12月，首个连接四个节点 的计算机网络建立并投入运行。建立一个计算机网络面临的关键问题是如何将分散的计算机系统连接起来，又不因不间断连接而耗尽网络资源。为解除这一问题，发 明出了一种叫做&ldquo;分组交换（包交换）&rdquo;的技术，即把数据请求拆分为小的&ldquo;信息包&rdquo;，这些信息包可以得到快速地处理，且不阻塞与其他方的通信，目前的互联网 依然在使用这一技术原理。</p>
<p>分组交换技术自问世后得到了广泛的应用，一些在阿帕网之后新构建的网络都采用了分组交换技术。例如，英国第一个大学间的网络 <abbr title="Joint Academic Network">JANET</abbr>， 及美国的公共网络CompuServe，都是建立在X.25分组交换技术之上，此技术由国际电信联盟开发。前者使英国的大学之间可以收发文档和电子邮件， 而后者做为一家商业机构，允许小公司和个人访问分时共享的计算机资源，并且后来被接入互联网。这些网络尽管有很多连接，但实质上都还是专用网络，而不是我 们今天使用的互联网。</p>
<p>当人们试图让所有这些分散的网络都能相互通信时，存在多种不同的网络协议就成为了一个问题。不过问题的解决方案很快就找到了，Robert Kahn在从事国防部高级研究计划局的一个卫星分组网络研究项目时，开始为更开放的网络架构定义一些规则，以取代阿帕网当时使用的网络协议。随后斯坦福大 学的Vinton Cerf加入了他的研究项目。他们两人创建了一个使用新的标准弥合不同网络协议间的差异的新系统。在1974年12月发表的草拟规范中，他们两人将这称为 &ldquo;互联网传输控制程序&rdquo;。</p>
<p>这个传输控制规范降低了网络所起的作用，而把维持传输完整性的职责交给了主机，其最终结果就是使将几乎所有网络都连接起来这一工作成为可能。国防部 高级研究计划局资助了相关软件的开发，然后在1977年，成功进行了三种不同的网络通信的演示。到1981年，传输控制规范最终确定和发布，并得到采用。 1982年，在美国以外的阿帕网连接都被转变使用新的 <abbr title="Transmission Control Protocol over Internet Protocol">TCP/IP</abbr> 协议，互联网诞生了。</p>
<h2 id="webcreation">万维网的诞生</h2>
<p><a href="http://en.wikipedia.org/wiki/Gopher_%28protocol%29">Gopher</a> 是20世纪90年代初期常用的信息检索系统，它提供了一种向文件、计算机资源和其他菜单添加链接菜单的方法。这些菜单可越过本机的界限，并使用互联网从其他计算机系统抓取菜单。Gopher深受那些希望共享全校信息的大学和希望集中储存和管理文件的大型组织的欢迎。</p>
<p>Gopher是由明尼苏达大学首创的。1993年2月，明尼苏达大学宣布将针对使用Gopher服务器收取许可费，这样很多组织就开始寻找替代Gopher的系统。</p>
<p>设在瑞士的欧洲核研究理事会（CERN）就有这样一个替代系统。该组织的Tim Berners-Lee 当时正在开发一个信息管理系统，在该系统中，文本可包含指向其他文件的链接，这样读者就可以在文档间快速跳转。他创建了一个发布这种被称为&ldquo;超文本&rdquo;格式 文档的服务器，以及阅读这些超文本文档的程序，他称它们为&ldquo;万维网&rdquo;（WorldWideWeb）。这个软件于1991年首次发布，不过在经历了两个事件 之后，它才得到极其广泛的普及，并最终取代了Gopher。</p>
<p>1993年4月13日，欧洲核研究理事会公开了万维网的源代码，这样任何人都可以使用或改进这个软件，且不需要付费。</p>
<p>同一年的晚些时候，超级计算机应用国家中心（NCSA）发布了一个集成Web浏览器和Gopher客户端的程序，被称为Mosaic 。最初这个程序只能在Unix机器上以源代码的方式获得，不过到了1993年的12月，Mosaic发布了可在苹果机和Windows计算机上安装和运行 的新版本。选用Mosaic浏览器的用户激增，同时上网的人也越来越多。</p>
<p>可用的Web浏览器数量戏剧性地增长，很多浏览器都是由大学和公司开发出来的，例如，一家挪威的通信公司&mdash;&mdash;Telenor，就于1994年开发出了第一个版本的Opera浏览器。</p>
<h3 id="browserwars">浏览器之争</h3>
<p>Web的普及带来了商业利益，Marc Andreessen离开了超级计算机应用国家中心，和Jim Clark 一道创立了Mosaic通信公司，后来改名为网景（Netscape）通信公司。他们开发出Netscape Navigator浏览器，并于1994年12月发布了该浏览器的1.0版本。</p>
<p>Spyglass有限公司是NCSA的下属商业部门，它将Mosaic浏览器技术许可给微软使用，Mosaic浏览器技术构成了微软Internet Explorer浏览器的基础。1995年8月，微软发布了Internet Explorer浏览器的1.0版本。</p>
<p>此后微软和网景都不断推出各自浏览器的升级版本，都想在浏览器支持的功能方面赢得竞争优势，以吸引Web开发人员。这被称为&ldquo;浏览器之争&rdquo;。同一时期，Opera浏览器占有的市场份额虽然还很小，但已有一批忠实的用户。同时，Opera公司也在尽力创新和支持Web标准。</p>
<h2 id="comingofstandards">Web标准的诞生</h2>
<p>在浏览器之争中，微软和网景都将重点放在实施新功能上，而不是放在解决他们各自的浏览器已经支持的功能所出现的问题上。他们还着重于向各自的浏览器增添专有功能，并创建与其他浏览器已有的功能相直接竞争，但不具有兼容性的功能。</p>
<p>面临这种浏览器之争造成的混乱，Web开发人员在构建Web站点时，不得不采取一些权宜之计，一些时候是分别针对这两个主流浏览器开发两个版本的 Web站点，而有时干脆就选择只支持一个浏览器，使使用其他浏览器的用户无法正常访问Web站点。这是一种可怕的工作方式，相应地，Web开发人员也开始 寻求解决的办法。</p>
<h3 id="w3cformation">W3C（万维网联盟）的成立</h3>
<p>1994年，在欧洲核研究理事会、国防部高级研究计划局和欧洲委员会的支持下，Tim Berners-Lee在麻省理工学院创立了W3C（万维网联盟）。W3C的目标是：规范用于创建Web站点和Web页的协议和技术，以使Web站点和 Web页的内容能为全球尽可能多的人访问。</p>
<p>此后的数年内，W3C发布了多份规范文件（称为&ldquo;建议&rdquo;），包括HTML 4.0、PNG图像格式、CSS样式表的1.0和2.0版本。</p>
<p>但是W3C并未强制执行其提出的建议，生产厂商只有在希望在产品上标注&ldquo;符合W3C规范&rdquo;的情况下，才必须遵守W3C制定的规范。这不是一个可以吸 引消费者的产品特色，因为几乎所有的互联网用户都不知道，而且可能也不关心W3C是个什么样的组织。浏览器之争继续激烈地进行着。</p>
<h3 id="webstandardsproject">Web标准组织</h3>
<p>1998年，浏览器市场被当时的两大主流浏览器Internet Explorer 4和Netscape Navigator 4所占据。微软发布了Internet Explorer 5的测试版本，该测试版本的Internet Explorer 5执行一种新的、专有的动态HTML，这意味着专业的Web开发人员需要知道5种不同的写JavaScript 的方法。</p>
<p>在这种情况下，一个由专业Web开发人员和设计师组成的团体应运而生，这个团体称自己为Web标准组织(（WaSP），他们的想法是通过呼吁将W3C制定的规范称为标准而不是建议，可能可以说服微软和网景支持他们。</p>
<p>Web标准组织为推广他们的行动呼吁，在早期阶段采用了一种传统的广告技术&mdash;&ldquo;路障策略&rdquo;（roadblock）。所谓&ldquo;路障策略&rdquo;，是指一家公司 在同一时段，在所有的电视频道上都播出一个同样的广告，这样观众无论将电视调到哪一个频道，得到的都是完全相同的广告讯息。借鉴这个策略，Web标准组织 同时在很多Web开发专业站点（包括builder.com），连线杂志网络版（Wired online），以及一些受欢迎的邮件列表上，发布同一篇文章。</p>
<p>Web标准组织使用的另一个宣传技术是嘲笑那些将要加入W3C（及其他标准制定组织）的公司，不过后来就更侧重于创造新特性，而不再侧重于推广那些他们认为一开始就必须使用的基本方法。</p>
<p>Web标准组织的所作所为似乎更偏重于批评，但他们并不只是坐在那里批评人，他们也向人们提供帮助。Web标准组织的7位成员成立了一个&ldquo;CSS武 士团&rdquo;（CSS Samurai），明确指出Opera浏览器和Internet Explorer浏览器在支持CSS方面存在的十大问题（Opera公司解决了这些问题，但微软并未解决）。</p>
<h3 id="riseofstandards">Web标准的兴起</h3>
<p>2000年，微软发布了Internet Explorer 5浏览器的苹果机版本，这是一个非常重要的里程碑事件，Internet Explorer浏览器成为Mac OS操作系统下的默认浏览器，并在一定程度上支持了W3C建议。这一事件，以及Opera浏览器当时已可以很好地支持CSS 和 HTML这一事实，推动了Web标准的使用，Web开发人员和设计师第一次感到使用Web标准设计站点是轻松的工作。</p>
<p>Web标准组织劝说网景公司在其浏览器完全支持Web标准前，不发布Netscape Navigator浏览器的5.0版本（这项工作为当前非常流行的浏览器Firefox的推出奠定了基础）。Web标准组织还创建了一个 &ldquo;Dreamweaver专责小组&rdquo;，促请Macromedia公司改进其流行的网页制作工具Dreamweaver，以鼓励和支持创建符合Web标准的 站点。</p>
<p>很受欢迎的Web开发站点&ldquo;A List Apart&rdquo;，于2001年初进行了重新设计，在一篇文章中他们阐述了为什么要重新设计Web站点：</p>
<blockquote>
<p>&ldquo;在6个月内，或1年内，最多两年内，所有的站点在设计时都将使用这些Web标准。［中间略过&hellip;&hellip;］我们要么不思进取，听任自己落伍，要么现在就开始学习基于Web标准的技术。&rdquo;</p>
</blockquote>
<p>这有些过于乐观了。即使是到了2008年，也不是所有站点都是使用Web标准而构建的。不过发展趋势是可以让人乐观的，旧式浏览器所占的市场份额已 经下降。两个著名的Web站点已使用Web标准对其站点进行了重新设计，它们就是连线杂志网络版（于2002年重新设计），和ESPN电视网的站点（于 2003年重新设计），它们已成为支持Web标准和新技术的先锋。</p>
<p>同样也是在2003年，Dave Shea推出了一个被称作&ldquo;CSS Zen Garden&rdquo;（CSS禅意花园）的站点，这个站点用实际例子证明仅通过改变页面的样式，而内容保持不变，就可以实现整个设计的改变，这对Web专业人士产生了莫大的影响。</p>
<p>从那时起，在专业Web开发圈子里，Web标准就已成为必须遵守的标准。在本课程中，我们将向大家全面介绍Web标准，向大家提供Web设计和Web开发的牢固基础，使你们能开发出符合Web标准的、可访问性好的，且代码精简高效的Web站点，如同大公司的站点一样。</p>
<h2 id="summary">总结</h2>
<p>在这篇文章里，我简述了现代互联网是如何诞生的，即最初它实际上是美苏太空军备竞赛的产物；Tim Berners-Lee 是如何为一代人定义超文本的，以及微软和网景的商业之争，是如何导致Web开发人员群体发起推广Web标准的行动的。&ldquo;Web标准&rdquo;这一术语现在已广泛地 在Web专业人士圈子里使用，连W3C在其站点也开始使用这一术语。我们要向你们教授的正是Web标准，即建立Web站点的标准方式。</p>
<h2 id="furtherreading">延伸阅读</h2>
<p>如果你想了解更多的知识，可以访问以下一些站点：</p>
<ul>
    <li><a href="http://en.wikipedia.org/wiki/History_of_the_Internet">互联网的历史（维基百科wikipedia）</a></li>
    <li><a href="http://en.wikipedia.org/wiki/History_of_the_World_Wide_Web">万维网的历史（维基百科wikipedia）</a></li>
    <li><a href="http://www.w3.org/Consortium/history">W3C的历史</a></li>
    <li><a href="http://webstandards.org/">Web标准组织</a>，及其<a href="http://www.webstandards.org/about/history/">历史</a></li>
    <li><a href="http://www.alistapart.com/">A List Apart站点</a></li>
    <li><a href="http://www.csszengarden.com/">CSS Zen Garden站点</a></li>
</ul>
<h2 id="exercisequestions">练习题</h2>
<ul>
    <li>Windows平台、Mac OS X平台、 Linux平台各自的用户，目前可用的互联网浏览器有哪些？</li>
    <li>每种浏览器的用户比例分别是多少？</li>
    <li>移动设备访问网页使用哪些浏览器？</li>
    <li>W3C已发布了多少个&ldquo;Web标准&rdquo;，其中有哪些目前得到浏览器开发商的广泛支持？<a href="http://kb.operachina.com/?q=node/14"><br />
    </a></li>
</ul>
<ul style="list-style-type: none;">
    <li><a href="http://www.w3cgroup.com/article.asp?id=269">下一篇：互联网是如何工作的？</a><a href="http://kb.operachina.com/wsc/#toc"><br />
    </a></li>
</ul>
<h2>作者简介</h2>
<p><img style="float: right; margin-left: 10px;" src="http://kb.operachina.com/files/norm.jpg" alt="Picture of the article author Mark Norman Francis" /></p>
<p>Mark Norman Francis 早在万维网诞生前，就在从事互联网领域的工作了，一直持续到现在。目前他是全球最大网站Yahoo! 的前端设计师，负责制定Web开发的最佳习惯、代码标准和质量标准。</p>
<p>在加入Yahoo!前，他先后在Formula One Management（F-1管理公司）、Purple Interactive （紫色互动公司）、伦敦城市大学从事过多种工作，包括Web开发、后端CGI编程和系统架构等。他的博客地址为：<a href="http://marknormanfrancis.com/">http://marknormanfrancis.com/</a>。</p>
<p id="license">本文采用的授权是<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/">创作共用的&ldquo;署名-非商业性使用-相同方式共享 2.5 通用许可&rdquo;</a>。</p>
</div>
</div>
</div>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=267</link>
			<title><![CDATA[JavaScript游戏玛丽医生Dr Mario]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Mon,12 Oct 2009 18:00:54 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=267</guid>
		<description><![CDATA[<p>在很久很久以前，我们这些80后的小朋友终于玩上了自己的小霸王游戏机，超级玛丽，玛丽医生，雪人兄弟，诸多经典游戏让人无法忘怀，成为一个心结！</p>
<p>在完成了<a href="http://www.w3cgroup.com/article.asp?id=257" target="_blank">俄罗斯方块</a>后，这是我写的又一个JavaScript游戏，<a href="http://www.w3cgroup.com/article.asp?id=267" target="_blank">玛丽医生Dr.Mario</a>。</p>
<p><a href="http://www.v-ec.com/games/drmario/" target="_blank"><img border="0" src="http://www.w3cgroup.com/attachments/month_0910/p20091012175611.png" alt="javascript dr mario玛丽医生" /></a></p>
<p><a href="http://www.v-ec.com/games/drmario/" target="_blank"><img border="0" src="http://www.w3cgroup.com/attachments/month_0910/x20091012175619.png" alt="javascript dr mario玛丽医生" /></a></p>
<p><strong>游戏方法：</strong></p>
<p>3颗相同颜色的药丸与同色的病毒在横向纵向上相连时，则可杀死该病毒得分。</p>
<p>方向键：上：药丸形状及颜色切换，左、右、下：左移、右移、下落。</p>
<p><strong>实现流程：</strong></p>
<p>药丸落下 -&gt; 边界检测 -&gt; 不可再动 -&gt; 加入到groups -&gt; 杀病毒检测 -&gt; 消除 -&gt; 重新整理groups -&gt; 无支撑的药丸掉落 -&gt; 回到杀毒检测，直到所有无支撑药丸掉落结束 -&gt; 下一个</p>
<p><strong>Groups概念：</strong></p>
<p>在该游戏的实现中， 出现了一个groups的概念，它是一个数组，它记录了所有堆积的元素，这些元素是活动的，会在消除某些元素后掉落，所以，比较麻烦。</p>
<p>groups记录着每次掉落元素的坐标及样式，形如：[[[0,0,'red_left'],[0,1,'blue_right']],......]</p>
<p>在每次消除病毒后，它需要维护一次，维护的过程是，先将其按照每个元素的第1维进行倒序排列（用于保证越靠下的药丸在后面最先掉落），然后遍历每个元素，进行整理，如：某个与元素的一半被消除了，或者两个元素都被消除了，等等。</p>
<p><strong>几个算法：</strong></p>
<p>在该游戏中需要优化的几个算法：</p>
<p>取横向、纵向N个以上连续相同的内容（实现参见：<a href="http://www.jslab.org.cn/?tag=getsamelistfrommartix" target="_blank">http://www.jslab.org.cn/?tag=getsamelistfrommartix</a>）</p>
<p>边界检测（与俄罗斯方块的边界检测算法类似，采用位与的方式）</p>
<p>groups维护（遍历数组）</p>
<p>如果能够优化以上算法，则程序运行效率会更高！</p>
<p>其他操作类似于俄罗斯方块，具体情况，可以去看它的源代码！</p>
<h3><a href="http://www.v-ec.com/games/drmario/" target="_blank">现在就来玩玩看这个JavaScript实现的Dr.Mario玛丽医生吧 ^_^</a></h3>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=266</link>
			<title><![CDATA[基于EasyUI的全站表单AJAX提交验证及返回值提示功能的实现]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Fri,21 Aug 2009 15:53:27 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=266</guid>
		<description><![CDATA[<p>在一个网站建设过程中，对表单的验证、返回信息处理等等常常会占据前端开发人员比较多的时间，有时候甚至会编写出一些总体功能相似的重复代码片段，这不得不让人懊恼。</p>
<h3>前段时间在一个项目中，通过对以往表单提交、验证、返回信息处理等功能的分析总结，编写了一个基于<a href="http://www.easyui.org.cn" target="_blank">EasyUI</a>的全站表单AJAX提交验证及返回值提示功能的通用方法。</h3>
<p>伪代码形如：</p>
<p>formsubmit(dModule){</p>
<p>在一些表单中可能会出现联动选单，我们再编写一个联动选单的通用方法，形如：getUS(dModule)；</p>
<p>在一些表单中可能会出现日历选框，我们再编写一个日历选框的通用方法，形如：calendar(dModule)；</p>
<p>在一些表单中可能会出现颜色选框，我们再编写一个颜色选框的通用方法，形如：colorPicker(dModule)；</p>
<p>定义提交时显示的提示信息；</p>
<p>定义处理结果返回时的显示信息，此信息为模板类型，可定义一些通配符，以便在得到具体返回值时进行替换；</p>
<p>定义弹出层及遮罩；</p>
<p>定义onsubmit事件处理函数，如fooaction(){</p>
<p>调用easyUI.checkForm进行表单验证；</p>
<p>定义提交的URL及提交的ARGS；</p>
<p>定义显示返回值方法，如showmsg(stype,msg)；</p>
<p>定义显示失败值方法；</p>
<p>定义AJAX处理函数；</p>
<p>定义AJAX失败时函数；</p>
<p>调用easyUI.ajax.post方法提交表单</p>
<p>}</p>
<p>绑定表单onsubmit方法</p>
<p>}</p>
<p>之后，在每个页面进行调用：formsubmit(document.body);</p>
<p>（在每个页面进行调用不是让你去每一个页面上这么写一遍，记得用src方式引入JS文件即可 ^_^）</p>
<p>以后的页面编写中，就可以不用再去重复编写不同的表单提交处理函数了。</p>
<p>&nbsp;</p>
<p>附源代码部分：</p>
<p>formsubmit:function(dModule){</p>
<p>&nbsp;&nbsp; &nbsp;if(!dModule){return;}</p>
<p>&nbsp;&nbsp; &nbsp;//联动部分，可根据项目需求自行编写通用方法</p>
<p>&nbsp;&nbsp; &nbsp;sutil.getUS(dModule);</p>
<p>&nbsp;&nbsp; &nbsp;//日历部分，可参照<a target="_blank" href="http://www.easyui.org.cn/EasyCalendar_demo.html">easyCalendar</a>的使用方法</p>
<p>&nbsp;&nbsp; &nbsp;sutil.calendar(dModule);</p>
<p>&nbsp;&nbsp; &nbsp;//取色部分，可参照<a target="_blank" href="http://www.easyui.org.cn/easyColorPicker_demo.html">easyColorPicker</a>的使用方法</p>
<p>&nbsp;&nbsp; &nbsp;sutil.colorPicker(dModule);</p>
<p>&nbsp;&nbsp; &nbsp;//处理提示</p>
<p>&nbsp;&nbsp; &nbsp;var swaiting = '&lt;div class=&quot;waiting&quot;&gt;&lt;img src=&quot;'+vIjcPath+'loading.gif&quot; /&gt; 请稍候，正在处理您的请求......&lt;/div&gt;';</p>
<p>&nbsp;&nbsp; &nbsp;//处理结果模板</p>
<p>&nbsp;&nbsp; &nbsp;var sresult = '&lt;div class=&quot;result&quot;&gt;&lt;div class=&quot;hd&quot;&gt;$1&lt;/div&gt;&lt;div class=&quot;bd&quot;&gt;&lt;div class=&quot;msg&quot;&gt;$2&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;';</p>
<p>&nbsp;&nbsp; &nbsp;//输出设备，遮罩、弹出层</p>
<p>&nbsp;&nbsp; &nbsp;var dmask = sutil.mask;</p>
<p>&nbsp;&nbsp; &nbsp;var dpopup = sutil.formpopup;</p>
<p>&nbsp;&nbsp; &nbsp;dpopup.fixsize = true;</p>
<p>&nbsp;&nbsp; &nbsp;dpopup.autofullsize = false;</p>
<p>&nbsp;&nbsp; &nbsp;dpopup.setShadow();</p>
<p>&nbsp;&nbsp; &nbsp;dpopup.onopen = function(){dmask.open();};</p>
<p>&nbsp;&nbsp; &nbsp;dpopup.onclose = function(){dmask.close();};</p>
<p>&nbsp;&nbsp; &nbsp;//onsubmit事件处理函数</p>
<p>&nbsp;&nbsp; &nbsp;var fooaction = function(){</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//表单验证</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; var bc = easyUI.checkForm(this);</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; if(!bc){return false;}</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; //如果不是ajax方式提交则返回</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; var queryType = this.getAttribute('qtype');</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; if(!queryType||queryType.toLowerCase()!='ajax'){return true;}</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//取表单数据</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; var scaption = this.getAttribute('caption');</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; var dlms = this.elements,l = dlms.length-1;</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; var surl = this.action,args = [];</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; var dbtn = easyUI.getElementsBy('type','submit','button',this)[0];//取提交按钮</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; var pn = '',pt = '';</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; for(var i=0;i&lt;l;i++){</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;pn = dlms[i].name;</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;pt = dlms[i].type;</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if((pt=='checkbox'||pt=='radio')&amp;&amp;!dlms[i].checked){continue;}</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;args.push(pn+'='+encodeURI(dlms[i].value));</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//提交过程中禁用提交按钮</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; if(dbtn){dbtn.disabled = true;}</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//显示信息</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; var showmsg = function(stype,msg){</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;msg = msg.replace(/\\n/g,'&lt;br/&gt;');</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;var stitle = scaption?scaption:'提交表单';</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;var shd = (stype==1)?'&lt;h3 class=&quot;error&quot;&gt;错误!您提交的请求遇到了问题!&lt;/h3&gt;':'&lt;h3 class=&quot;success&quot;&gt;您提交的请求已处理成功!&lt;/h3&gt;';</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;var sbox = sresult.replace(/\$1/g,shd).replace(/\$2/g,msg);</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;dpopup.setTitle(stitle);</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;dpopup.setContent(sbox);</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(!dpopup.isopen){dpopup.open();}</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//显示错误信息</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; var fmsg = function(msg){</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;showmsg(1,msg);</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(dbtn){dbtn.disabled = false;}</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//AJAX提交处理函数</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; var cbfoo = function(xhr){</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(!xhr){fmsg('数据处理失败！xmlhttp对象未就绪！');return;}</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;var rtxt = xhr.responseText;</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(!rtxt){fmsg('数据处理失败！服务器没有返回值！');return;}</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//返回值约定为code,descript,jumpUrl</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;var astr = rtxt.split(','),scode = astr[0]||'20156',desc = astr[1],jump = astr[2];</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;desc = desc?unescape(decodeURI(desc)):'未知错误!';</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;jump = jump?unescape(decodeURI(jump)):false;</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(isNaN(scode)){fmsg('数据处理失败！服务器返回值不正确！');return;}</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;switch(scode){</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; case '-1'://状态码code为-1时则显示成功信息</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;showmsg(0,desc);</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//如果有跳转URL，则在关闭提示信息层后跳转</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(!!jump){dpopup.onclose = function(){dmask.close();window.location = jump;};}</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;break;</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; default:</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;fmsg('数据处理失败！'+desc+'！');break;</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//AJAX失败处理函数</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; var ffoo = function(xhr){</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;var sts = (xhr)?xhr.status:'20156';</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;fmsg('数据处理失败！服务器错误，错误代码：'+sts+'！');</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//AJAX提交</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; dpopup.setTitle('正在处理您的请求');</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; dpopup.setContent(swaiting);</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; dpopup.open();</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; easyUI.ajax.post(surl,args.join('&amp;'),true,cbfoo,ffoo);</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; return false;</p>
<p>&nbsp;&nbsp; &nbsp;};</p>
<p>&nbsp;&nbsp; &nbsp;//遍历所有dModule中出现的表单，并绑定onsubmit处理函数</p>
<p>&nbsp;&nbsp;&nbsp; var dforms = dModule.getElementsByTagName('form'),l = dforms.length;</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; for(var i=0;i&lt;l;i++){</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dforms[i].onsubmit = fooaction;</p>
<p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>}</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=265</link>
			<title><![CDATA[WEB取色器Easy Color Picker V1发布]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Wed,12 Aug 2009 14:36:51 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=265</guid>
		<description><![CDATA[<h2 class="topic"><strong><strong>基于EasyUI开发的可扩展附加组件WEB取色器 Easy Color Picker V1.0发布！</strong></strong></h2>
<p>&nbsp;</p>
<dl><dd>
<h3>方便绑定到控件</h3>
</dd><dd>
<h3>支持的颜色格式：</h3>
</dd><dd>
<h3>hex 十六进制值，如：#ff0000</h3>
</dd><dd>
<h3>rgb 值，如：255,0,0</h3>
</dd><dd>
<h3>hsb 值，如：0,100,100</h3>
<p>&nbsp;</p>
</dd></dl>
<p>EasyColorPicker测试地址：</p>
<p><a target="_blank" href="http://www.easyui.org.cn/easyColorPicker_demo.html">http://www.easyui.org.cn/easyColorPicker_demo.html</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=264</link>
			<title><![CDATA[JavaScript基础知识篇-你真的了解JavaScript吗？]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Fri,07 Aug 2009 09:29:17 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=264</guid>
		<description><![CDATA[<h1>你真的了解JavaScript吗？</h1>
<p>让我们重温一下JavaScript的一些基础知识，请先写出以下代码中问号处的答案，再运行比较！</p>
<p>&lt;script type=&quot;text/javascript&quot;&gt;<br />
<br />
var a=0,b=0,c=0;<br />
a+++b+++c;<br />
alert([a,b,c]);//?<br />
<br />
var a=[];<br />
alert(a[a++]);//?<br />
alert(a);//?<br />
<br />
var o={a:o++};<br />
alert(o.a);//?<br />
<br />
var f=function(){};<br />
alert(f(f++));<br />
<br />
alert(typeof(NaN))//?<br />
<br />
alert(typeof(Infinity))//?<br />
<br />
alert(typeof(null))//?<br />
<br />
alert(typeof(undefined))//?<br />
<br />
alert(NaN == NaN)//?<br />
<br />
alert(NaN != NaN)//?<br />
<br />
alert(NaN &gt;= NaN)//?<br />
<br />
alert(null == undefined)//?<br />
<br />
alert(null &gt;= undefined)//?<br />
<br />
alert(null &lt;= undefined)//?<br />
<br />
alert(parseInt(&quot;123abc&quot;))//?<br />
<br />
alert((&quot;123abc&quot; - 0))//?<br />
<br />
alert(Infinity &gt; 10)//?<br />
<br />
alert(Infinity &gt; &quot;abc&quot;)//?<br />
<br />
alert(Infinity == NaN)//?<br />
<br />
alert(true == 1)//?<br />
<br />
alert(new String(&quot;abc&quot;) == &quot;abc&quot;)//?<br />
<br />
alert(new String(&quot;abc&quot;) === &quot;abc&quot;)//?<br />
<br />
var a = &quot;123abc&quot;;<br />
alert(typeof(a++));//?<br />
alert(a);//?<br />
<br />
var a = &quot;123abc&quot;;<br />
a.valueOf = function(){return parseInt(a);}<br />
alert(++a);//?<br />
alert(a-0);//?<br />
<br />
var a = new Object();<br />
a.toString = function(){return &quot;123abc&quot;;}<br />
a.valueOf = function(){return parseInt(a);}<br />
alert(++a);//?<br />
alert(a-0);//?<br />
<br />
var spv = String.prototype.valueOf;<br />
String.prototype.valueOf = function(){<br />
&nbsp;&nbsp;&nbsp; return parseFloat(this);<br />
}<br />
alert(&quot;123abc&quot; &gt; 122);//?<br />
alert(new String(&quot;123abc&quot;) &gt; 122);//?<br />
String.prototype.valueOf = spv;<br />
<br />
var s = new String(&quot;abc&quot;);<br />
alert(typeof(s) == typeof(&quot;abc&quot;));//?<br />
alert(s === &quot;abc&quot;);//?<br />
alert(s.toString() == s);//?<br />
<br />
var a = new Object(),b = new Object();<br />
a.toString = function(){return &quot;a&quot;};<br />
b.toString = function(){return &quot;b&quot;};<br />
alert(a&gt;b);//?<br />
a.valueOf = function(){return 1};<br />
b.valueOf = function(){return 0};<br />
alert(a&gt;b);//?<br />
<br />
var step = function(a){<br />
&nbsp;&nbsp;&nbsp; return function(x){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x + a++;<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
var a = step(10);<br />
var b = step(20);<br />
alert(a(10));//?<br />
alert(b(10));//?<br />
<br />
&lt;/script&gt;</p>
<p>运行代码查看结果：<a href="http://www.jslab.org.cn/?tag=javascriptBasis" target="_blank">http://www.jslab.org.cn/?tag=javascriptBasis</a></p>
<p>希望大家在学习JavaScript的时候注意基本功的练习！^_^</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=263</link>
			<title><![CDATA[Nginx泛域名解析及Rewrite重定向普通页面及带参数的页面]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Fri,24 Jul 2009 10:30:37 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=263</guid>
		<description><![CDATA[<p>原本准备换Linux服务器，所以数据迁移暂时需要使用静态页面临时代替一下，之前的article.asp?id=xxx都要重定向到静态文件article/xxx.htm，下面看看Nginx是如何进行Rewrite的！</p>
<p><strong>静态地址重定向到带参数的动态地址</strong><br />
<br />
rewrite &quot;^(.*)/service/(.*)\.html$&quot; $1/service.php?sid=$2 permanent;<br />
<br />
<br />
<strong>带参数的动态地址重定向到静态地址</strong><br />
<br />
if ($query_string ~* id=(.*)) {<br />
&nbsp;&nbsp;&nbsp; set $id $1;<br />
&nbsp;&nbsp;&nbsp; rewrite &quot;^(.*)/article.asp$&quot; $1/article/$id.htm last;<br />
}</p>
<p><strong>泛域名解析<br />
</strong><br />
server_name www.w3cgroup.com *.w3cgroup.com;<br />
server_name_in_redirect off;<br />
#设置默认root<br />
set $rootdir /usr/local/nginx/html/w3cgroup/;<br />
#匹配三级域名<br />
if ($host ~* ^([^\.]+)\.([^\.]+)\.([^\.]+)\.([^\.]+)$) {<br />
&nbsp;&nbsp;&nbsp; set $rootdir /usr/local/nginx/html/w3cgroup/$2/$1;<br />
&nbsp;&nbsp;&nbsp; #三级域名中有访问指定的目录则重定向到相应的二级域名下<br />
&nbsp;&nbsp;&nbsp; rewrite &quot;^.+upload/?(.*)$&quot; http://upload.w3cgroup.com/$1 permanent;<br />
&nbsp;&nbsp;&nbsp; rewrite &quot;^.+ijc/?(.*)$&quot; http://ijc.w3cgroup.com/$1 permanent;<br />
&nbsp;&nbsp;&nbsp; break;<br />
}<br />
#匹配二级域名<br />
if ($host ~* ^([^\.]+)\.([^\.]+)\.([^\.]+)$) {<br />
&nbsp;&nbsp;&nbsp; set $rs1 $1;<br />
}<br />
#设置www时root<br />
if ($rs1 ~* ^www$) {<br />
&nbsp;&nbsp;&nbsp; set $rootdir /usr/local/nginx/html/platform_ig/;<br />
&nbsp;&nbsp;&nbsp; #二级域名中有访问指定的目录则重定向到相应的二级域名下,注意，这里要使用last<br />
&nbsp;&nbsp;&nbsp; rewrite &quot;^.+upload/?(.*)$&quot; upload/$1 last;<br />
&nbsp;&nbsp;&nbsp; rewrite &quot;^.+ijc/?(.*)$&quot; ijc/$1 last;<br />
&nbsp;&nbsp;&nbsp; break;<br />
}<br />
#设置非www二级域名时root<br />
if ($rs1 !~* ^www$) {<br />
&nbsp;&nbsp;&nbsp; set $rootdir /usr/local/nginx/html/w3cgroup/$rs1;<br />
&nbsp;&nbsp;&nbsp; #二级域名中有访问指定的目录则重定向到相应的二级域名下<br />
&nbsp;&nbsp;&nbsp; rewrite &quot;^.+upload/?(.*)$&quot; http://upload.w3cgroup.com/$1 permanent;<br />
&nbsp;&nbsp;&nbsp; rewrite &quot;^.+ijc/?(.*)$&quot; http://ijc.w3cgroup.com/$1 permanent;<br />
&nbsp;&nbsp;&nbsp; break;<br />
}<br />
#应用root<br />
root $rootdir;<br />
index index.php index.html;<br />
error_page 404 http://$host/;<br />
&nbsp;</p>
<p><strong>注意：if () {} 之间需要空格，否则Nginx.conf会报unknow directive 错误!</strong></p>
<p>参考：</p>
<p><img alt="" src="http://www.v-ec.com/dh20156/file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/moz-screenshot.jpg" /></p>
<p><strong>Nginx Rewrite Flags</strong><br />
* last 相当于Apache里的[L]标记，表示完成rewrite<br />
* break 终止匹配, 不再匹配后面的规则<br />
* redirect 返回302临时重定向<br />
* permanent 返回301永久重定向</p>
<p><strong>Nginx正则表达式匹配</strong><br />
* ~ 为区分大小写匹配<br />
* ~* 为不区分大小写匹配<br />
* !~和!~*分别为区分大小写不匹配及不区分大小写不匹配</p>
<p><strong>Nginx文件及目录匹配</strong><br />
* -f和!-f用来判断是否存在文件<br />
* -d和!-d用来判断是否存在目录<br />
* -e和!-e用来判断是否存在文件或目录<br />
* -x和!-x用来判断文件是否可执行</p>
<p><strong>Nginx全局变量</strong><br />
$args<br />
$content_length<br />
$content_type<br />
$document_root<br />
$document_uri<br />
$host<br />
$http_user_agent<br />
$http_cookie<br />
$limit_rate<br />
$request_body_file<br />
$request_method<br />
$remote_addr<br />
$remote_port<br />
$remote_user<br />
$request_filename<br />
$request_uri<br />
$query_string<br />
$scheme<br />
$server_protocol<br />
$server_addr<br />
$server_name<br />
$server_port<br />
$uri</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=262</link>
			<title><![CDATA[CSS选择器实现原理 - easyUI.cssSel&#101;ctor更新记录]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Wed,08 Jul 2009 11:29:34 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=262</guid>
		<description><![CDATA[<p>自从JQuery实现了Selector后，貌似其他一些JavaScript框架也开始向Selector靠拢，相继推出了自己的CSS选择器， 考虑到css选择器确实强大，所以，在easyUI中也添加了一个自己的cssSelector方法：easyUI.cssSelector('css选 择器',dom范围)</p>
<h1>CSS选择器实现原理：</h1>
<h2>&nbsp;</h2>
<h2>一、解析</h2>
<p><strong>1、格式化数据，将css选择器转换成一种便于后面进行操作的格式，这一步很重要，这是数据结构部分，后面的实现都将以此为依据。</strong></p>
<p>以下面数据为例：</p>
<p>#a b.c .d + e:first-child &gt; f[data = &quot;hello world!&quot;]</p>
<p>首先，捕获形如 [ 属性 = 值 ] 的数据，将&quot;=&quot;两边的空格去掉，然后将&ldquo;值&rdquo;里的空格替换为一个不太可能会出现的临时字串，如0x20156<br />
<br />
然后，在+、：、&gt;、[ 符号前加空格<br />
<br />
接着，将#、.、+、:、]、&gt;后的空格去掉</p>
<p>最好将单引号和双引号也都去掉</p>
<p>做完上述替换操作后，变可得到形如下面的数据：</p>
<p>#a b.c .d +e :first-child &gt;f [data=hello0xdh20156world!]</p>
<p><strong>2、将格式化后的数据转换成这样的伪代码：取节点函数('css选择符',上一次操作的结果)，以空格为分隔：</strong></p>
<p>取节点函数('#a',上一次操作的结果)</p>
<p>取节点函数('b.c',上一次操作的结果)</p>
<p>取节点函数('.d',上一次操作的结果)</p>
<p>取节点函数('+e',上一次操作的结果)</p>
<p>取节点函数(':first-child',上一次操作的结果)</p>
<p>取节点函数('&gt;f',上一次操作的结果)</p>
<p>取节点函数('[data=hello0xdh20156world!]',上一次操作的结果)</p>
<p><strong>3、将css选择器解析成具体的取节点函数，如：</strong></p>
<p>#a应当解析成：document.getElementById('a')</p>
<p>E#a应当解析成：document.getElementsByTagName('E')，然后遍历id=a的</p>
<p>之前进行过转换的0x20156记得重新转换为空格。</p>
<p>&nbsp;</p>
<p>更多css Selectors的解释请参见：</p>
<p><a href="http://www.w3.org/TR/CSS2/selector.html" target="_blank">http://www.w3.org/TR/CSS2/selector.html</a></p>
<h2>&nbsp;</h2>
<h2>二、编写取节点函数，将伪代码实现</h2>
<p>在easyUI.cssSelector的实现中采用的是eval的方式，目前该方法尚未完全支持CSS2选择器，还在测试阶段！</p>
<p>&nbsp;</p>
<p><strong>演示：</strong></p>
<p><br />
<a href="http://www.jslab.org.cn/?tag=cssSelector" target="_blank">easyUI Css Selector测试地址：http://www.jslab.org.cn/?tag=cssSelector</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=261</link>
			<title><![CDATA[汇编语言中CPU寄存器的功能和说明]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Fri,03 Jul 2009 17:03:53 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=261</guid>
		<description><![CDATA[<h1>CPU寄存器的功能和说明:</h1>
<p>&nbsp;</p>
<p>
<table border="0" style="width: 561px; height: 230px;">
    <tbody>
        <tr>
            <td><span>通用寄存器</span></td>
            <td><span>4个</span></td>
            <td><span>EAX、EBX、ECX和EDX</span></td>
            <td><span>32位</span></td>
        </tr>
        <tr>
            <td><span>段寄存器</span></td>
            <td><span><span>6个</span></span></td>
            <td><span>ES、CS、SS、DS、FS和GS</span></td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td><span>变址寄存器</span></td>
            <td><span>2个</span></td>
            <td><span>ESI和EDI</span></td>
            <td><span>32位</span></td>
        </tr>
        <tr>
            <td><span>堆栈寄存器</span></td>
            <td><span>2个</span></td>
            <td><span>ESP和EBP</span></td>
            <td><span>32位</span></td>
        </tr>
        <tr>
            <td><span>指令指针寄存器</span></td>
            <td><span>1</span></td>
            <td><span>EIP</span></td>
            <td><span>32位</span></td>
        </tr>
        <tr>
            <td><span>状态标志寄存器</span></td>
            <td><span>1</span></td>
            <td><span>EFlags</span></td>
            <td><span>32位</span></td>
        </tr>
        <tr>
            <td><span>控制寄存器</span></td>
            <td>&nbsp;</td>
            <td><span>CR0-CR4</span></td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td><span>调试寄存器</span></td>
            <td>&nbsp;</td>
            <td><span>DR0-DR7</span></td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td><span>测试寄存器</span></td>
            <td>&nbsp;</td>
            <td><span>TR3-TR5</span></td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td><span>系统地址寄存器</span></td>
            <td><span>2个</span></td>
            <td><span>GDTR，IDTR</span></td>
            <td><span>48位</span></td>
        </tr>
    </tbody>
</table>
</p>
<p>&nbsp;</p>
<h2>通用寄存器</h2>
<p><br />
EAX通常称为累加器(Accumulator),用累加器进行的操作速度最快</p>
<p>EBX称为基址寄存器(Base Register),可作为存储器地址指针来使用</p>
<p>ECX称为计数寄存器(Count Register)。在循环和字符串操作时，可用它来控制循环次数</p>
<p>EDX称为数据寄存器(Data Register)。在进行乘、除运算时，作为默认操作数参与运算</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>变址寄存器&nbsp;</h2>
<p>&nbsp;</p>
<p>ESI&nbsp; 指针寄存器的一种。是内存移动和比较操作的源地址寄存器；</p>
<p>EDI&nbsp; 指针寄存器的一种。是内存移动和比较操作的目标地址寄存器；</p>
<p>&nbsp;</p>
<h2>堆栈寄存器</h2>
<p>&nbsp;</p>
<p>EBP 指针寄存器的一种，堆栈基址指针寄存器确定堆栈帧的起始位置，</p>
<p>ESP 指针寄存器的一种，总是指向当前堆栈顶位置。</p>
<p>&nbsp;</p>
<h2>段寄存器</h2>
<p>&nbsp;</p>
<p>段寄存器是根据内存分段的管理模式而设置的。内存单元的物理地址由段寄存器的值和一个偏移量组合而成的，这样可用两</p>
<p>个较少位数的值组合成一个可访问较大物理空间的内存地址，CPU内部的段寄存器：</p>
<p>CS：代码段寄存器(Code Segment Register)：和IP（是用来存放下条待执行的指令在该段的偏移量）合在一起可在该内存段内取到下次要执行的指令。</p>
<p>DS：数据段寄存器(Data Segment Register)：</p>
<p>SS：堆栈段寄存器(Stack Segment Register)：堆栈操作所用的段寄存器和偏移量一定是SS和ESP</p>
<p>ES：附加段寄存器(Extra Segment Register)：&nbsp;串操作的目标操作数所用的段寄存器和偏移量一定是ES和EDI</p>
<p>FS：附加段寄存器(Extra Segment Register)：</p>
<p>GS：附加段寄存器(Extra Segment Register)：</p>
<p>&nbsp;</p>
<h2>指令指针寄存器</h2>
<p>EIP：EIP的低16位为代码CS段的偏移量，高16位都为0。</p>
<p>&nbsp;</p>
<h2>状态标志寄存器</h2>
<p>运算结果标志位</p>
<p>1、进位标志CF(Carry Flag)：</p>
<p style="padding-left: 30px;">进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位，那么，其值为1，否则其值为0。使用该标志位的情况有：多字(字节)数的加减运算，无符号数的大小比较运算，移位操作，字(字节)之间移位，专门改变CF值的指令等。</p>
<p>2、奇偶标志PF(Parity Flag)：</p>
<p style="padding-left: 30px;">奇偶标志PF用于反映运算结果中&ldquo;1&rdquo;的个数的奇偶性。如果&ldquo;1&rdquo;的个数为偶数，则PF的值为1，否则其值为0。利用PF可进行奇偶校验检查，或产生奇偶校验位。在数据传送过程中，为了提供传送的可靠性，如果采用奇偶校验的方法，就可使用该标志位。</p>
<p>3、辅助进位标志AF(Auxiliary Carry Flag)：</p>
<p style="padding-left: 30px;">在发生下列情况时，辅助进位标志AF的值被置为1，否则其值为0：</p>
<p style="padding-left: 30px;">(1)、在字操作时，发生低字节向高字节进位或借位时；<br />
(2)、在字节操作时，发生低4位向高4位进位或借位时。</p>
<p>4、零标志ZF(Zero Flag)：</p>
<p style="padding-left: 30px;">零标志ZF用来反映运算结果是否为0。如果运算结果为0，则其值为1，否则其值为0。</p>
<p>5、符号标志SF(Sign Flag)：</p>
<p style="padding-left: 30px;">符号标志SF用来反映运算结果的符号位，它与运算结果的最高位相同。运算结果为正数时，SF的值为0，否则其值为1。</p>
<p>6、溢出标志OF(Overflow Flag)：</p>
<p style="padding-left: 30px;">运算结果超过当前运算位数所能表示的范围，OF的值被置为1，否则，OF的值被清为0&nbsp;</p>
<p>７、状态控制标志位：状态控制标志位是用来控制CPU操作的，它们要通过专门的指令才能使之发生改变。</p>
<p style="padding-left: 30px;">1、追踪标志TF(Trap Flag)：</p>
<p style="padding-left: 60px;">当追踪标志TF被置为1时，CPU进入单步执行方式。</p>
<p style="padding-left: 30px;">2、中断允许标志IF(Interrupt-enable Flag)：</p>
<p style="padding-left: 30px;">CPU外部的不可屏蔽中断所发出的中断请求，以及CPU内部产生的中断请求。具体规定如下：</p>
<p style="padding-left: 60px;">(1)、当IF=1时，CPU可以响应CPU外部的可屏蔽中断发出的中断请求；</p>
<p style="padding-left: 60px;">(2)、当IF=0时，CPU不响应CPU外部的可屏蔽中断发出的中断请求。</p>
<p style="padding-left: 30px;">CPU的指令系统中也有专门的指令来改变标志位IF的值。</p>
<p style="padding-left: 30px;">3、方向标志DF(Direction Flag)：</p>
<p style="padding-left: 60px;">方向标志DF用来决定在串操作指令执行时有关指针寄存器发生调整的方向。在微机的指令系统中，还提供了专门的指令来改变标志位DF的值。</p>
<p>8、32位标志寄存器增加的标志位：</p>
<p style="padding-left: 30px;">1、I/O特权标志IOPL(I/O Privilege Level)：</p>
<p style="padding-left: 60px;">I/O特权标志用两位二进制位来表示，也称为I/O特权级字段。该字段指定了要求执行I/O指令的特权级。如果当前的特权级别在数值上小于等于IOPL的值，那么，该I/O指令可执行，否则将发生一个保护异常。</p>
<p style="padding-left: 30px;">2、嵌套任务标志NT(Nested Task)：</p>
<p style="padding-left: 60px;">嵌套任务标志NT用来控制中断返回指令IRET的执行。具体规定如下：</p>
<p style="padding-left: 60px;">(1)、当NT=0，用堆栈中保存的值恢复EFLAGS、CS和EIP，执行常规的中断返回操作；</p>
<p style="padding-left: 60px;">(2)、当NT=1，通过任务转换实现中断返回。</p>
<p style="padding-left: 30px;">3、重启动标志RF(Restart Flag)：</p>
<p style="padding-left: 60px;">重启动标志RF用来控制是否接受调试故障。规定：RF=0时，表示&ldquo;接受&rdquo;调试故障，否则拒绝之。在成功执行完一条指令后，处理机把RF置为0，当接受到一个非调试故障时，处理机就把它置为1。</p>
<p style="padding-left: 30px;">4、虚拟8086方式标志VM(Virtual 8086 Mode)：</p>
<p style="padding-left: 60px;">如果该标志的值为1，则表示处理机处于虚拟的8086方式下的工作状态，否则，处理机处于一般保护方式下的工作状态。</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=260</link>
			<title><![CDATA[反汇编代码分析后编写出C代码实例]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Fri,03 Jul 2009 13:39:03 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=260</guid>
		<description><![CDATA[<p><font color="#0000ff" style="font-size: 12px;">00401020&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp<br />
00401021&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp,esp<br />
00401023&nbsp;&nbsp; sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esp,50h<br />
00401026&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebx<br />
00401027&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esi<br />
00401028&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edi<br />
00401029&nbsp;&nbsp; lea&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edi,[ebp-50h]<br />
0040102C&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ecx,14h<br />
00401031&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,0CCCCCCCCh<br />
00401036&nbsp;&nbsp; rep stos&nbsp;&nbsp;&nbsp; dword ptr [edi]</font></p>
<p><font color="#009900" style="font-size: 12px;">；函数初始化以及分配栈的代码</font></p>
<p><font color="#0000ff" style="font-size: 12px;">00401038&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-4],64h&nbsp;</font></p>
<p><font color="#0000ff" style="font-size: 12px;"><font color="#009900">；将100给第一个局部变量，我们假设它是n ,int n=100;</font><br />
0040103F&nbsp;&nbsp; jmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boxer+2Ah (0040104a)&nbsp;<font color="#009900">；之后一个只直接跳转到0040104a</font></font></p>
<p><br />
<font color="#0000ff" style="font-size: 12px;">00401041&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [ebp-4]&nbsp;<font color="#009900">；n放到eax<br />
</font>00401044&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,1&nbsp;&nbsp;&nbsp;<font color="#009900">；eax+1<br />
</font>00401047&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-4],eax&nbsp;<font color="#009900">；就是n++</font></font></p>
<p><font style="font-size: 12px;">&nbsp;</font></p>
<p><font color="#0000ff" style="font-size: 12px;">0040104A&nbsp;&nbsp; cmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-4],3E8h&nbsp;</font></p>
<p><font color="#0000ff" style="font-size: 12px;"><font color="#009900">；n与3E8比较，我们看看10进制的数是什么，n&lt;1000;<br />
</font>00401051&nbsp;&nbsp; jge&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boxer+0A5h (004010c5)&nbsp;<font color="#009900">；小于就不跳，继续</font></font></p>
<p><br />
<font color="#0000ff" style="font-size: 12px;">00401053&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [ebp-4]&nbsp;<font color="#009900">；n放进eax<br />
</font>00401056&nbsp;&nbsp; cdq&nbsp;&nbsp;&nbsp;&nbsp;<font color="#009900">&nbsp;；CDQ 双字扩展. (把EAX中的值与符号扩展为EDX:EAX)<br />
</font>00401057&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ecx,64h&nbsp;&nbsp;&nbsp;<font color="#009900">；100放进ecx<br />
</font>0040105C&nbsp;&nbsp; idiv&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,ecx&nbsp;&nbsp;&nbsp;</font></p>
<p><font color="#0000ff" style="font-size: 12px;"><font color="#009900">；整数除法，eax除以ecx，就是n/100，商保存在eax，余数放在edx</font><br />
0040105E&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [i],eax&nbsp;<font color="#009900">；把结果放在变量i中,i=n/100</font></font></p>
<p><br />
<font style="font-size: 12px;"><font color="#0000ff">00401061&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [ebp-4]&nbsp;<font color="#009900">；再把n放进eax<br />
</font>00401064&nbsp;&nbsp; cdq<br />
00401065&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ecx,0Ah&nbsp;&nbsp;&nbsp;<font color="#009900">；把0Ah（10）放进ecx<br />
</font>0040106A&nbsp;&nbsp; idiv&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,ecx&nbsp;&nbsp;&nbsp;</font><font color="#009900">；n/10，商保存在eax，余数放在edx<br />
</font><font color="#0000ff">0040106C&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edx,dword ptr [i]&nbsp;<font color="#009900">；将之前n/100的结果放到edx中<br />
</font>0040106F&nbsp;&nbsp; imul&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edx,edx,0Ah&nbsp;&nbsp;<font color="#009900">；edx乘10结果放在edx中<br />
</font>00401072&nbsp;&nbsp; sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,edx&nbsp;&nbsp;<font color="#009900">&nbsp;；n/10-i*10<br />
</font>00401074&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [j],eax&nbsp;</font><font color="#009900">；j=n/10-i*10;</font></font></p>
<p><br />
<font color="#0000ff" style="font-size: 12px;">00401077&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [ebp-4]&nbsp;<font color="#009900">；n放进eax<br />
</font>0040107A&nbsp;&nbsp; cdq<br />
0040107B&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ecx,0Ah&nbsp;&nbsp;&nbsp;<font color="#009900">；10放进ecx<br />
</font>00401080&nbsp;&nbsp; idiv&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,ecx&nbsp;&nbsp;&nbsp;<font color="#009900">；n/10，商放在eax（其实是ax），余数在edx（其实是dx）</font><br />
00401082&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [k],edx&nbsp;<font color="#009900">；将n/10余数放进变量k，就是k=n%10;</font></font></p>
<p><br />
<font style="font-size: 12px;"><font color="#0000ff">00401085&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edx,dword ptr [i]&nbsp;<font color="#009900">；这三句是i*i*i<br />
</font></font><font color="#0000ff">00401088&nbsp;&nbsp; imul&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edx,dword ptr [i]<br />
0040108C&nbsp;&nbsp; imul&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edx,dword ptr [i]<br />
00401090&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [j]&nbsp;<font color="#009900">；这三句是j*j*j<br />
</font>00401093&nbsp;&nbsp; imul&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [j]<br />
00401097&nbsp;&nbsp; imul&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [j]<br />
0040109B&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edx,eax&nbsp;&nbsp;&nbsp;<font color="#009900">；i*i*i+j*j*j<br />
</font>0040109D&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ecx,dword ptr [k]&nbsp;<font color="#009900">；这三句是k*k*k<br />
</font>004010A0&nbsp;&nbsp; imul&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ecx,dword ptr [k]<br />
004010A4&nbsp;&nbsp; imul&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ecx,dword ptr [k]<br />
004010A8&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edx,ecx&nbsp;&nbsp;&nbsp;</font><font color="#009900">；i*i*i+j*j*j+k*k*k，放在edx</font></font></p>
<p><br />
<font style="font-size: 12px;"><font color="#0000ff">004010AA&nbsp;&nbsp; cmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-4],edx&nbsp;<font color="#009900">；将上面的结果和变量n比较<br />
</font>004010AD&nbsp;&nbsp; jne&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boxer+0A0h (004010c0)&nbsp;</font><font color="#009900">；不等就跳004010c0<br />
；一个cmp加一个跳转，是if语句了</font></font></p>
<p><br />
<font color="#0000ff" style="font-size: 12px;">004010AF&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edx,dword ptr [ebp-4]&nbsp;<font color="#009900">；n放在edx，然后入栈，调用printf函数<br />
</font>004010B2&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edx&nbsp;&nbsp;&nbsp;<br />
004010B3&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset string &quot;%4d&quot; (00422020)<br />
004010B8&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (00401160)<br />
004010BD&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esp,8</font></p>
<p><font color="#0000ff" style="font-size: 12px;">&nbsp;</font></p>
<p><font style="font-size: 12px;"><font color="#0000ff">004010C0&nbsp;&nbsp; jmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boxer+21h (00401041)&nbsp;</font></font></p>
<p><font color="#009900" style="font-size: 12px;">；一个硬跳转回到开头，上面应该是一个for循环体了<br />
；我们可以复习一下for循环的debug版模板</font></p>
<p><br />
<font color="#0000ff" style="font-size: 12px;"><font color="#009900">；又一个printf语句</font><br />
004010C5&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset string &quot;\n&quot; (0042201c)<br />
004010CA&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (00401160)<br />
004010CF&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esp,4<br />
004010D2&nbsp;&nbsp; xor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,eax&nbsp;&nbsp;&nbsp;<font color="#009900">清空eax，就是返回值是0，return 0;</font></font></p>
<p><br />
<font color="#009900" style="font-size: 12px;">；上面就是代码的主体了，我们看看怎么写反C代码</font></p>
<p><font style="font-size: 12px;"><font color="#0000ff">004010D4&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edi</font><br />
<font color="#0000ff">004010D5&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esi<br />
004010D6&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebx<br />
004010D7&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esp,50h<br />
004010DA&nbsp;&nbsp; cmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp,esp<br />
004010DC&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __chkesp (004011e0)<br />
004010E1&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esp,ebp<br />
004010E3&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp<br />
004010E4&nbsp;&nbsp; ret</font></font></p>
<p><br />
<font color="#009900" style="font-size: 12px;">；函数结束时候恢复寄存器恢复堆栈检查esp等代码</font></p>
<p><br />
<font color="#009900" style="font-size: 12px;">------------------------------------------------------------------------------</font></p>
<p><font color="#009900" style="font-size: 12px;">完整分析了上面代码后，我们去写出C代码</font></p>
<p><br />
<font color="#0000ff" style="font-size: 12px;">int&nbsp;boxer()<br />
{<br />
&nbsp;for (int n=100; n&lt;1000; n++)<br />
&nbsp;{<br />
&nbsp;&nbsp;int i=n/100;<br />
&nbsp;&nbsp;int j=n/10-i*10;<br />
&nbsp;&nbsp;int k=n%10;</font></p>
<p><font color="#0000ff" style="font-size: 12px;">&nbsp;&nbsp;if (n==i*i*i+j*j*j+k*k*k)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;printf(&quot;%4d&quot;,n);<br />
&nbsp;&nbsp;}</font></p>
<p><font style="font-size: 12px;">&nbsp;<font color="#0000ff">}</font></font></p>
<p><font color="#0000ff" style="font-size: 12px;">&nbsp;printf(&quot;\n&quot;);</font></p>
<p><font color="#0000ff" style="font-size: 12px;">&nbsp;return 0;<br />
}</font></p>
<p><br />
<font color="#009900" style="font-size: 12px;">------------------------------------------------------------------------------</font></p>
<p><font style="font-size: 12px;">写完代码后，我们补全这个程序然后验证一下，显示结果了看看程序的用途</font></p>
<p><font style="font-size: 12px;">比如说153=1^3+5^3+3^3，这个是一个水仙花数</font></p>
<p><font style="font-size: 12px;">水仙花数：一个3位数，其各位数字的立方和等于该数本身</font></p>
<p><font style="font-size: 12px;">所以这个程序是打印出所有的水仙花数的</font></p>
<p>&nbsp;</p>
<p><font style="font-size: 12px;">原文出处：<a rel="nofollow" target="_blank" href="http://www.hight123.cn/Html/?611.html">http://www.hight123.cn/Html/?611.html</a></font></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=259</link>
			<title><![CDATA[汇编指令英文全称及中文释义]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Fri,03 Jul 2009 12:45:11 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=259</guid>
		<description><![CDATA[<h2><strong>汇编指令英文全称</strong></h2>
<p>&nbsp;</p>
<p><strong>1.通用数据传送指令</strong></p>
<p>MOV----&gt; move&nbsp;</p>
<pre><font color="#990000"><strong>&nbsp;MOV&nbsp;dest,src&nbsp;;dest&larr;src <br />&nbsp;MOV指令把一个字节或字的操作数从源地址src传送至目的地址dest。 </strong></font>

MOVSX----&gt;extended move with sign data 
MOVZX----&gt;extended move with zero data </pre>
<pre>
PUSH----&gt;push 
POP----&gt;pop </pre>
<pre><font><strong><font color="#990000"><strong>进栈出栈指令</strong></font></strong></font></pre>
<pre>
PUSHA----&gt;push all 
POPA----&gt;pop all 
PUSHAD----&gt;push all data 
POPAD----&gt;pop all data 
BSWAP----&gt;byte swap </pre>
<pre>
XCHG----&gt;exchange </pre>
<pre><span style="color: rgb(153, 0, 0);"><strong>交换指令用来将源操作数和目的操作数内容交换，操作数可以是字、也可以是字节，可以在通用寄存器与通用寄存器或存储器之间对换数据，但不能在存储器与存储器之间对换数据。</strong> </span>
<font color="#990000"><strong>mov ax,1234h ;ax=1234h <br />mov bx,5678h ;bx=5678h <br />xchg ax,bx ;ax=5678h，bx=1234h <br />xchg ah,al ;ax=7856h</strong></font>

CMPXCHG----&gt;compare and change 
XADD----&gt;exchange and add 

XLAT----&gt;translate 
<font color="#990000"><strong>换码指令用于将BX指定的缓冲区中、AL指定的位移处的数据取出赋给AL。 <br /></strong></font></pre>
<pre><strong>2.输入输出端口传送指令</strong>

IN----&gt;input 
OUT----&gt;output 
</pre>
<pre><strong>3.目的地址传送指令</strong>

LEA----&gt;load effective addres
<span style="color: rgb(153, 0, 0);"><font><b>有效地址传送指令</b></font></span>
<font size="2">mov bx,0400h</font>
<font size="2">mov si,3ch</font>
<font size="2">lea bx,[bx+si+0f62h] ;BX=139EH<br /></font><strong><font color="#990000">这里BX得到的是主存单元的有效地址，不是物理地址，也不是该单元的内容。</font></strong></pre>
<pre>
LDS----&gt;load DS 
LES----&gt;load ES 
LFS----&gt;load FS 
LGS----&gt;load GS 
LSS----&gt;load SS 
</pre>
<pre><strong>4.标志传送指令</strong>

LAHF----&gt;load AH from flag 
SAHF----&gt;save AH to flag 
PUSHF----&gt;push flag 
POPF----&gt;pop flag 
PUSHD----&gt;push dflag 
POPD----&gt;pop dflag


<strong>二、算术运算指令</strong> 

ADD----&gt;add </pre>
<pre><span style="color: rgb(153, 0, 0);"><strong>加法指令</strong> </span>mov al,0fbh ;al=0fbh
add al,07h ;al=02h</pre>
<pre>

ADC----&gt;add with carry 
INC----&gt;increase 1 
AAA----&gt;ascii add with adjust 
DAA----&gt;decimal add with adjust 
SUB----&gt;substract 
SBB----&gt;substract with borrow 
DEC----&gt;decrease 1 
NEC----&gt;negative 
CMP----&gt;compare 
AAS----&gt;ascii adjust on substract 
DAS----&gt;decimal adjust on substract 
MUL----&gt;multiplication 
IMUL----&gt;integer multiplication 
AAM----&gt;ascii adjust on multiplication 
DIV----&gt;divide 
IDIV----&gt;integer divide 
AAD----&gt;ascii adjust on divide 
CBW----&gt;change byte to word 
CWD----&gt;change word to double word 
CWDE----&gt;change word to double word with sign to EAX 
CDQ----&gt;change double word to quadrate word 
</pre>
<pre>

</pre>
<pre><strong>三、逻辑运算指令</strong>

AND----&gt;and 
or----&gt;or 
XOR----&gt;xor 
NOT----&gt;not 
TEST----&gt;test 
SHL----&gt;shift left 
SAL----&gt;arithmatic shift left 
SHR----&gt;shift right 
SAR----&gt;arithmatic shift right 
ROL----&gt;rotate left 
ROR----&gt;rotate right 
RCL----&gt;rotate left with carry 
RCR----&gt;rotate right with carry 


<strong>四、串指令</strong> 

MOVS----&gt;move string 
CMPS----&gt;compare string 
SCAS----&gt;scan string 
LODS----&gt;load string 
STOS----&gt;store string 
REP----&gt;repeat 
REPE----&gt;repeat when equal 
REPZ----&gt;repeat when zero flag 
REPNE----&gt;repeat when not equal 
REPNZ----&gt;repeat when zero flag 
REPC----&gt;repeat when carry flag 
REPNC----&gt;repeat when not carry flag 


<strong>五、程序转移指令</strong> 

<strong>1&gt;无条件转移指令(长转移)</strong> 

JMP----&gt;jump 
CALL----&gt;call 
RET----&gt;return 
RETF----&gt;return far 

<strong>2&gt;条件转移指令(短转移,-128到+127的距离内)</strong> 

JAE----&gt;jump when above or equal 
JNB----&gt;jump when not below 
JB----&gt;jump when below 
JNAE----&gt;jump when not above or equal 
JBE----&gt;jump when below or equal 
JNA----&gt;jump when not above 
JG----&gt;jump when greater 
JNLE----&gt;jump when not less or equal 
JGE----&gt;jump when greater or equal 
JNL----&gt;jump when not less 
JL----&gt;jump when less 
JNGE----&gt;jump when not greater or equal 
JLE----&gt;jump when less or equal 
JNG----&gt;jump when not greater 
JE----&gt;jump when equal 
JZ----&gt;jump when has zero flag 
JNE----&gt;jump when not equal 
JNZ----&gt;jump when not has zero flag 
JC----&gt;jump when has carry flag 
JNC----&gt;jump when not has carry flag 
JNO----&gt;jump when not has overflow flag 
JNP----&gt;jump when not has parity flag 
JPO----&gt;jump when parity flag is odd 
JNS----&gt;jump when not has sign flag 
JO----&gt;jump when has overflow flag 
JP----&gt;jump when has parity flag 
JPE----&gt;jump when parity flag is even 
JS----&gt;jump when has sign flag 

<strong>3&gt;循环控制指令(短转移)</strong> 

LOOP----&gt;loop 
LOOPE----&gt;loop equal 
LOOPZ----&gt;loop zero 
LOOPNE----&gt;loop not equal 
LOOPNZ----&gt;loop not zero 
JCXZ----&gt;jump when CX is zero 
JECXZ----&gt;jump when ECX is zero 

<strong>4&gt;中断指令</strong> 

INT----&gt;interrupt 
INTO----&gt;overflow interrupt 
IRET----&gt;interrupt return 

<strong>5&gt;处理器控制指令</strong> 

HLT----&gt;halt 
WAIT----&gt;wait 
ESC----&gt;escape 
LOCK----&gt;lock 
NOP----&gt;no operation 
STC----&gt;set carry 
CLC----&gt;clear carry 
CMC----&gt;carry make change 
STD----&gt;set direction 
CLD----&gt;clear direction 
STI----&gt;set interrupt 
CLI----&gt;clear interrupt 
<strong> 六、伪指令</strong> 

DW----&gt;definw word 
PROC----&gt;procedure 
ENDP----&gt;end of procedure 
SEGMENT----&gt;segment 
ASSUME----&gt;assume 
ENDS----&gt;end segment 
END----&gt;end
</pre>
<p>&nbsp;</p>
<h2>汇编指令中文释义</h2>
<p>&nbsp;</p>
<p><strong>数据传输指令</strong><br />
───────────────────────────────────────<br />
它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.<br />
1. 通用数据传送指令.<br />
MOV 传送字或字节.<br />
MOVSX 先符号扩展,再传送.<br />
MOVZX 先零扩展,再传送.<br />
PUSH 把字压入堆栈.<br />
POP 把字弹出堆栈.<br />
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.<br />
POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.<br />
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.<br />
POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.<br />
BSWAP 交换32位寄存器里字节的顺序<br />
XCHG 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数)<br />
CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX )<br />
XADD 先交换再累加.( 结果在第一个操作数里 )<br />
XLAT 字节查表转换.<br />
── BX 指向一张 256 字节的表的起点, AL 为表的索引值 (0-255,即<br />
0-FFH); 返回 AL 为查表结果. ( [BX+AL]-&gt;AL )<br />
2. 输入输出端口传送指令.<br />
IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} )<br />
OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )<br />
输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,<br />
其范围是 0-65535.<br />
3. 目的地址传送指令.<br />
LEA 装入有效地址.<br />
例: LEA DX,string ;把偏移地址存到DX.<br />
LDS 传送目标指针,把指针内容装入DS.<br />
例: LDS SI,string ;把段地址:偏移地址存到DS:SI.<br />
LES 传送目标指针,把指针内容装入ES.<br />
例: LES DI,string ;把段地址:偏移地址存到ES:DI.<br />
LFS 传送目标指针,把指针内容装入FS.<br />
例: LFS DI,string ;把段地址:偏移地址存到FS:DI.<br />
LGS 传送目标指针,把指针内容装入GS.<br />
例: LGS DI,string ;把段地址:偏移地址存到GS:DI.<br />
LSS 传送目标指针,把指针内容装入SS.<br />
例: LSS DI,string ;把段地址:偏移地址存到SS:DI.<br />
4. 标志传送指令.<br />
LAHF 标志寄存器传送,把标志装入AH.<br />
SAHF 标志寄存器传送,把AH内容装入标志寄存器.<br />
PUSHF 标志入栈.<br />
POPF 标志出栈.<br />
PUSHD 32位标志入栈.<br />
POPD 32位标志出栈.<br />
<br />
<strong>二、算术运算指令</strong><br />
───────────────────────────────────────<br />
ADD 加法.<br />
ADC 带进位加法.<br />
INC 加 1.<br />
AAA 加法的ASCII码调整.<br />
DAA 加法的十进制调整.<br />
SUB 减法.<br />
SBB 带借位减法.<br />
DEC 减 1.<br />
NEC 求反(以 0 减之).<br />
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).<br />
AAS 减法的ASCII码调整.<br />
DAS 减法的十进制调整.<br />
MUL 无符号乘法.<br />
IMUL 整数乘法.<br />
以上两条,结果回送AH和AL(字节运算),或DX和AX(字运算),<br />
AAM 乘法的ASCII码调整.<br />
DIV 无符号除法.<br />
IDIV 整数除法.<br />
以上两条,结果回送:<br />
商回送AL,余数回送AH, (字节运算);<br />
或 商回送AX,余数回送DX, (字运算).<br />
AAD 除法的ASCII码调整.<br />
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)<br />
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)<br />
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)<br />
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)<br />
<br />
<strong>三、逻辑运算指令</strong><br />
───────────────────────────────────────<br />
AND 与运算.<br />
or 或运算.<br />
XOR 异或运算.<br />
NOT 取反.<br />
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).<br />
SHL 逻辑左移.<br />
SAL 算术左移.(=SHL)<br />
SHR 逻辑右移.<br />
<font color="#ff3300">SAR 算术右移.<strike>(=SHR)</strike></font>&nbsp; 当值为负时，高位补 1 ；当值为正时，高位补 0 <br />
ROL 循环左移.<br />
ROR 循环右移.<br />
RCL 通过进位的循环左移.<br />
RCR 通过进位的循环右移.<br />
以上八种移位指令,其移位次数可达255次.<br />
移位一次时, 可直接用操作码. 如 SHL AX,1.<br />
移位&gt;1次时, 则由寄存器CL给出移位次数.<br />
如 MOV CL,04<br />
SHL AX,CL<br />
<br />
<strong>四、串指令</strong><br />
───────────────────────────────────────<br />
DS:SI 源串段寄存器 :源串变址.<br />
ES:DI 目标串段寄存器:目标串变址.<br />
CX 重复次数计数器.<br />
AL/AX 扫描值.<br />
D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.<br />
Z标志 用来控制扫描或比较操作的结束.<br />
MOVS 串传送.<br />
( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )<br />
CMPS 串比较.<br />
( CMPSB 比较字符. CMPSW 比较字. )<br />
SCAS 串扫描.<br />
把AL或AX的内容与目标串作比较,比较结果反映在标志位.<br />
LODS 装入串.<br />
把源串中的元素(字或字节)逐一装入AL或AX中.<br />
( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )<br />
STOS 保存串.<br />
是LODS的逆过程.<br />
REP 当CX/ECX&lt;&gt;0时重复.<br />
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX&lt;&gt;0时重复.<br />
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX&lt;&gt;0时重复.<br />
REPC 当CF=1且CX/ECX&lt;&gt;0时重复.<br />
REPNC 当CF=0且CX/ECX&lt;&gt;0时重复.<br />
<br />
<strong>五、程序转移指令</strong><br />
───────────────────────────────────────<br />
1&gt;无条件转移指令 (长转移)<br />
JMP 无条件转移指令<br />
CALL 过程调用<br />
RET/RETF过程返回.<br />
2&gt;条件转移指令 (短转移,-128到+127的距离内)<br />
( 当且仅当(SF XOR OF)=1时,OP1 JA/JNBE 不小于或不等于时转移.<br />
JAE/JNB 大于或等于转移.<br />
JB/JNAE 小于转移.<br />
JBE/JNA 小于或等于转移.<br />
以上四条,测试无符号整数运算的结果(标志C和Z).<br />
JG/JNLE 大于转移.<br />
JGE/JNL 大于或等于转移.<br />
JL/JNGE 小于转移.<br />
JLE/JNG 小于或等于转移.<br />
以上四条,测试带符号整数运算的结果(标志S,O和Z).<br />
JE/JZ 等于转移.<br />
JNE/JNZ 不等于时转移.<br />
JC 有进位时转移.<br />
JNC 无进位时转移.<br />
JNO 不溢出时转移.<br />
JNP/JPO 奇偶性为奇数时转移.<br />
JNS 符号位为 &quot;0&quot; 时转移.<br />
JO 溢出转移.<br />
JP/JPE 奇偶性为偶数时转移.<br />
JS 符号位为 &quot;1&quot; 时转移.<br />
3&gt;循环控制指令(短转移)<br />
LOOP CX不为零时循环.<br />
LOOPE/LOOPZ CX不为零且标志Z=1时循环.<br />
LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.<br />
JCXZ CX为零时转移.<br />
JECXZ ECX为零时转移.<br />
4&gt;中断指令<br />
INT 中断指令<br />
INTO 溢出中断<br />
IRET 中断返回<br />
5&gt;处理器控制指令<br />
HLT 处理器暂停, 直到出现中断或复位信号才继续.<br />
WAIT 当芯片引线TEST为高电平时使CPU进入等待状态.<br />
ESC 转换到外处理器.<br />
LOCK 封锁总线.<br />
NOP 空操作.<br />
STC 置进位标志位.<br />
CLC 清进位标志位.<br />
CMC 进位标志取反.<br />
STD 置方向标志位.<br />
CLD 清方向标志位.<br />
STI 置中断允许位.<br />
CLI 清中断允许位.<br />
<br />
<strong>六、伪指令</strong><br />
─────────────────────────────────────<br />
DW 定义字(2字节).<br />
PROC 定义过程.<br />
ENDP 过程结束.<br />
SEGMENT 定义段.<br />
ASSUME 建立段寄存器寻址.<br />
ENDS 段结束.<br />
END 程序结束.</p>
<p>&nbsp;</p>
<p>学习地址：<a href="http://www2.zzu.edu.cn/qwfw/hbyycai/courses/step.asp?id=8" rel="nofollow" target="_blank">http://www2.zzu.edu.cn/qwfw/hbyycai/courses/step.asp?id=8</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=258</link>
			<title><![CDATA[俄罗斯方块EasyTetris人工智能AI挑战赛]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Fri,26 Jun 2009 09:43:30 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=258</guid>
		<description><![CDATA[<p>针对之前编写的JavaScript版俄罗斯方块游戏EasyTetris展开的人工智能AI挑战赛，欢迎大家踊跃尝试！ <br />
<br />
<a target="_blank" title="Easy Tetris正在举办人工智能AI大赛页面： br / http://www.v-ec.com/games/tetris/ai.htm" href="http://www.v-ec.com/games/tetris/ai.htm">Easy Tetris正在举办人工智能AI大赛页面： <br />
http://www.v-ec.com/games/tetris/ai.htm</a> <br />
<br />
请先熟悉Easy Tetris实现代码，我们给出了一些可能有用的游戏实例属性和方法，当然，如果不够用的话，可以查看源代码看所有的部分！ <br />
<br />
在大家动手之前，可以先看看已有的AI算法，并运行查看结果！ <br />
<br />
本次大赛没有奖品（至少现在没有^_^），旨在增加大家编程的乐趣，我们会在一周后开通提交算法功能，您编写好的算法就可以提交上去以供其他人学习和&ldquo;敬仰&rdquo;！ ^_^ <br />
<br />
再次邀请大家踊跃参与！</p>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=257</link>
			<title><![CDATA[JavaScript版俄罗斯方块Easy Tetris实现原理]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Sun,21 Jun 2009 21:58:18 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=257</guid>
		<description><![CDATA[<h1>最近心血来潮加上有点闲情，动手写了第一个JavaScript版的俄罗斯方块Easy Tetris.</h1>
<p>先上Easy Tetris俄罗斯方块游戏截图：</p>
<p><img src="http://www.w3cgroup.com/attachments/month_0906/i2009621214419.jpg" alt="" /></p>
<p>由于某些人有cheat情节，加上了一个投影功能：^_^</p>
<p><img src="http://www.w3cgroup.com/attachments/month_0906/l2009621214743.jpg" alt="" /></p>
<p>由于非IE浏览器的功能键屏蔽无法完美实现，在游戏页面中的&ldquo;清爽页面&rdquo;用来隐藏非游戏区域的其他页面模块以清除页面滚动条，之后可以通过&ldquo;展开页面&rdquo;重新展开隐藏的页面。</p>
<p>经过一些测试发现，在某些系统下的非IE浏览器中运行Easy Tetris时，左右移动有粘滞感，有兴趣的朋友可以一起讨论下优化。</p>
<h1>Easy Tetris实现核心部分</h1>
<h2>下一个方块</h2>
<p>原型为一个4*4的表格加上方块展示方法，可以通过分别继承两个类（表格类，方块类），加上自身的next方法，来实现。</p>
<h2>游戏区域</h2>
<p>原型为一个12*20的表格，由于考虑到算法优化，直接设置为（4+12+4）*（4+20+4）的表格，该表格同时具有一个与表格中格子数相同的二维数组，用作方块的边界检测</p>
<h2>游戏填色区域</h2>
<p>原型为一个12*20的表格，由于考虑到算法优化，直接设置为（4+12+4）*（4+20+4）的表格，方块停止下落后，在对应的行和列中填上与下落方块相同的颜色。</p>
<p>当在&ldquo;游戏区域&rdquo;的二维数组中检测到行被填满，则删除填色区域相应的行，同时，在首行前插入相应数量的新行。</p>
<h2>游戏方块</h2>
<p>原型为一个4*4的表格加上方块展示方法，可以通过分别继承两个类（表格类，方块类）并且加上自身的一些方法来实现，此组件为俄罗斯方块中的重要组件，在Easy Tetris的实现中，该组件担当了大部分的游戏任务，移动，变形，边界检测等等，游戏中多数的方法都被安排在此组件上实现。</p>
<h2>方块形状及变形</h2>
<p>方块及形状的实现可以通过一个4*4的二维数组来实现，比如方块Z，我们可以写为：</p>
<p>[<br />
[1,1,0,0]<br />
[0,1,1,0]<br />
[0,0,0,0]<br />
[0,0,0,0]<br />
]</p>
<p>1，表示这个位置是一个方块，0表示什么都没有，是不是很简单？由于这种写法会造成数据量的增大，我们可以将此数据形式压缩为16进制形式，还是以Z为例。</p>
<p>1100011000000000 -&gt; 转为16进制 -&gt; 0xc600，于是上面的数组可以简写为：</p>
<p>[0xc600]</p>
<p>数据量大大缩减，然后在程序中需要有一个反转的过程，将此16进制数据转换到2进制数据，需要注意的是，你可能会发现一些16进制的数据转换到2进制后不够如上面数组中的16个元素，你需要在转换后的2进制数据前补足相应个数的 0。</p>
<h2>变形部分相对简单，如，Z的变形为：</h2>
<p>[<br />
[0,0,1,0]<br />
[0,1,1,0]<br />
[0,1,0,0]<br />
[0,0,0,0]<br />
]</p>
<p>只要将此形状同时保存到方块数组中即可，由于所有方块中，最多变形次数为4次，所以，所有方块都4个一组的来表示，每一个维度表示每一次形变后的形状，在变形方法中只要通过这个索引值来进行递增即可获得下一次形变的样子，然后重新渲染出来即可。</p>
<h2>投影部分</h2>
<p>需要一个和方块部分一一对应的数组，记录每个方块的投影区域，还是以Z为例，它可以表示为：</p>
<p>[1,1,1,0,1,1,0,0]</p>
<p>前4位 1,1,1,0 表示，在一个4列的格子中，Z，前面3个格子是要进行投影的</p>
<p>后4位 1,1,0,0 表示，投影跟随下落方块的时候，Y坐标在下落方块下面第1个位置（1的个数-1）</p>
<p>投影部分除了需要一个对应的数据外，还需要一个DOM元素进行表示，很简单，就是一个1*4的表格，它需要在下落方块移动、变形的时候做相应的处理。</p>
<h2>边界检测</h2>
<p>边界检测应该是俄罗斯方块中最重要的算法部分了。在Easy Tetris中采用的是&ldquo;位与&rdquo;判断的方法进行处理，即，将下落的方块4*4个区域与即将落在的游戏区域中相应的4*4个区域进行&ldquo;位与&rdquo;比较，如果返回0，则说明可以移动，否则，不能移动。</p>
<p>下落的方块每调用一次&ldquo;移动&rdquo;的方法之前，都要进行边界检测；</p>
<p>下落的方块每调用一次&ldquo;变形&ldquo;的方法之前，也要进行边界检测；</p>
<p>所以，如果你能够足够的优化移动、变形、边界检测这三部分的算法，那么你的俄罗斯方块将会给玩家一个非常高的控制灵敏度，从而大大提高可玩性！</p>
<p>&nbsp;</p>
<p>好了，在WEB中用JavaScript编写俄罗斯方块的大体原理就是这样了，下面，我们一起来玩玩这个写好的俄罗斯方块游戏Easy Tetris吧：</p>
<h2><a href="http://www.v-ec.com/games/tetris/" target="_blank" title="JavaScript俄罗斯游戏EasyTetris">http://www.v-ec.com/games/tetris/</a></h2>]]></description>
		</item>
		
			<item>
			<link>http://www.v-ec.com/dh20156/article.asp?id=256</link>
			<title><![CDATA[EasyUI更新-添加toJSON及domEvent方法]]></title>
			<author>dh20156@126.com(dh20156)</author>
			<category><![CDATA[Web Develop]]></category>
			<pubDate>Wed,10 Jun 2009 11:07:37 +0800</pubDate>
			<guid>http://www.v-ec.com/dh20156/default.asp?id=256</guid>
		<description><![CDATA[<p>EasyUI更新列表：</p>
<p>添加方法：<strong>easyUI.toJSON(obj)</strong></p>
<p>&nbsp;</p>
<dl><dd>将JavaScript对象转换为JSON字符串<br />
<br />
</dd><dd>参数：obj javascript对象<br />
<br />
</dd><dd>返回值：JSON格式字符串</dd></dl>
<p>&nbsp;</p>
<p>添加方法：<strong>easyUI.domEvent()</strong></p>
<dl><dd>为DOM节点或[object HTMLCollection]对象添加安全的事件绑定和解除的方法<br />
<br />
</dd><dd>参数：无<br />
<br />
</dd><dd>返回值：无<br />
<br />
</dd><dd>用法：easyUI.easyDomEvent.call(DOM节点或[object HTMLCollection]对象)<br />
<br />
</dd><dd>方法：DOM节点或[object HTMLCollection]对象.bindEvent(事件类型如'click'，前面不要写'on', 绑定的函数, capture)<br />
<br />
</dd><dd>方法：DOM节点或[object HTMLCollection]对象.removeEvent(事件类型如'click'，前面不要写'on', 绑定的函数, capture)<br />
<br />
</dd><dd>属性：DOM节点或[object HTMLCollection]对象.eventList Object，包含绑定的事件对应的函数列表，如：对象.eventList['click']可获取该对象click事件绑定的函数列表</dd></dl>
<p>&nbsp;</p>
<p><a href="http://www.easyui.org.cn" target="_blank">EasyUI API及最新版本下载：http://www.easyui.org.cn</a></p>
<p>更新时间：2009-6-10</p>]]></description>
		</item>
		
</channel>
</rss>
