<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_一棵树</title><subtitle type="text">C#,ASP.NET技术学习交流分享的博客。一棵树-守护一片绿</subtitle><id>http://feed.cnblogs.com/blog/u/68878/rss</id><updated>2012-03-19T09:03:05Z</updated><author><name>zock</name><uri>http://www.cnblogs.com/ATree/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ATree/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/68878/rss"/><entry><id>http://www.cnblogs.com/ATree/archive/2012/03/13/HTML5-Storage-API.html</id><title type="text">HTML5 存储API介绍（收集）</title><summary type="text">HTML5的最有趣的功能之一是本地存储数据并且允许应用程序离线运行的功能。 共有三种不同的处理这些功能的API，如何选中其中之一取决于你希望对你将要本地存储的数据进行怎样处理：Web 存储：适用于具有 key/value对的基本本地存储离线存储：利用一个 manifest文件来高速缓存所有文件以便离线使用Web 数据库：适用于关系型数据库存储</summary><published>2012-03-13T14:30:00Z</published><updated>2012-03-13T14:30:00Z</updated><author><name>zock</name><uri>http://www.cnblogs.com/ATree/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ATree/archive/2012/03/13/HTML5-Storage-API.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ATree/archive/2012/03/13/HTML5-Storage-API.html"/><content type="html">&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;HTML5的最有趣的功能之一是本地存储数据并且允许应用程序离线运行的功能。 共有三种不同的处理这些功能的API，如何选中其中之一取决于你希望对你将要本地存储的数据进行怎样处理：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Web 存储&lt;/strong&gt;：适用于具有 key/value对的基本本地存储&lt;/li&gt;&lt;li&gt;&lt;strong&gt;离线存储&lt;/strong&gt;：利用一个 manifest文件来高速缓存所有文件以便离线使用&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Web 数据库&lt;/strong&gt;：适用于关系型数据库存储&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div id="content_atree"&gt;&lt;em&gt;如果你看到这段文字，说明您正使用RSS阅读或转自《一棵树-博客园》，原文地址：&lt;a id="Editor_Edit_hlEntryLink" title="view: HTML5 存储API介绍" href="http://www.cnblogs.com/ATree/archive/2012/03/12/HTML5-Storage-API.html" target="_blank"&gt;http://www.cnblogs.com/ATree/archive/2012/03/12/HTML5-Storage-API.html&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="parbase compbase numberedheader section"&gt;&lt;h3 class="TextH3 LayoutCellSides LayoutRow"&gt;Web存储API&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;在用户的机器上进行本地存储的最基本的实现方法是利用web存储API。 该API使用 &lt;strong&gt;key/value&lt;/strong&gt; 对来支持开发人员存储能够被&lt;strong&gt; web &lt;/strong&gt;应用程序访问的基本信息和变量。 该功能的一个理想用例是用于存储那些在用户已经浏览完并且离开应用程序或已经关闭 web 浏览器之后需要永久保留的简单数据。 例如，保存游戏状态、保存导航位置或存储你希望在整个 web 应用程序中使用但你不希望使用 cookie 的一些特定信息（例如用户名称或姓名）。 类似的 API 还可以用于为个体会话存储数据。 这些数据将在用户浏览完离开应用程序或关闭浏览器之后自动清除。&lt;/p&gt;&lt;p&gt;当使用&lt;strong&gt; web&lt;/strong&gt; 存储&lt;strong&gt; API&lt;/strong&gt; 时，你需要记住下列事项：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;该存储操作只能适用于相关的域（domain-wide），因此当使用web存储功能保存数据时，只有在该域上的其它网站才能访问这些数据。&lt;/li&gt;&lt;li&gt;存储数据的大小限制是大约5M字节。 5M字节的限制是由&lt;a href="http://dev.w3.org/html5/webstorage/#disk-space" target="_blank"&gt; W3C建议的&lt;/a&gt;，但该规范提供了实现细节的一些保留空间，因此，实际的字节大小取决于每个浏览器厂商。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;核查浏览器支持功能&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在使用web存储API之前需要做的第一件事情是核查用户的浏览器是否支持这一API：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; checkLocalStorageSupport() {&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt; {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; 'localStorage' &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; window &amp;amp;&amp;amp; window['localStorage'] !== &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt; (e) {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;    } &lt;br /&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;你也许在上面的代码片段中明显地看出，web存储使用一个名称为&lt;code&gt;localStorage &lt;/code&gt;的对象，它是一个windowclass对象。 上面的代码片段能够核查&lt;code&gt;localStorage&lt;/code&gt; 实际上是否是一个基于 window的对象，以及它能否返回true，以便应用程序能够充分利用本地存储API。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;添加和返回数据&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;从&lt;code&gt;localStorage&lt;/code&gt;对象中添加和返回数据与调用由本地存储规范实现的getter和 setter方法一样简单。 使用&lt;code&gt;localStorage &lt;/code&gt;可以存储任何类型的数据，但所有的数据必须以字符串的格式存储于相应的存储区域。 这意味着在将数据发送到&lt;code&gt;localStorage&lt;/code&gt; 之前或在使用它们之后有必要对它们进行解析。 例如，为了存储一个 JavaScript 对象，必须使用JSON 并且在检索数据之前调用 &lt;code&gt;stringify()&lt;/code&gt; 而在检索数据之后调用&lt;code&gt;parse()&lt;/code&gt;。 在从l&lt;code&gt;ocalStorage&lt;/code&gt; 对象中检索到数值变量之后，对它们进行解析也是如此。&lt;/p&gt;&lt;p&gt;在本范例中，已经建立一个单一的表单输入，这样，当用户点击Submit时，相应的数据将存储到本地高速缓存区域。 当加载页面时，如果数据已经存储，则页面将通过一个欢迎窗口显示已存储的信息。 下面是当用户点击 Submit时调用的函数：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; onClick() {&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (checkLocalStorageSupport) {&lt;br /&gt;        window.localStorage.setItem("name", document.getElementById("name").value);&lt;br /&gt;    } &lt;br /&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;该函数使用&lt;code&gt;localStorage&lt;/code&gt;对象中的&lt;code&gt; setItem &lt;/code&gt;方法，然后使用相应表单中的值来填充存储高速缓存区。 当加载页面时，应用程序利用一个&lt;code&gt; onLoad &lt;/code&gt;函数来核查相应的数据是否已经位于本地高速缓存区中并且将添加一个欢迎窗口。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="parbase codeblock compbase section"&gt;&lt;div class="PanelFillLight PanelBevelTop LayoutCell LayoutRow"&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; onLoad() {&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (checkLocalStorageSupport) {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; name = window.localStorage.getItem("name");&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (name != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;) {&lt;br /&gt;            window.document.getElementById("divName").innerHTML = "Welcome back " + name;&lt;br /&gt;        } &lt;br /&gt;    } &lt;br /&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;&lt;strong&gt;清除数据&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;尽管用户能够使用浏览器在任何时间删除&lt;code&gt;localStorage &lt;/code&gt;数据，但为他们提供从应用程序自身删除数据的选项也是合理的。&lt;code&gt;localStorage&lt;/code&gt; 提供一个正好能够实现这一目的 &lt;code&gt;clear()&lt;/code&gt;方法。 当用户在你的应用程序中点击一个复位按钮时，将触发下面代码。 如果你希望从存储区中移除一个特定条目，则你可以使用&lt;code&gt;removeItem()&lt;/code&gt; 方法从本地存储区中删除一个单一key。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; onReset() {&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (checkLocalStorageSupport()) {&lt;br /&gt;        window.localStorage.clear();&lt;br /&gt;    } &lt;br /&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="parbase codeblock compbase section"&gt;&lt;div class="PanelFillLight PanelBevelTop LayoutCell LayoutRow"&gt;&lt;strong&gt;处理变更&lt;/strong&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;Web存储 API 还包含一种侦听和响应任何本地存储变更的方法。 通过添加一个事件侦听程序以及侦听一个&lt;code&gt;storage &lt;/code&gt;事件，应用程序能够对&lt;code&gt;localStorage&lt;/code&gt;变更进行响应。 事件中的数据包含已更改的key的名称、新值、老值（如果有的话）以及调用该API的页面的URL。 可以利用下面的方式实现localStorage API的规范要求，即发起事件的会话将不能看到该事件的触发。 这是因为规范要求该事件只能针对其它、而不是更改存储的标签或会话进行触发。&lt;/p&gt;&lt;p&gt;为了侦听存储事件，首先需要做的事情是添加事件侦听程序：&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="parbase codeblock compbase section"&gt;&lt;div class="PanelFillLight PanelBevelTop LayoutCell LayoutRow"&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;window.addEventListener("storage",onStorageChange);&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;然后建立&lt;code&gt; onStorageChange&lt;/code&gt; 事件来处理存储事件。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="parbase codeblock compbase section"&gt;&lt;div class="PanelFillLight PanelBevelTop LayoutCell LayoutRow"&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; onStorageChange(e) {&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (e.key == "name") {&lt;br /&gt;        alert(e.newValue + ' just added their name to local storage');&lt;br /&gt;    } &lt;br /&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;另外，有一个创建数据的类似API，它只对个体会话持续有效。 通过使用&lt;code&gt;sessionStorage &lt;/code&gt;对象，而不是&lt;code&gt;localStorage&lt;/code&gt;对象，当用户离开页面时，任何保存的数据将被自动清除。 事实上，API 具有完全相同的方法，因此你可以仔细检查并且利用&lt;code&gt;sessionStorage&lt;/code&gt;替换&lt;code&gt;localStorage&lt;/code&gt;，然后本地数据将被保存直到用户关闭他们的浏览器或其中包含应用程序的标签。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a name="articlecontentAdobe_numberedheader_0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="parbase compbase numberedheader section"&gt;&lt;h3 class="TextH3 LayoutCellSides LayoutRow"&gt;离线存储&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;a name="articlecontentAdobe_text_7"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;有时在用户的机器中仅仅存储一些数据是不能满足要求的。 在许多情形下，整个应用程序必须离线运行，而不仅仅存储一些数据。 对于这种使用情形，HTML5 包含了在用户机器上高速缓存文件和资源的功能，以便浏览器在没有因特网连接的情形下访问它们。 这意味着构成web应用程序的图像、JavaScript 文件、 HTML 文件、 CSS文件等大量数据能够本地存储，甚至在没有因特网连接的情形下能够对它们进行访问。 这一功能的关键是建立一个高速缓存的Manifest文件。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;使用 manifest文件&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Manifest文件是页面的根 HTML标签的新&lt;code&gt;manifest&lt;/code&gt; 属性的一个组成部分。 它是一个位于web服务器上的文件，它能够列出浏览器应该下载和保存以便以后使用的所有文件。 它具有一个 .manifest 扩展名并且其唯一主要的gotcha 是相应的web 服务器必须支持 .manifest mime类型，因此，应该确保驻留应用程序的该 web 服务器能够正确提供.manifest 文件。&lt;/p&gt;&lt;p&gt;Manifest文件具有一个基本架构。 每个manifest 文件以 &lt;code&gt;CACHE MANIFEST &lt;/code&gt;开头，并且从这里开始，列出所有浏览器需要高速缓存的、用于离线访问的文件。 下面是一个简单范例，它能够存储一些JavaScript、一个 CSS 文件、一些图像和 相应的HTML页面：&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a name="articlecontentAdobe_codeblock_5"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="parbase codeblock compbase section"&gt;&lt;div class="PanelFillLight PanelBevelTop LayoutCell LayoutRow"&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;CACHE MANIFEST style.css offlinescript.js images/dreamweaver_logo.png images/edge_logo.png&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;相应的路径均与用户正在访问的HTML页面相关。 当创建高速缓存manifest文件时，你必须了解一些其它选项。 其中一个选项是绝不能高速缓存的文件的情形。 也许只有能够在线获得的动态脚本或某些内容才是有意义的。 高速缓存manifest文件能够划分为告知浏览器如何对某些内容进行响应的区段（section）。 通过创建一个&lt;code&gt; NETWORK&lt;/code&gt;和列出那些绝不能高速缓存的文件，浏览器一定能够忽略这些文件并且让人们决不能离线获得它们。&lt;/p&gt;&lt;p&gt;另一个情形是当用户试图访问一个没有高速缓存的页面或某些应该高速缓存但却没有正确保存的内容时的情形。 高速缓存 manifest API 能够提供一个&lt;code&gt;FALLBACK&lt;/code&gt; 区段（section），它指向一个在上述用例中加载的页面。 因此，当用户试图访问没有保存的某些内容时，他们将看到一条关于离线提示的消息。 下面是一个理论上的包含这些区段（section）的高速缓存Manifest文件的大概架构：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;CACHE MANIFEST NETWORK: my_dynamic_script.cgi FALLBACK: my_offline_message.html CACHE: style.css offlinescript.js images/dreamweaver_logo.png images/edge_logo.png&lt;/div&gt;&lt;p&gt;在本例中，我提供了一个带有一个外部JavaScript 页面和外部 CSS页面的HTML页面。 该HTML页面能够显示一些描述一个Adobe徽标的文本，并且当你点击相应的图像时，JavaScript 将会为另一个徽标换出相应的图像和文本。 下面是相应的HTML代码，紧跟其后的是JavaScript函数：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #ff00ff;"&gt;DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;html &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;xmlns&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="http://www.w3.org/1999/xhtml"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; manifest&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="cache.manifest"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;meta &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;http-equiv&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="Content-Type"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; content&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="text/html; charset=UTF-8"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;Adobe Logos&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;script &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;src&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="offlinescript.js"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;link &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;href&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="style.css"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; rel&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="stylesheet"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="textContent"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        This is the Edge logo:&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;br &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;img &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="logo"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; name&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="logo"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; src&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="images/edge_logo.png"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; onclick&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="onLogoClick();"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;p &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="small"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        Click on the logo to swap it out.&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;p&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;&amp;lt;!--&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;//JavaScript Document &lt;br /&gt;function onLogoClick(e) {&lt;br /&gt;    var currentContent = window.document.getElementById("textContent").innerHTML;&lt;br /&gt;    if (currentContent == "This is the Edge logo:") {&lt;br /&gt;        window.document.getElementById("textContent").innerHTML = "This is the Dreamweaver logo:";&lt;br /&gt;        window.document.logo.src = "images/dreamweaver_logo.png";&lt;br /&gt;    }&lt;br /&gt;    else {&lt;br /&gt;        window.document.getElementById("textContent").innerHTML = "This is theEdge logo:"; window.document.logo.src = "images/edge_logo.png";&lt;br /&gt;    } &lt;br /&gt;}&lt;/span&gt;&lt;span style="color: #008000;"&gt;--&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;所有这些代码的关键部分是带有&lt;code&gt; manifest&lt;/code&gt; 属性的HTML标签。 它是指向我在上面引用的我的cache.manifest 文件。 该manifest文件能够指示浏览器下载列表中给出的所有文件。 不管用户在浏览这些文件时是否下载它们，相应的浏览器将自动下载manifest文件中包含的所有文件。 这意味着两个图像都将被保存以便离线访问，即使第二个图像直到我与相应内容互动时才加载到页面。 因此，只需加载该页面一次，我即可以在离线情形下完全与它进行互动，并且两个图像均会旋转。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;&lt;strong&gt;了解事件&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;需要略微提到的、但却是非常重要的离线访问的最后部分是发生在高速缓存过程中的事件。 当浏览器遇到 manifest 属性，它将在window.applicationCache 对象中触发一系列事件。 第一个发生的事件是触发一个checking事件。 该事件可以确定需要利用这一特别的高速缓存文件进行哪些操作。 Google Chrome 开发人员工具可以在高速缓存区保存数据时能够全面地核查发生的事件（参见图1）。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a name="articlecontentAdobe_image"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="parbase image section"&gt;&lt;img class="cq-dd-image LayoutRow LayoutImage LayoutCellSides" title="在高速缓存区保存数据时发生的事件 " src="http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/html5/articles/html5-storage-apis/fig01.jpg" alt="在高速缓存区保存数据时发生的事件 " /&gt;&lt;div class="TextSmall LayoutCellSides LayoutRowTop LayoutBigRowBottom"&gt;图 1. 在高速缓存区保存数据时发生的事件&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a name="articlecontentAdobe_text_11"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;如果这是用户第一次访问该网站，则将触发一个下载事件并且相应的web浏览器将仔细查看并且下载manifest文件中包含的所有资源。 它能够读取相应的manifest文件，确定它需要下载多少文件，然后以progress事件的形式为每个文件回送状态更新信息。 Progress 事件包含一个已加载的变量和一个总变量，这样开发人员能够确定高速缓存区已经存储的多少内容。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; onProgress(e) {&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; content = window.document.getElementById("loadedInfo").innerHTML;&lt;br /&gt;    window.document.getElementById("loadedInfo").innerHTML = content + '&amp;lt;br /&amp;gt; Loaded file ' + e.loaded + ' of ' + e.total;&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;当完成所有文件的保存操作时，浏览器将触发一个cached事件通知开发人员所有用于离线使用的文件已经成功保存。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;在后面用户访问页面的任何时刻，浏览器将核查看一看在manifest 文件中是否有内容发生改变。 如果没有，它将触发一个 &lt;code&gt;noupdate &lt;/code&gt;事件，然后继续运行。 如果其中有内容发生改变，则它将经历与上面完全相同的过程；它将触发一个包含一系列&lt;code&gt;progress&lt;/code&gt;事件的&lt;code&gt;downloading &lt;/code&gt;事件，直到相应的文件全部更新完毕。 当该事件发生时，而不是触发一个&lt;code&gt;cached&lt;/code&gt;事件，浏览器将触发一个&lt;code&gt;updateready&lt;/code&gt;事件表示所有的文件已经更新并且可以离线使用。&lt;/p&gt;&lt;p&gt;最后一个令人发愁的事件是&lt;code&gt;error &lt;/code&gt;事件，它将在应用程序出现故障时触发。 这些故障可能是文件不能正确加载，浏览器不能访问cache manifest文件，或manifest列出的一个或多个文件不存在等。 为了捕捉这些故障，只需为&lt;code&gt;error&lt;/code&gt;事件添加一个事件侦听程序。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;window.applicationCache.addEventListener("error", onError); &lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; onError(e) {&lt;br /&gt;    window.document.getElementById("loadedInfo").innerHTML = "Something went wrong while saving the files for offline use."; &lt;br /&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a name="articlecontentAdobe_numberedheader_1"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="parbase compbase numberedheader section"&gt;&lt;h3 class="TextH3 LayoutCellSides LayoutRow"&gt;数据库存储&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;a name="articlecontentAdobe_text_13"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;HTML5引入的最后一个存储类型是目前最处于不断变化之中的类型。 最初有一个&lt;a href="http://www.w3.org/TR/webdatabase/" target="_blank"&gt; Web SQL规范&lt;/a&gt;，但它现在已经不再使用。 现在，大多数人的精力已经转移到&lt;a href="http://www.w3.org/TR/IndexedDB/" target="_blank"&gt;Indexed Database API&lt;/a&gt; 上，并且似乎这将是在关系型数据库中存储信息的出路。 Firefox和 Chrome 均支持IndexedDB，但由于相应的规范和支持功能均处于不断变化之中，所以它超出本文的讨论范围。 在将来某个时候，当这一状态改变时，我将进行相应的更新。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a name="articlecontentAdobe_numberedheader_2"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="parbase compbase numberedheader section"&gt;&lt;h3 class="TextH3 LayoutCellSides LayoutRow"&gt;下一步阅读方向&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;a name="articlecontentAdobe_text_14"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="text parbase section"&gt;&lt;div class="Semantic LayoutCellSides LayoutBreakAfter TextMedium"&gt;&lt;p&gt;在本文中，我探索了两种本地存储信息的主要方法。 第一种方法以web存储API的形式提供一些非常基本的数据存储技术。 利用这一方法，你可以在会话之外或为一个单一会话保存名称值对（name value pair）。 第二种方法，即应用程序cache manifest，允许开发人员在本地机器上保存所有文件，以便可以在离线情形下访问它们。&lt;/p&gt;&lt;p&gt;关于HTML5存储API的更多信息，参见下列资源：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://diveintohtml5.org/storage.html" target="_blank"&gt;Web 应用程序本地存储的过去、现在和未来（The Past, Present, and Future of Local Storage for Web Applications） &lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.html5rocks.com/en/features/storage" target="_blank"&gt;HTML5 Rocks ：本地存储（HTML5 Rocks : Local Storage）&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://drdobbs.com/web-development/225702544" target="_blank"&gt;Dr Dobbs：HTML5 Web 存储（Dr Dobbs : HTML5 Web Storage）&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://dev.w3.org/html5/webstorage/" target="_blank"&gt;文档：W3C草案：Web 存储（ Documentation: W3C Draft: Web Storage）&amp;nbsp;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/ATree/aggbug/2391651.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ATree/archive/2012/03/13/HTML5-Storage-API.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ATree/archive/2012/03/12/JQuery-select-checkbox-text-radio.html</id><title type="text">jQuery基础：select、checkbox、text、radio取值、选中、删除等</title><summary type="text">获取值：下拉框select： 获取value：$('#sel').val(); 获取text:$('#sel').find("option:selected").text()多选框checkbox：$("#checkbox_id").attr("value")；文本框，文本区域：$("#txt").val(); 或 $("#txt").attr("value")；单选组radio： $("input[@type=radio][@checked]").val();</summary><published>2012-03-12T14:42:00Z</published><updated>2012-03-12T14:42:00Z</updated><author><name>zock</name><uri>http://www.cnblogs.com/ATree/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ATree/archive/2012/03/12/JQuery-select-checkbox-text-radio.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ATree/archive/2012/03/12/JQuery-select-checkbox-text-radio.html"/><content type="html">&lt;p&gt;&lt;strong&gt;获取值：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;下拉框select： 获取value：$('#sel').val(); 获取text:$('#sel').find("option:selected").text()&lt;/p&gt;&lt;p&gt;多选框checkbox：$("#checkbox_id").attr("value")；&lt;/p&gt;&lt;p&gt;文本框，文本区域：$("#txt").val(); 或&amp;nbsp;$("#txt").attr("value")；&lt;/p&gt;&lt;p&gt;单选组radio： $("input[type=radio][checked]").val();&lt;/p&gt;&lt;div id="content_atree"&gt;&lt;em&gt;如果你看到这段文字，说明您正使用RSS阅读或转自《一棵树-博客园》，原文地址：&lt;a id="Editor_Edit_hlEntryLink" title="view: jQuery基础：select、checkbox、text、radio取值、选中、删除等" href="http://www.cnblogs.com/ATree/archive/2012/03/07/JQuery-select-checkbox-text-radio.html" target="_blank"&gt;http://www.cnblogs.com/ATree/archive/2012/03/07/JQuery-select-checkbox-text-radio.html&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;选中：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;select下拉框的第二个元素为当前选中值&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;$('#select_id')[0].selectedIndex = 1;&lt;/div&gt;&lt;p&gt;radio单选组的第二个元素为当前选中值&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;$('input[name=items]').get(1).checked = &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;控制表单元素：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;文本框，文本区域：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;$("#txt").attr("value",'');     &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;清空内容&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;$("#txt").attr("value",'11');  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;填充内容&lt;/span&gt;&lt;/div&gt;&lt;p&gt;多选框checkbox：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;$("#chk1").attr("checked",'');&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;不打勾&lt;/span&gt;&lt;br /&gt;$("#chk2").attr("checked",&lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;);&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;打勾&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;($("#chk1").attr('checked')==undefined) &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;判断是否已经打勾&lt;/span&gt;&lt;/div&gt;&lt;p&gt;单选组radio： &amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;$("input[type=radio]").attr("checked",'2');&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置value=2的项目为当前选中项&lt;/span&gt;&lt;/div&gt;&lt;p&gt;下拉框select： &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;$("#sel").attr("value",'-sel3');  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置value=-sel3的项目为当前选中项&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;$("&amp;lt;option value='1'&amp;gt;1111&amp;lt;/option&amp;gt;&amp;lt;option value='2'&amp;gt;2222&amp;lt;/option&amp;gt;").appendTo("#sel")&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;添加下拉框的option&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;$("#sel").empty()；  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;清空下拉框&lt;/span&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/ATree/aggbug/2383351.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ATree/archive/2012/03/12/JQuery-select-checkbox-text-radio.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ATree/archive/2012/03/12/Visual-Studio11-VS11-Page.html</id><title type="text">Visual Studio 11 新界面引发热议</title><summary type="text">微软发布了Visual Studio 11 beta。新版本的Visual Studio不仅拥有一个全新的基于灰度调色板的用户界面，还对工具栏图标进行了重新设计。新版界面一出，迅速引发了激烈的讨论。微软开发工具事业部用户体验总监Monty Hammontree在博客里发布了两篇介绍新版本开发体验的文章，见这里和这里。新版VS11的样式与VS2010相比相似度很小，它既包含了Windows 8的Metro界面元素，也融入了微软Office Ribbon工具栏风格。Hammontree解释说，他的团队认为影响开发人员效率的问题主要有三个：过于繁多的工具；代码库较为复杂时，较难理解和定位较为困难；当文件数量很多时，不易处理。</summary><published>2012-03-12T05:12:00Z</published><updated>2012-03-12T05:12:00Z</updated><author><name>zock</name><uri>http://www.cnblogs.com/ATree/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ATree/archive/2012/03/12/Visual-Studio11-VS11-Page.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ATree/archive/2012/03/12/Visual-Studio11-VS11-Page.html"/><content type="html">&lt;p&gt;微软发布了Visual Studio 11 beta。新版本的Visual Studio不仅拥有一个全新的基于灰度调色板的用户界面，还对工具栏图标进行了重新设计。新版界面一出，迅速引发了激烈的讨论。&lt;/p&gt;&lt;div id="content_atree"&gt;&lt;em&gt;如果你看到这段文字，说明您正使用RSS阅读或转自《一棵树-博客园》，原文地址：&lt;a id="Editor_Edit_hlEntryLink" title="view: Visual Studio 11 新界面引发热议" href="http://www.cnblogs.com/ATree/archive/2012/03/12/Visual-Studio11-VS11-Page.html" target="_blank"&gt;http://www.cnblogs.com/ATree/archive/2012/03/12/Visual-Studio11-VS11-Page.html&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="http://www.infoq.com/resource/news/2012/02/vs11goesgrey/en/resources/screenshot_VS11BetaNewUI_web.jpg" alt="Visual Studio 11's new User Interface" width="600" /&gt;&lt;/p&gt;&lt;p&gt;微软开发工具事业部用户体验总监Monty Hammontree在博客里发布了两篇介绍新版本开发体验的文章，见&lt;a href="http://blogs.msdn.com/b/visualstudio/archive/2012/02/23/introducing-the-new-developer-experience.aspx"&gt;这里&lt;/a&gt;和&lt;a href="http://blogs.msdn.com/b/visualstudio/archive/2012/02/24/introducing-the-new-developer-experience-part2.aspx"&gt;这里&lt;/a&gt;。新版VS11的样式与VS2010相比相似度很小，它既包含了Windows 8的Metro界面元素，也融入了微软Office Ribbon工具栏风格。Hammontree解释说，他的团队认为影响开发人员效率的问题主要有三个：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;过于繁多的工具；&lt;/li&gt;&lt;li&gt;代码库较为复杂时，较难理解和定位较为困难；&lt;/li&gt;&lt;li&gt;当文件数量很多时，不易处理。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;这些问题并不是凭空想象，它们是建立于微软内部和微软外部的研究成果之上。有意思的是，Hammontre还引用了某篇研究&lt;a href="http://academic.research.microsoft.com/Paper/4416874.aspx?viewType=1"&gt;论文&lt;/a&gt;中的Elicpse例子来解释他的团队正在试图解决的问题。虽然调色板和图形界面设计的改动只是他们团队设计方案中的一部分，但这一部分却又是开发社区中最引发争议的话题。Hammontree解释说他们之所以减少色彩，其背后用意在于：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;随着开发人员目光转向Metro风格的客户端，如Xbox、Windows Phone7和Windows8，将应用程序内容颜色至于中央变得越来越重要。当开发人员在上述平台设立用户体验时，会用到更醒目、更有活力的颜色。而将这些颜色放在一个单色工具设置中，会显得更加有效。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;尽管新界面背后有研究支持，而且Hammontree也进行了一番善意的解释，但是开发人员还是纷纷表达了他们个人对此次变动的看法。到目前为止，Visual Studio博客上有超过700名的开发人员参与了该话题的讨论。另外，在微软的用户心声网站上，我们也能看到一个关于Visual Studio色彩改动的&lt;a href="http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2623017-add-some-color-to-visual-studio-11-beta"&gt;投票话题&lt;/a&gt;，目前当前该话题热度排名第一。&lt;/p&gt;&lt;p&gt;微软号召开发人员继续提供反馈，并声明他们会阅读所有的留言，不论留言内容是褒扬还是批评。&lt;/p&gt;&lt;p&gt;面对新版VS11界面，您又是怎样的看法呢？请在评论中留言。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ATree/aggbug/2391621.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ATree/archive/2012/03/12/Visual-Studio11-VS11-Page.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ATree/archive/2012/03/07/HTML5-Web-Messaging.html</id><title type="text">HTML5 web通信（跨文档通信/通道通信）简介</title><summary type="text">web通信（洋名：web messaging）是一种文档中独立的浏览上下文间的DOM不会被恶意的跨域脚本暴露数据分享方式。得得得，术语啊什么的，比看到凤姐还头疼。有必要把上面一句话拆开讲：web通信是一种数据分享方式（有屁话之嫌）；通信的主体是“浏览上下文”（这是纳尼？）；哦，“浏览上下文”呢是“一个将 Document 对象呈现给用户的环境”，你可以近似理解为平常我们看到的某个页面所处的环境；web通信不会有DOM被恶意暴露的危险；目前应用比较多的就是iframe之间的通信（这是我自个儿额外加的）。</summary><published>2012-03-07T05:45:00Z</published><updated>2012-03-07T05:45:00Z</updated><author><name>zock</name><uri>http://www.cnblogs.com/ATree/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ATree/archive/2012/03/07/HTML5-Web-Messaging.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ATree/archive/2012/03/07/HTML5-Web-Messaging.html"/><content type="html">&lt;p&gt;&lt;strong&gt;一、简单概要&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;web通信（洋名：web messaging）是一种文档中独立的浏览上下文间的DOM不会被恶意的跨域脚本暴露数据分享方式。&lt;/p&gt;&lt;p&gt;得得得，术语啊什么的，比看到凤姐还头疼。有必要把上面一句话拆开讲：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;web通信是一种数据分享方式（有屁话之嫌）；&lt;/li&gt;&lt;li&gt;通信的主体是&amp;ldquo;浏览上下文&amp;rdquo;（这是纳尼？）；&lt;/li&gt;&lt;li&gt;哦，&amp;ldquo;浏览上下文&amp;rdquo;呢是&amp;ldquo;一个将&amp;nbsp;&lt;a href="http://www.w3.org/html/ig/zh/wiki/HTML5/infrastructure#document"&gt;Document&amp;nbsp;&lt;/a&gt;对象呈现给用户的环境&amp;rdquo;，你可以近似理解为平常我们看到的某个页面所处的环境；&lt;/li&gt;&lt;li&gt;web通信不会有DOM被恶意暴露的危险；&lt;/li&gt;&lt;li&gt;目前应用比较多的就是iframe之间的通信（这是我自个儿额外加的&lt;img title="挤眼" src="http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/c3/zy_thumb.gif" alt="挤眼" /&gt;）。&lt;/li&gt;&lt;/ul&gt;&lt;div id="content_atree"&gt;&lt;em&gt;如果你看到这段文字，说明您正使用RSS阅读或转自《一棵树-博客园》，原文地址：&lt;a id="Editor_Edit_hlEntryLink" title="view: HTML5 web通信（跨文档通信/通道通信）简介" href="http://www.cnblogs.com/ATree/archive/2012/03/07/HTML5-Web-Messaging.html" target="_blank"&gt;http://www.cnblogs.com/ATree/archive/2012/03/07/HTML5-Web-Messaging.html&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;&lt;p&gt;当我们谈论web通信的时候，实际上谈论的是两个略有不同的系统：&lt;strong&gt;跨文档通信(cross-document messaging)&lt;/strong&gt;和&lt;strong&gt;通道通信(channel messaging)&lt;/strong&gt;。跨文档通信就是我们国内更为熟知的HTML5 window.postMessage()应用的那种通信；通道通信也被称为&amp;rdquo;MessageChannel&amp;rdquo;. 伴随着server-sent事件以及&lt;a href="http://dev.opera.com/articles/tags/web%20sockets"&gt;web sockets&lt;/a&gt;, 跨文档通信和通道通信成为HTML5 通信接口&amp;ldquo;套件&amp;rdquo;中有用的一部分。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;浏览器支持(至2012-02-27)&lt;/strong&gt;&lt;br /&gt;web通信已经被Opera, Chrome, Safari支持，尽管Safari&amp;le; 5.1.2的版本&lt;a href="https://bugs.webkit.org/show_bug.cgi?id=63141"&gt;有bug&lt;/a&gt;. IE8 部分支持跨文档通信：只能和iframe通信，不支持新窗口通信。IE10 将支持通道通信。FireFox目前支持跨文档信息，但是并不支持通道通信。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;二、通信事件&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这里要先介绍下&lt;code&gt;message&lt;/code&gt;事件对象。为何？&lt;/p&gt;&lt;p&gt;因为，无论是跨文档通信(cross-document messaging)、通道通信(channel messaging)、服务器发送事件(server-sent events)或是网络套接字(web sockets)都要执行&lt;code&gt;message&lt;/code&gt;事件。因此理解之时很有帮助滴。就像是你无论要娶志林姐还是&amp;ldquo;风叉变人&amp;rdquo;姐，都要过你妈这关，因此，了解你妈的偏好就很有帮助啦！&lt;/p&gt;&lt;p&gt;Message事件的定义可参见&lt;a href="http://dev.w3.org/html5/postmsg/#event-definitions"&gt;这里&lt;/a&gt;（此链接建议不用点，英文+术语&amp;rarr;大头儿子），该事件包含5个只读属性：&lt;/p&gt;&lt;table class="params_table" style="width: 100%;" border="0" cellspacing="1" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th scope="row"&gt;data&lt;/th&gt;&lt;td&gt;包含任意字符串数据，由原始脚本发送&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope="row"&gt;origin&lt;/th&gt;&lt;td&gt;一个字符串，包含原始文档的方案、域名以及端口(如：http://domain.example:80)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope="row"&gt;lastEventId&lt;/th&gt;&lt;td&gt;一个字符串，包含了当前的消息事件的唯一标识符。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope="row"&gt;source&lt;/th&gt;&lt;td&gt;原始文件的窗口的引用。更确切地说，它是一个&lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#windowproxy"&gt;WindowProxy对象&lt;/a&gt;。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope="row"&gt;ports&lt;/th&gt;&lt;td&gt;一个数组，包含任何&lt;a href="http://dev.w3.org/html5/postmsg/#messageport"&gt;MessagePort&lt;/a&gt;对象发送消息。&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;在跨文档通信和通道通信中，&lt;code&gt;lastEventId&lt;/code&gt;的值一般是个空字符串；&lt;code&gt;lastEventId&lt;/code&gt;应用在服务器端发送事件上。发送信息中如果没有ports, 则&lt;code&gt;ports&lt;/code&gt;属性值就是个长度为0的数组。&lt;/p&gt;&lt;p&gt;&lt;code&gt;MessageEvent&lt;/code&gt;继承DOM&lt;a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-event"&gt;事件接口&lt;/a&gt;，且属性共享。然而，通信事件并没有冒泡，不能取消，也没有默认行为。&lt;img title="冒泡" src="http://image.zhangxinxu.com/image/blog/201202/maopao.gif" alt="" width="36" height="36" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;三、跨文档通信&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;跨文档通信的使用跟我们平时实际生活中的邮件接收等类似。发送&amp;rarr;接收。&lt;/p&gt;&lt;p&gt;文字化的描述不利于理解。所以，先从一个例子开始吧。&lt;/p&gt;&lt;p&gt;例子很简单，页面上两个iframe框架，左侧的可以输入信息，点击确认按钮后，输入的信息可以在右侧的iframe中显示。&lt;/p&gt;&lt;p&gt;您可以狠狠地点击这里：&lt;a class="a_link" href="http://www.zhangxinxu.com/study/201202/web-messing-cross-document-messaging-two-iframe.html" target="_blank"&gt;两个iframe之间的跨文档通信demo&lt;/a&gt;&lt;/p&gt;&lt;p&gt;例如，我们在左侧输入&amp;ldquo;白静被害&amp;rdquo;，点击按钮后，右侧就有对应显示，参见下面截图：&lt;br /&gt;&lt;img class="alignnone" title="两个iframe之间的跨文档通信" src="http://image.zhangxinxu.com/image/blog/201202/2012-02-28_233325.png" alt="两个iframe之间的跨文档通信 张鑫旭-鑫空间-鑫生活" width="570" height="220" /&gt;&lt;/p&gt;&lt;p&gt;上面已经提过，跨文档通信被IE8+浏览器支持，因此，本demo在IE8浏览器下也是有效果滴：&lt;br /&gt;&lt;img class="alignnone" title="IE8下跨文档通信效果 " src="http://image.zhangxinxu.com/image/blog/201202/2012-02-28_233709.png" alt="IE8下跨文档通信效果 张鑫旭-鑫空间-鑫生活" width="513" height="219" /&gt;&lt;/p&gt;&lt;p&gt;OK，上面例子简单很，发送以及接收！&lt;/p&gt;&lt;p&gt;发送核心JS代码如下：&lt;/p&gt;&lt;div class="zxx_code"&gt;window.parent.frames[1].postMessage(message, '*');&lt;/div&gt;&lt;p&gt;&lt;strong&gt;说明：&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;window.parent.frames[1]&lt;/code&gt;指的就是demo正页中的第二个iframe. 然后使用&lt;code&gt;postMessage&lt;/code&gt;方法发送数据。&lt;/li&gt;&lt;li&gt;&lt;code&gt;postMessage&lt;/code&gt;方法支持两个参数，具体参考下表：&lt;br /&gt;&lt;table class="params_table" style="width: 100%;" border="0" cellspacing="1" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th scope="row"&gt;message&lt;/th&gt;&lt;td&gt;发送的数据&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope="row"&gt;targetOrigin&lt;/th&gt;&lt;td&gt;发送数据的来源。&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span&gt;其实还有个可选的第三参数&lt;code&gt;&lt;strong&gt;transfer&lt;/strong&gt;&lt;/code&gt;，不过用在通道通信中，这个放在后面讲。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;postMessage&lt;/code&gt;方法中的&lt;code&gt;message&lt;/code&gt;参数不仅仅可以是字符串，结构对象、数据对象(如：&lt;code&gt;File&lt;/code&gt;和&lt;code&gt;ArrayBuffer&lt;/code&gt;)或是数组都是可以的。很厉害吧，不过遗憾的是，IE8/IE9/FireFox3.6及其以下版本只支持字符串数据。&lt;/p&gt;&lt;p&gt;&lt;code&gt;targetOrigin&lt;/code&gt;参数指接收文档的来源。除非接收信息浏览上下文来源于提供的&lt;code&gt;targetOrigin&lt;/code&gt;中的一个匹配，否则浏览器是不会发送消息的。当然，您可以像上面的demo一样，绕开这类限制，直接使用&lt;code&gt;"*"&lt;/code&gt;通配符，但显然，这是把主公暴露在反贼的刀口之下啊（不安全的信息泄露）。本demo为了便于理解，去除不必要的干扰，所以才使用了&lt;code&gt;"*"&lt;/code&gt;通配符，您在实际使用的时候务必指定目标来源。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;您还可以通过使用&lt;code&gt;"/"&lt;/code&gt;来限制信息只能同源发送。不过，在文字落成的这个时候，只有Opera浏览器支持之。&lt;/li&gt;&lt;li&gt;还有一个需要注意的就是偶们指定来源的时候，后面不要带上斜杠。也就是要使用：&lt;div class="zxx_code"&gt;window.postMessage('发送信息。','http://example.zhangxinxu.com');&lt;/div&gt;&lt;p&gt;而不是：&lt;/p&gt;&lt;div class="zxx_code"&gt;&lt;del datetime="2012-02-28T13:53:54+00:00"&gt;window.postMessage('发送信息。','http://example.zhangxinxu.com/');&lt;/del&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;跨文档的浏览器窗体通信&lt;/strong&gt;&lt;br /&gt;上面的demo实在一个文档页面内完成的。实际上跨文档通信也可以在不同窗体之间完成。&lt;/p&gt;&lt;p&gt;您可以狠狠地点击这里：&lt;a class="a_link" href="http://www.zhangxinxu.com/study/201202/web-messing-cross-document-messaging-window.html" target="_blank"&gt;不同窗体间的跨文档通信demo&lt;/a&gt;&lt;/p&gt;&lt;p&gt;在现代浏览器下，点击男生或女生按钮（例如点击男生按钮），打开的新页面子啊2秒后显示了对应的通信信息。如下截图展示（截自FireFox 10）：&lt;br /&gt;&lt;img class="alignnone" title="点击男生按钮" src="http://image.zhangxinxu.com/image/blog/201202/2012-02-29_004704.png" alt="" width="322" height="176" /&gt;&amp;nbsp;&lt;img class="alignnone" title="显示对于信息" src="http://image.zhangxinxu.com/image/blog/201202/2012-02-29_004741.png" alt="" width="465" height="160" /&gt;&lt;/p&gt;&lt;p&gt;这个例子不仅仅展示了窗口见的通信，还有一点很重要的，就是展示了特定时间控制窗体信息的发送。&lt;/p&gt;&lt;p&gt;demo主页面有个名为&lt;code&gt;message&lt;/code&gt;的全局变量，当点击男生按钮的时候，这个变量值变成&amp;ldquo;&lt;code&gt;我是男生，帅气的男生！&lt;/code&gt;&amp;rdquo;；点击女生按钮则是&amp;ldquo;我是女生，漂亮的女生！&amp;rdquo;。消息的发送来自收到打开页面的&lt;code&gt;'ready'&lt;/code&gt;通信信息。&lt;/p&gt;&lt;p&gt;代码稍稍长了点，这里就不展示了。主demo页面JS代码都有，且高亮显示了，有中文注释，相信不难理解的。&lt;/p&gt;&lt;p&gt;本来还想举个实际应用的例子，例如iframe高度自适应问题。不过，一是懒；二是担心躲得深不易发现。这里赞先免了。有精力的时候可以专门说说。&lt;/p&gt;&lt;p&gt;本文一开始就提过，IE8不支持窗体通信，但是，细心的你可能发现IE9浏览器下也没有效果。到不是别的，而是貌似IE9还没有提供&lt;code&gt;e.currentTarget.opener&lt;/code&gt;接口，使得demo瞌睡去了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;四、通道通信&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;消息通道提供了一个直接，双向浏览上下文之间的通信手段。跟跨文档通信一样，DOM不直接暴露。取而代之，管道每端为端口，数据从一个端口发送，另一个变成输入（反之亦然）。&lt;/p&gt;&lt;p&gt;消息通道是有用的，特别是跨多个起源的沟通。请考虑以下情形：人人网上(http://renren.com)嵌入了一个第三方的游戏页面（通过iframe的形式，如&amp;ldquo;人人餐厅&amp;rdquo;），同时，这个第三方的游戏页面(http://game.com)又需要从另外一个通讯录网站(http://address.com)获取用户的通讯信息。咋办？&lt;/p&gt;&lt;p&gt;也就是说通讯录站点要发送信息给游戏站点，根据跨文档通信，我们让父页面作为代理（也就是这里的人人网页面）（类似第一个demo）。然而，这种做法意味着通讯录站点需要有和人人网页面一样的信任级别。人人网这个社交站点需要信任每一个请求，或者为我们过滤（应该指：一个一个指定）。&lt;/p&gt;&lt;p&gt;但是，使用渠道通信，通讯录站点(http://address.com)和游戏站点(http://game.com)可以直接沟通。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;MessageChannel和MessagePort对象&lt;/strong&gt;&lt;br /&gt;当我们创建了一个&lt;code&gt;MessageChannel&lt;/code&gt;对象，我们实际上创造了两个相互关联的端口。一个端口保持开放，为发送端。另外一个被转发到其他浏览上下文。&lt;/p&gt;&lt;p&gt;每一个端口就是一个&lt;code&gt;&lt;a href="http://dev.w3.org/html5/postmsg/#messageport"&gt;MessagePort&lt;/a&gt;&lt;/code&gt;对象，包含3个可用方法：&lt;/p&gt;&lt;table class="params_table" style="width: 100%;" border="0" cellspacing="1" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th scope="row"&gt;postMessage()&lt;/th&gt;&lt;td&gt;通过通道发送消息&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope="row"&gt;start()&lt;/th&gt;&lt;td&gt;开始在端口上分派接受的信息&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope="row"&gt;close()&lt;/th&gt;&lt;td&gt;关闭端口&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;code&gt;MessagePort&lt;/code&gt;对象还有&lt;code&gt;onmessage&lt;/code&gt;事件属性，可被用来定义事件句柄而不是事件监听。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;实例&lt;/strong&gt;&lt;br /&gt;上面过于术语的东西我自己都看不明白，还是实例好说话。&lt;/p&gt;&lt;p&gt;您可用狠狠地点击这里：&lt;a class="a_link" href="http://www.zhangxinxu.com/study/201202/web-messing-channel-messaging-two-iframe.html" target="_blank"&gt;通道通信应用demo&lt;/a&gt;&lt;/p&gt;&lt;p&gt;文章以开始的兼容性部分已经提过，FireFox浏览器目前还不支持通信通道，因此，上demo需要在Opera或是Chrome浏览器下打开。&lt;br /&gt;&lt;img class="alignnone" title="不支持的firefox下截图" src="http://image.zhangxinxu.com/image/blog/201202/2012-02-29_120645.png" alt="" width="330" height="148" /&gt;&lt;/p&gt;&lt;p&gt;demo页面操作与第一个demo类似，左侧输入信息，点击按钮提交。&lt;/p&gt;&lt;p&gt;例如在Opera浏览器下：&lt;br /&gt;&lt;img class="alignnone" title="Opera浏览器下的通道通信截图" src="http://image.zhangxinxu.com/image/blog/201202/2012-02-29_120926.png" alt="Opera浏览器下的通道通信截图 张鑫旭-鑫空间-鑫生活" width="541" height="269" /&gt;&lt;/p&gt;&lt;p&gt;当然，并不是每一次都是OK的，有时候会弹出&amp;ldquo;端口不可用的提示&amp;rdquo;，原因不详，估计可能与端口被占用有关，遇到这种情况，稍后尝试即可。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;简析&lt;/strong&gt;&lt;br /&gt;上面的demo动用了三个页面：主页面和两个iframe页面。下面说说每个页面都做了些什么：&lt;/p&gt;&lt;p&gt;首先是第一个iframe页面（demo左侧有表单提交的那个）。其任务有两个：一是告诉主页面，我加载好了；二是扩大并确定端口，表单提交时用做发送用。&lt;/p&gt;&lt;div class="zxx_code"&gt;&lt;span&gt;// 告诉主页面，我加载好了&lt;/span&gt;&lt;br/&gt;window.parent.postMessage('发送页加载完毕', 'http://www.zhangxinxu.com');&lt;/div&gt;&lt;div class="zxx_code"&gt;&lt;span&gt;// 扩大并确定端口&lt;/span&gt;&lt;br/&gt;port = evt.ports[0];&lt;br/&gt;&lt;br/&gt;&lt;span&gt;// 端口发送数据&lt;/span&gt;&lt;br/&gt;port.postMessage(message);&lt;/div&gt;&lt;p&gt;然后是第二个iframe页面（demo右侧那个，用来显示信息）。其任务有三个，一是创建&lt;code&gt;MessageChannel&lt;/code&gt;通道对象；二是告诉主页面，我加载好了，并把端口传过去；三是显示发送信息。&lt;/p&gt;&lt;div class="zxx_code"&gt;&lt;span&gt;// 创建一个新的 MessageChannel 对象&lt;/span&gt;&lt;br/&gt;var mc = new MessageChannel();&lt;br/&gt;&lt;br/&gt;&lt;span&gt;// 给父级发送一个端口&lt;/span&gt;&lt;br/&gt;window.parent.postMessage('显示页加载完毕','http://www.zhangxinxu.com', [mc.port1]);&lt;/div&gt;&lt;div class="zxx_code"&gt;&lt;span&gt;// 显示发送的信息&lt;/span&gt;&lt;br/&gt;mc.port2.addEventListener('message', messageHandle, false);&lt;br/&gt;mc.port2.start();&lt;/div&gt;&lt;p&gt;最后是主页面。其任务很简单就一个：告诉第一个iframe页面，端口已经打开了（第一个iframe就可以确定跟第二个iframe通信的端口了）。&lt;/p&gt;&lt;div class="zxx_code"&gt;&lt;span&gt;// 将端口告诉其他文档&lt;/span&gt;&lt;br/&gt;window.frames[0].postMessage('端口打开','http://www.zhangxinxu.com', evt.ports);&lt;/div&gt;&lt;p&gt;于是，三者关联配合，就搞定啦！&lt;/p&gt;&lt;p&gt;&lt;strong&gt;五、其他资源&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;slideshare上有个web通信的文档，这里展示下，有兴趣的童鞋可以快速浏览下。&lt;/p&gt;&lt;div id="__ss_7970364"&gt;&lt;strong&gt;&lt;a title="HTML5 Web Messaging" href="http://www.slideshare.net/miketaylr/html5-web-messaging-7970364" target="_blank"&gt;HTML5 Web Messaging&lt;/a&gt;&lt;/strong&gt;&lt;iframe src="http://www.slideshare.net/slideshow/embed_code/7970364" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="425" height="355"&gt;&lt;/iframe&gt;&lt;div&gt;更多来自&lt;a href="http://www.slideshare.net/miketaylr" target="_blank"&gt;Mike Taylor&lt;/a&gt;的&lt;a href="http://www.slideshare.net/" target="_blank"&gt;演示文档&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;六、参考文章&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;middot;&amp;nbsp;&lt;a href="http://dev.opera.com/articles/view/window-postmessage-messagechannel/"&gt;An Introduction to HTML5 web messaging&lt;/a&gt;&lt;br /&gt;&amp;middot;&amp;nbsp;&lt;a href="http://www.w3.org/html/ig/zh/wiki/HTML5/browsers"&gt;HTML5/browsers（中文）&lt;/a&gt;&lt;br /&gt;&amp;middot;&amp;nbsp;&lt;a href="http://www.36ria.com/3890"&gt;利用HTML5的window.postMessage实现跨域通信&lt;/a&gt;&lt;/p&gt;&lt;p&gt;转自：&lt;a href="http://www.zhangxinxu.com/wordpress/?p=2229"&gt;http://www.zhangxinxu.com/wordpress/?p=2229&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ATree/aggbug/2383410.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ATree/archive/2012/03/07/HTML5-Web-Messaging.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ATree/archive/2012/03/07/Responsive-Images-Cookie-JavaScript.html</id><title type="text">Responsive Images技术简介：根据显示器宽度下调用图片</title><summary type="text">响应图片技术可以说是响应布局衍生出来的一个小分支。说白了，就是不同显示器宽度下调用不同的图片。这玩意，最近在国外讨论很火，有几种不同的实现方法，但都并不复杂。github上有该技术介绍。该技术需要Javascript以及后台程序的配合。加载需要的JS文件responsive-images.js, 该JS文件为获取当前用户显示器宽度，然后根据宽度值大小决定图片是小(small)呢，中等(medium)呢还是大(large)，然后写入对应的Cookie.下面就是服务器端事了，服务器（可以通过配置项）检测Cookie是被设成了small呢， medium呢还是large决定图片的src地址到底是哪个。github上项目有个demo, 点击这里访问。</summary><published>2012-03-07T05:37:00Z</published><updated>2012-03-07T05:37:00Z</updated><author><name>zock</name><uri>http://www.cnblogs.com/ATree/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ATree/archive/2012/03/07/Responsive-Images-Cookie-JavaScript.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ATree/archive/2012/03/07/Responsive-Images-Cookie-JavaScript.html"/><content type="html">&lt;p&gt;&lt;strong&gt;一、开门见山&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;响应图片技术可以说是&lt;a href="http://www.zhangxinxu.com/wordpress/?p=1937"&gt;响应布局&lt;/a&gt;衍生出来的一个小分支。说白了，就是不同显示器宽度下调用不同的图片。&lt;/p&gt;&lt;p&gt;这玩意，最近在国外讨论很火，有几种不同的实现方法，但都并不复杂。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;二、Cookie + Server实现&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;github上有该技术&lt;a href="https://github.com/filamentgroup/Responsive-Images/tree/cookie-driven"&gt;介绍&lt;/a&gt;。该技术需要Javascript以及后台程序的配合。&lt;/p&gt;&lt;div id="content_atree"&gt;&lt;em&gt;如果你看到这段文字，说明您正使用RSS阅读或转自《一棵树-博客园》，原文地址：&lt;a id="Editor_Edit_hlEntryLink" title="view: Responsive Images技术简介：根据显示器宽度下调用图片" href="http://www.cnblogs.com/ATree/archive/2012/03/07/Responsive-Images-Cookie-JavaScript.html" target="_blank"&gt;http://www.cnblogs.com/ATree/archive/2012/03/07/Responsive-Images-Cookie-JavaScript.html&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;&lt;p&gt;加载需要的JS文件&lt;a href="http://filamentgroup.com/examples/responsive-images-new/responsive-images.js"&gt;responsive-images.js&lt;/a&gt;, 该JS文件为获取当前用户显示器宽度，然后根据宽度值大小决定图片是小(small)呢，中等(medium)呢还是大(large)，然后写入对应的Cookie.&lt;/p&gt;&lt;p&gt;下面就是服务器端事了，服务器（可以通过配置项）检测Cookie是被设成了small呢， medium呢还是large决定图片的src地址到底是哪个。&lt;/p&gt;&lt;p&gt;github上项目有个demo, 点击&lt;a href="http://filamentgroup.com/examples/responsive-images-new/demos/A-Default/demo.html"&gt;这里&lt;/a&gt;访问。&lt;/p&gt;&lt;p&gt;首次进入的时候是个小图（Cookie首次写入，后台无法获取），再次刷新就是个大家伙了：&lt;br /&gt;&lt;img title="首次载入的小图 " src="http://image.zhangxinxu.com/image/blog/201202/2012-02-15_192900.jpg" alt="" width="440" height="308" /&gt;&amp;nbsp;&lt;img title="再次刷新的大图" src="http://image.zhangxinxu.com/image/blog/201202/2012-02-15_193514.jpg" alt="" width="414" height="287" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;与响应布局差异&lt;/strong&gt;&lt;br /&gt;虽说该技术有响应布局的影子，但是，实际上实现的原理以及效果等是大相径庭的。差异在于：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;非CSS技术，为Cookie + server实现&lt;/li&gt;&lt;li&gt;与浏览器宽度无关，即改变浏览器宽度图片不会有变化&lt;/li&gt;&lt;li&gt;兼容具有考古价值的浏览器&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;这种响应方式跟京东商城首页几乎如出一辙。页面宽度由用户显示器分辨率决定（非浏览器）。&lt;/p&gt;&lt;p&gt;下图为1024像素显示器宽度和1680像素下(1280像素宽度就足够了)的京东商城页面布局截图。&lt;br /&gt;&lt;img class="alignnone" title="京东商城1024宽度下首页布局 张鑫旭-鑫空间-鑫生活" src="http://image.zhangxinxu.com/image/blog/201109/2011-09-19_173215.png" alt="京东商城1024宽度下首页布局 张鑫旭-鑫空间-鑫生活" width="514" height="282" /&gt;&amp;nbsp;&lt;img class="alignnone" title="京东商城1680像素宽度下首页布局 张鑫旭-鑫空间-鑫生活" src="http://image.zhangxinxu.com/image/blog/201109/2011-09-19_173342.png" alt="京东商城1680像素宽度下首页布局 张鑫旭-鑫空间-鑫生活" width="514" height="281" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;兼容性&lt;/strong&gt;&lt;br /&gt;因为使用Cookie，并非CSS3&amp;nbsp;&lt;code&gt;media queries&lt;/code&gt;，因此低版本IE浏览器下也是OK的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;如果设备不支持Javascript以及Cookie&lt;/strong&gt;&lt;br /&gt;如果访问设备不支持Javascript以及Cookie, 则图片会显示mobile手机上尺寸，即小尺寸。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;可选项&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://filamentgroup.com/examples/responsive-images-new/responsive-images.js"&gt;responsive-images.js&lt;/a&gt;是一个非常小的脚本，不会其也会有可选项的。可选参数为一个全局的对象字面量。&lt;/p&gt;&lt;div class="zxx_code"&gt;&lt;code&gt;&amp;lt;script&amp;gt; &lt;span&gt;//这里为配置项:&lt;/span&gt; var responsive_images = { "key": "value" }; &amp;lt;/script&amp;gt; &lt;/code&gt;&lt;/div&gt;&lt;p&gt;对象字面量的名称是固定的，为responsive_images，支持的关键字、默认值和含义见下表：&lt;/p&gt;&lt;table class="params_table" style="width: 100%;" border="0" cellspacing="1" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th scope="col"&gt;关键字&lt;/th&gt;&lt;th scope="col"&gt;默认值&lt;/th&gt;&lt;th scope="col"&gt;释义&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cookieName&lt;/td&gt;&lt;td&gt;rwd-screensize&lt;/td&gt;&lt;td&gt;Cookie名&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cookieValue&lt;/td&gt;&lt;td&gt;sw &amp;gt; 500 ? ( sw &amp;gt; 1000 ? "large" : "medium" ) : "small"&lt;/td&gt;&lt;td&gt;Cookie值&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cookieAge&lt;/td&gt;&lt;td&gt;30000&lt;/td&gt;&lt;td&gt;过期时间，单位毫秒&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cookieDomain&lt;/td&gt;&lt;td&gt;当前访问&lt;/td&gt;&lt;td&gt;Cookie域&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;cookiePath&lt;/td&gt;&lt;td&gt;/&lt;/td&gt;&lt;td&gt;Cookie路径&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;三、其他同行的Cookie实现&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;keithclark在去年夏天的时候就说过响应图片，不过其文章更多的是展示服务器端的处理(PHP)，原理与上面类似。&lt;/p&gt;&lt;p&gt;先是写Cookie, 很简短的：&lt;/p&gt;&lt;div class="zxx_code"&gt;document.cookie = "device_dimensions=" + screen.width + "x" + screen.height; &lt;/div&gt;&lt;p&gt;然后就是PHP语言的绽放了：&lt;/p&gt;&lt;div class="zxx_code"&gt;&amp;lt;?php&lt;br/&gt;  $device_width = 0;&lt;br/&gt;  $device_height = 0;&lt;br/&gt;  $file = $_SERVER[&lt;span class="string"&gt;'QUERY_STRING'&lt;/span&gt;];&lt;br/&gt;&lt;br/&gt;  &lt;span class="keyword"&gt;if&lt;/span&gt; (file_exists($file)) {&lt;br/&gt;&lt;br/&gt;    &lt;span class="comment"&gt;// Read the device viewport dimensions&lt;/span&gt;&lt;br/&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; (isset($_COOKIE[&lt;span class="string"&gt;'device_dimensions'&lt;/span&gt;])) {&lt;br/&gt;      $dimensions = explode(&lt;span class="string"&gt;'x'&lt;/span&gt;, $_COOKIE[&lt;span class="string"&gt;'device_dimensions'&lt;/span&gt;]);&lt;br/&gt;      &lt;span class="keyword"&gt;if&lt;/span&gt; (count($dimensions)==2) {&lt;br/&gt;        $device_width = intval($dimensions[0]);&lt;br/&gt;        $device_height = intval($dimensions[1]);&lt;br/&gt;      }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; ($device_width &amp;gt; 0) {&lt;br/&gt;&lt;br/&gt;      $fileext = pathinfo($file, PATHINFO_EXTENSION);&lt;br/&gt;&lt;br/&gt;      &lt;span class="comment"&gt;// Low resolution image&lt;/span&gt;&lt;br/&gt;      &lt;span class="keyword"&gt;if&lt;/span&gt; ($device_width &amp;lt;= 800) {&lt;br/&gt;        $output_file = substr_replace($file, &lt;span class="string"&gt;'-low'&lt;/span&gt;, -strlen($fileext)-1, 0);&lt;br/&gt;      } &lt;br/&gt;&lt;br/&gt;      &lt;span class="comment"&gt;// Medium resolution image&lt;/span&gt;&lt;br/&gt;      &lt;span class="keyword"&gt;else&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; ($device_width &amp;lt;= 1024) {&lt;br/&gt;        $output_file = substr_replace($file, &lt;span class="string"&gt;'-med'&lt;/span&gt;, -strlen($fileext)-1, 0);&lt;br/&gt;      }&lt;br/&gt;&lt;br/&gt;      &lt;span class="comment"&gt;// check the file exists&lt;/span&gt;&lt;br/&gt;      &lt;span class="keyword"&gt;if&lt;/span&gt; (isset($output_file) &amp;amp;&amp;amp; file_exists($output_file)) {&lt;br/&gt;        $file = $output_file;&lt;br/&gt;      }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="comment"&gt;// return the file;&lt;/span&gt;&lt;br/&gt;    readfile($file);&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;?&amp;gt;&lt;/div&gt;&lt;p&gt;然后HTML端的庐山面目：&lt;/p&gt;&lt;div class="zxx_code"&gt;&lt;span class="dtd"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="tag"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="tag"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;br/&gt;  &lt;span class="tag"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Responsive Images Test&lt;span class="tag"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;br/&gt;  &lt;span class="tag"&gt;&amp;lt;meta &lt;span class="attname"&gt;charset=&lt;/span&gt;&lt;span class="attvalue"&gt;"utf-8"&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;  &lt;span class="tag"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;br/&gt;    document.cookie = "device_dimensions=" + screen.width + "x" + screen.height;&lt;br/&gt;  &lt;span class="tag"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="tag"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="tag"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;br/&gt;  &lt;span class="tag"&gt;&amp;lt;img &lt;span class="attname"&gt;src=&lt;/span&gt;&lt;span class="attvalue"&gt;"images/?test.png"&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;  &lt;span class="comment"&gt;&amp;lt;!-- 上面等同于： &amp;lt;img src="images/index.php?test.png"&amp;gt; --&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="tag"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="tag"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;/div&gt;&lt;p&gt;这个嘛希望对喜欢copy代码的同行有所帮助。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;四、使用noscript标签创建响应图片&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;上面例子中的响应图片在两种情况下会直接mobile尺寸图片显示：一是站点首次载入的时候；二是Cookie禁用或是Javascript出去撞劳斯莱斯的时候。&lt;/p&gt;&lt;p&gt;这里的&lt;code&gt;noscript&lt;/code&gt;标签创建法则基本没有这些问题，因为该方法完全借助客户端实现。&lt;/p&gt;&lt;p&gt;同样，github上有该方法的项目页面 &amp;ndash;&amp;nbsp;&lt;a class="a_link" href="https://github.com/futurechimp/responsive_image_tag" target="_blank"&gt;futurechimp / responsive_image_tag&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;这里的响应图片技术貌似不需要Cookie的前后端通讯，而是借助&lt;code&gt;noscript&lt;/code&gt;标签以及JS实现。&lt;/p&gt;&lt;p&gt;下面就是实现的&lt;strong&gt;步步展示&lt;/strong&gt;：&lt;/p&gt;&lt;p&gt;首先是HTML部分：&lt;/p&gt;&lt;div class="zxx_code"&gt;&lt;span class="ta"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="an"&gt;class&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;img-placeholder&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;tt&gt; &lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;noscript&lt;/span&gt; &lt;span class="an"&gt;data-mobilesrc&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;small.jpg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;data-fullsrc&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;big.jpg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;data-alttext&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;your alt text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;class&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;responsivize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt; &lt;/tt&gt;   &lt;span class="ta"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="an"&gt;src&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;big.jpg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt; &lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/noscript&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;上面代码中，类名为&lt;code&gt;img-placeholder&lt;/code&gt;的&lt;code&gt;span&lt;/code&gt;标签是用来占位子和插入图片的。&lt;code&gt;&amp;lt;noscript&amp;gt;&lt;/code&gt;中的图片默认调用的是大图地址，在JavaScript被禁用的时候会显示。&lt;/p&gt;&lt;p&gt;下面要做的就是使用JavaScript判别当前显示设备是mobile类别还是desktop类别：&lt;/p&gt;&lt;div class="zxx_code"&gt;&lt;span class="kw"&gt;var&lt;/span&gt; responsiveImageTag = {&lt;tt&gt; &lt;/tt&gt;    &lt;span class="fu"&gt;replaceInitialImages&lt;/span&gt;:&lt;span class="kw"&gt;function&lt;/span&gt;() {&lt;tt&gt; &lt;/tt&gt;        &lt;span class="kw"&gt;var&lt;/span&gt; platform = &lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;desktop&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt; &lt;/tt&gt;        &lt;span class="kw"&gt;var&lt;/span&gt; responsiveImages = &lt;span class="pd"&gt;$$&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;.responsivize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt; &lt;/tt&gt;        &lt;span class="kw"&gt;var&lt;/span&gt; i,&lt;tt&gt; &lt;/tt&gt;            noOfresponsiveImages = responsiveImages.length;&lt;tt&gt; &lt;/tt&gt;        &lt;span class="c"&gt;//当前显示器设备宽度测试&lt;/span&gt;&lt;tt&gt; &lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt;(screen.width &amp;lt;= &lt;span class="i"&gt;767&lt;/span&gt;){&lt;br/&gt;                &lt;span class="c"&gt;//767px, 比 ipad 小的都认为是 mobile&lt;/span&gt;&lt;tt&gt; &lt;/tt&gt;          platform = &lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;mobile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt; &lt;/tt&gt;        }&lt;tt&gt; &lt;/tt&gt;        &lt;tt&gt; &lt;/tt&gt;       &lt;span class="c"&gt;//set initial source element on image&lt;/span&gt;&lt;tt&gt; &lt;/tt&gt;       &lt;span class="kw"&gt;for&lt;/span&gt;(i = &lt;span class="i"&gt;0&lt;/span&gt;; i &amp;lt; noOfresponsiveImages; i = i + &lt;span class="i"&gt;1&lt;/span&gt; ){&lt;tt&gt; &lt;/tt&gt;       &lt;span class="kw"&gt;var&lt;/span&gt; noScriptElem = &lt;span class="pd"&gt;$&lt;/span&gt;(responsiveImages[i]);&lt;tt&gt; &lt;/tt&gt;&lt;tt&gt; &lt;/tt&gt;&lt;/div&gt;&lt;p&gt;既然知道了设备类别，我们就可以根据这个类别分别载入对应尺寸的图片了。对应设备尺寸图片地址以通过HTML5自定义属性&lt;code&gt;data-&lt;/code&gt;定义在了&lt;code&gt;&amp;lt;noscript&amp;gt;&lt;/code&gt;上，因此，我们就有代码（紧接上面）：&lt;/p&gt;&lt;div class="zxx_code"&gt;&lt;span class="kw"&gt;    var&lt;/span&gt; img = window.document.createElement(&lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;img&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt; &lt;/tt&gt;       img.alt = noScriptElem.attr(&lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;data-alttext&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt; &lt;/tt&gt;       &lt;span class="kw"&gt;if&lt;/span&gt;(platform === &lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;mobile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;){&lt;tt&gt; &lt;/tt&gt;          img.src = noScriptElem.attr(&lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;data-mobilesrc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt; &lt;/tt&gt;       }&lt;span class="kw"&gt;else&lt;/span&gt;{&lt;tt&gt; &lt;/tt&gt;          img.src = noScriptElem.attr(&lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;data-fullsrc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt; &lt;/tt&gt;       }&lt;tt&gt; &lt;/tt&gt;       img.className = &lt;span class="s"&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="k"&gt;responsive&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt; &lt;/tt&gt;&lt;/div&gt;&lt;p&gt;然后，把图片以DOM的形式插入到上面用来占位的&lt;code&gt;span&lt;/code&gt;标签元素内，于是就大功告成！&lt;/p&gt;&lt;div class="zxx_code"&gt;       noScriptElem.prev().append(img);   &lt;tt&gt; &lt;/tt&gt;       noScriptElem.hide();&lt;tt&gt; &lt;/tt&gt;     }&lt;tt&gt; &lt;/tt&gt;   }&lt;tt&gt; &lt;/tt&gt;};&lt;/div&gt;&lt;p&gt;&lt;strong&gt;五、另类图片响应&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Jeremy Keith提出了另外一种响应图片技术，可以算是一种图片加载优化技术。&lt;/p&gt;&lt;p&gt;如下：&lt;br /&gt;无论是小屏幕的手机，还是大屏幕的桌面设备，默认&lt;code&gt;img&lt;/code&gt;链接的图片都是小图（如下）。&lt;br /&gt;&lt;img class="alignnone" title="示例原始小图" src="http://image.zhangxinxu.com/image/blog/201202/response_image_m.jpg" alt="" width="240" height="179" /&gt;&lt;/p&gt;&lt;p&gt;然后页面载入完毕后，如果显示器宽度超过一个限制，则&lt;code&gt;src&lt;/code&gt;地址切换成大图地址。&lt;/p&gt;&lt;p&gt;其中，有个比较关键的就是，如果显示器宽度大于某个值，小图的高宽尺寸是要被放大的，也就是说小图会被拉伸显示。这种尺寸的控制借助于CSS3：&lt;/p&gt;&lt;div class="zxx_code"&gt;@media screen and (min-width: 50em) {&lt;br/&gt;    .photo {&lt;br/&gt;        width: 500px;&lt;br/&gt;        height: 375px;&lt;br/&gt;    }&lt;br/&gt;}&lt;/div&gt;&lt;p&gt;于是乎，我们会看到，页面载入后的模糊图片：&lt;br /&gt;&lt;img class="alignnone" title="图片拉伸" src="http://image.zhangxinxu.com/image/blog/201202/response_image_m.jpg" alt="" width="500" /&gt;&lt;/p&gt;&lt;p&gt;但是，这种模糊效果是暂时的，因为页面loaded完毕后，我们会根据宽度范围再次修改&lt;code&gt;img&lt;/code&gt;的&lt;code&gt;src&lt;/code&gt;地址，而载入清晰图片。&lt;br /&gt;&lt;img class="alignnone" title="大尺寸图片" src="http://image.zhangxinxu.com/image/blog/201202/response_image_l.jpg" alt="" width="500" height="374" /&gt;&lt;/p&gt;&lt;p&gt;我记得以前百度图片浏览就是这种效果滴。&lt;/p&gt;&lt;p&gt;这种图片响应实现的好处在于提高了页面的性能，虽然看上去好像比值加载大尺寸图片多了差不多20K。&lt;/p&gt;&lt;p&gt;根据作者的示例，大图的地址使用HTML5&amp;nbsp;&lt;code&gt;data-&lt;/code&gt;自定义属性藏匿：&lt;/p&gt;&lt;div class="zxx_code"&gt;&amp;lt;img src="seed.jpg" alt="刺刺的种子" &lt;span&gt;data-fullsrc&lt;/span&gt;="seed-large.jpg"&amp;gt; &lt;/div&gt;&lt;p&gt;&lt;strong&gt;六、参考文章&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://github.com/filamentgroup/Responsive-Images/tree/cookie-driven"&gt;Responsive Design Images&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://drupal.org/project/responsive_images"&gt;Responsive Images&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.keithclark.co.uk/responsive-images-using-cookies/"&gt;Responsive images using cookies&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Mairead:&amp;nbsp;&lt;a href="http://www.headlondon.com/our-thoughts/technology/posts/creating-responsive-images-using-the-noscript-tag"&gt;Creating responsive images using the noscript tag&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.alistapart.com/articles/responsive-images-how-they-almost-worked-and-what-we-need/"&gt;Responsive Images: How they Almost Worked and What We Need&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://adactio.com/journal/5208/"&gt;Image-y nation&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;转自：&lt;a href="http://www.zhangxinxu.com/wordpress/?p=2204"&gt;http://www.zhangxinxu.com/wordpress/?p=2204&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ATree/aggbug/2383394.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ATree/archive/2012/03/07/Responsive-Images-Cookie-JavaScript.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ATree/archive/2012/03/07/2011_state_agile.html</id><title type="text">2011年度敏捷软件开发调研结果发布</title><summary type="text">最近，VersionOne揭晓了2011年度敏捷软件开发调研结果，再一次向大家展示了敏捷应用和发展趋势的第一手资料。今年，我们进一步确信敏捷并非一时风潮。我们过半的调查对象坦言他们已经亲身实践敏捷超过两年了，并且三分之一的人把敏捷从一家公司带到了另一家。大约有三分之二的调查对象谈到，他们公司的项目有超过半数在使用敏捷方法，有三个以上团队实施了敏捷实践。Scrum依然是敏捷方法流行榜中当之为愧的状元，52%的受访者采用了Scrum（2010年则是58%）。</summary><published>2012-03-07T04:54:00Z</published><updated>2012-03-07T04:54:00Z</updated><author><name>zock</name><uri>http://www.cnblogs.com/ATree/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ATree/archive/2012/03/07/2011_state_agile.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ATree/archive/2012/03/07/2011_state_agile.html"/><content type="html">&lt;p&gt;最近，&lt;a href="http://www.versionone.com/"&gt;VersionOne&lt;/a&gt;揭晓了2011年度敏捷软件开发调研结果，再一次向大家展示了敏捷应用和发展趋势的第一手资料。&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;今年，我们进一步确信敏捷并非一时风潮。我们过半的调查对象坦言他们已经亲身实践敏捷超过两年了，并且三分之一的人把敏捷从一家公司带到了另一家。大约有三分之二的调查对象谈到，他们公司的项目有超过半数在使用敏捷方法，有三个以上团队实施了敏捷实践。&lt;div id="content_atree"&gt;&lt;em&gt;如果你看到这段文字，说明您正使用RSS阅读或转自《一棵树-博客园》，原文地址：&lt;a href="http://www.cnblogs.com/ATree/archive/2012/03/02/2011_state_agile.html"&gt;http://www.cnblogs.com/ATree/archive/2012/03/02/2011_state_agile.html&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;Scrum依然是敏捷方法流行榜中当之为愧的状元，52%的受访者采用了Scrum（2010年则是58%）。&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;&lt;a href="https://twitter.com/#%21/agilemaniac"&gt;Matt Badgley&lt;/a&gt;在最近的博文中&lt;a href="http://blogs.versionone.com/agile_management/2012/02/09/pondering-the-agile-dont-know-methodology/"&gt;探讨了那些&amp;ldquo;不确定&amp;rdquo;方法&lt;/a&gt;：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;我的第一感觉是培训&amp;hellip;&amp;hellip;如果团队没有接受过敏捷概念以及相关方法和流程的培训，那么不难理解，当你问他们：&amp;ldquo;你们在搞敏捷吗？&amp;rdquo;&amp;hellip;&amp;hellip;&amp;ldquo;是的。&amp;rdquo;&amp;ldquo;你们用了什么敏捷方法呢？&amp;rdquo;&amp;hellip;&amp;hellip;&amp;ldquo;我不确定。&amp;rdquo;&amp;hellip;&amp;hellip;我想人家回答&amp;ldquo;不确定&amp;rdquo;的另一个原因可能是他们正纠结于各个敏捷方法论五花八门的概念中&amp;mdash;&amp;mdash;甚至还混杂着敏捷项目管理和传统项目管理&amp;hellip;&amp;hellip;团队开始时用这个方法，接着糅合了另一种，在一些状况下，还要从每种方法中都取点精髓出来。这种做法有利有弊，它依赖于团队的成熟度和持续改进的能力。&lt;/blockquote&gt;&lt;p&gt;关于敏捷技术，每日站立会议、迭代计划和单元测试名列前茅（保持着去年的态势）：&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;52%&lt;/td&gt;&lt;td&gt;Scrum&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;14%&lt;/td&gt;&lt;td&gt;Scrum/XP混合&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9%&lt;/td&gt;&lt;td&gt;自定义混合&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8%&lt;/td&gt;&lt;td&gt;不确定&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;17%&lt;/td&gt;&lt;td&gt;其它（包括看板 3%以及 XP 2%）&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;78%&lt;/td&gt;&lt;td&gt;每日站立会议&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;74%&lt;/td&gt;&lt;td&gt;迭代计划&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;70%&lt;/td&gt;&lt;td&gt;单元测试&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;65%&lt;/td&gt;&lt;td&gt;发布计划&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;64%&lt;/td&gt;&lt;td&gt;燃尽图&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;64%&lt;/td&gt;&lt;td&gt;回顾会议&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;54%&lt;/td&gt;&lt;td&gt;持续集成&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;53%&lt;/td&gt;&lt;td&gt;自动构建&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;52%&lt;/td&gt;&lt;td&gt;速率&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;51%&lt;/td&gt;&lt;td&gt;编码规范&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;a href="https://twitter.com/#%21/energizr"&gt;Simon Baker&lt;/a&gt;在&lt;a href="http://www.energizedwork.com/weblog/2012/02/state-of-agile-survey-for-2011-tells-a-familiar-story"&gt;他名为&amp;ldquo;敏捷在行动&amp;rdquo;的博客里面&lt;/a&gt;剖析了述敏捷技术调查结果，他还特别分析了一些得票率较低的实践，如重构（48%）、测试驱动开发（38%）、自动化验收测试（25%）以及行为驱动开发（9%）：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;由这些数据我可以推断，软件行业还是在开发很多糟糕的软件，还很过分地把敏捷称为流程。大家还记得个体胜过流程吗？不管怎样，我想知道，投资人花钱买单，但这些糟糕的软件实际上能给客户带来多少价值呢？但愿有一天更多的人能够意识到，做到敏捷其实是要做到快速、经济、低风险地响应不断变化的业务需求。&lt;/blockquote&gt;&lt;p&gt;&amp;ldquo;项目失败的主要原因&amp;rdquo;的调查结果很有意思，其中有16%的调查对象反应他们的敏捷项目从没有失败过，位列榜首。下面援引了一些排名前列的失败原因：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;11%&lt;/td&gt;&lt;td&gt;缺乏敏捷方法相关经验&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;11%&lt;/td&gt;&lt;td&gt;缺乏对必要的组织层面的变化的认识&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9%&lt;/td&gt;&lt;td&gt;企业理念及文化与敏捷理念相冲突&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8%&lt;/td&gt;&lt;td&gt;外部要求遵循瀑布模型的压力&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;p&gt;进一步实施敏捷的障碍则有：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;52%&lt;/td&gt;&lt;td&gt;改变组织文化的能力&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;40%&lt;/td&gt;&lt;td&gt;是否有足够的专业人士&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;39%&lt;/td&gt;&lt;td&gt;抗拒改变的惯性&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;p&gt;就这些障碍，&lt;a href="https://twitter.com/#%21/dmoran1"&gt;Dave Moran&lt;/a&gt;在&lt;a href="http://www.softwareresults.us/2012/02/state-of-agile-development.html"&gt;Software Results上发表博文&lt;/a&gt;，分享了他的观点:&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;这些障碍和担忧映射出我们所熟知的道理：改变是艰难的。而敏捷开发就是一种改变。依照我对调查的解读，我们获得的这些实际收益，恰恰和我们在敏捷实践过程中所期望的是一致的。它们是更快、更易、坚实的每一步。团队士气提升则是实施敏捷能够获得的第四种益处，也是实施敏捷必然的结果。&lt;/blockquote&gt;&lt;p&gt;调查还显示，75%的参与者认为运用敏捷方法完成项目的时间和用之前的方法差不多，或者更快些（比2010年度的83%降低了）。实施敏捷的主要好处有：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;84%&lt;/td&gt;&lt;td&gt;管理变更优先级的能力&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;77%&lt;/td&gt;&lt;td&gt;项目可见性得以改进&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;75%&lt;/td&gt;&lt;td&gt;生产力得到提升&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;72%&lt;/td&gt;&lt;td&gt;团队士气有所提升&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;71%&lt;/td&gt;&lt;td&gt;更快地响应市场&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;p&gt;在VersionOne站点上，你可以浏览到&lt;a href="http://www.versionone.com/state_of_agile_development_survey/11/"&gt;完整的调查结果&lt;/a&gt;（你同时可以找到&lt;a href="http://www.versionone.com/state_of_agile_development_survey/10/"&gt;2010年的结果&lt;/a&gt;）。今年的调查结果有哪些很突出吗，还是说明敏捷实施趋于稳定了？&lt;/p&gt;&lt;p&gt;&lt;span&gt;查看英文原文：&lt;/span&gt;&lt;a href="http://www.infoq.com/news/2012/02/2011_state_agile"&gt;2011 State of Agile Survey Results Show Agile Adoption Stable&lt;/a&gt;&lt;/p&gt;&lt;p class="miniBio"&gt;&lt;em&gt;&lt;strong&gt;译者&lt;/strong&gt;&amp;nbsp;&lt;strong&gt;&lt;a class="editorlink f_taxonomyTranslator" href="http://www.infoq.com/cn/author/%E9%87%91%E6%AF%85"&gt;金毅&lt;/a&gt;&amp;nbsp;&lt;/strong&gt;多年来服务于欧美软件外包行业从事管理工作，对软件工程、方法学等在外包业的运用和CMMI实施略有感悟。&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://www.cnblogs.com/ATree/aggbug/2376482.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ATree/archive/2012/03/07/2011_state_agile.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ATree/archive/2012/02/17/jquery-zSlide-js-CSS3-HTML5.html</id><title type="text">jquery.zSlide.js-基于CSS3/HTML5演示文档jQuery插件</title><summary type="text">jquery.zSlide.js是我最近折腾的一个jQuery插件，借助于CSS3和HTML5的一些新特性，在浏览器中实现类似于powerpoint幻灯片展示。无论是在公司内部，还是在一些技术会议上，我们做分享的时候，用的最多的想必是powerpoint。但是，powerpoint这个东西本身就是缺乏“自由”与“分享”精神的，因为其目前无法在线共享。要学习某技术会议上大牛分享的东西，多半要去找资源→download→整理或解压或打开之类，资源不好还要清理等等。</summary><published>2012-02-17T06:40:00Z</published><updated>2012-02-17T06:40:00Z</updated><author><name>zock</name><uri>http://www.cnblogs.com/ATree/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ATree/archive/2012/02/17/jquery-zSlide-js-CSS3-HTML5.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ATree/archive/2012/02/17/jquery-zSlide-js-CSS3-HTML5.html"/><content type="html">&lt;p&gt;&lt;strong&gt;一、卖的什么葫芦药？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;jquery.zSlide.js是我最近折腾的一个jQuery插件，借助于CSS3和HTML5的一些新特性，在浏览器中实现类似于powerpoint幻灯片展示。&lt;/p&gt;&lt;div id="content_atree"&gt;&lt;em&gt;如果你看到这段文字，说明您正使用RSS阅读或转自《一棵树-博客园》，原文地址：&lt;a id="Editor_Edit_hlEntryLink" title="view: jquery.zSlide.js-基于CSS3/HTML5演示文档jQuery插件" href="http://www.cnblogs.com/ATree/archive/2012/02/17/jquery-zSlide-js-CSS3-HTML5.html" target="_blank"&gt;http://www.cnblogs.com/ATree/archive/2012/02/17/jquery-zSlide-js-CSS3-HTML5.html&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;二、为何需要？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;无论是在公司内部，还是在一些技术会议上，我们做分享的时候，用的最多的想必是powerpoint。但是，powerpoint这个东西本身就是缺乏&amp;ldquo;自由&amp;rdquo;与&amp;ldquo;分享&amp;rdquo;精神的，因为其目前无法在线共享。要学习某技术会议上大牛分享的东西，多半要去找资源&amp;rarr;download&amp;rarr;整理或解压或打开之类，资源不好还要清理等等。&lt;/p&gt;&lt;p&gt;oh, my! 像我这样懒得抽筋的人，决不愿意专门去做这种&amp;ldquo;烧水洗脚&amp;rdquo;的事情的！此时，我总不禁慨叹，要是可以直接在浏览器中查看该多好啊&amp;mdash;&amp;mdash;饭来张口，衣来伸手。&lt;/p&gt;&lt;p&gt;其实呢，是有专门的网站做这样的事情的。例如国内的豆丁，风波的百度文库，国外知名的&lt;a href="http://www.slideshare.net/"&gt;slideshare&lt;/a&gt;，但是，考虑到产品兼容性，这些站点的文档演示媒介都是flash，其实也没什么不好啦，就是巧克力里面的坚果外面还包了一层壳，有点让人不爽气！&lt;/p&gt;&lt;p&gt;显然，如果可以使用HTML+JS实现类似powerpoint演示文档的页面效果，即方便资源共享和技术的传播，同时，又具有简洁高效持久性。这就是zSlide诞生的意义所在。&lt;span class="s"&gt;//zxx:以后一些分享我会附上zSlide幻灯片版本。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;三、主要使用人群&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;zSlide插件下的演示文档页面的制作虽然简单，但是，还是需要一定的CSS与HTML技术基础的，因此，zSlide插件的主要使用人群就是web开发者了，尤其是web前端开发er们。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;四、demo体验与示例下载&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;demo&lt;/strong&gt;&lt;br /&gt;您可能狠狠地点击这里：&lt;a class="a_link" href="http://www.zhangxinxu.com/jq/slide/demo.html#slide1" target="_blank"&gt;演示文档jQuery插件zSlide demo&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;下载&lt;/strong&gt;&lt;br /&gt;您可以狠狠地点击这里：&lt;a href="http://files.cnblogs.com/ATree/jquery.zSlide.zip" target="_blank"&gt;上面示例demo源文件打包下载&lt;/a&gt;&lt;/p&gt;&lt;p&gt;插件本身用到的资源有：&lt;br /&gt;&lt;a href="http://www.zhangxinxu.com/jq/slide/css/jquery.zSlide.css"&gt;jquery.zSlide.css&lt;/a&gt;,&lt;br /&gt;jquery.js (官方最新)&lt;br /&gt;&lt;a href="http://www.zhangxinxu.com/jq/slide/js/jquery.zSlide.js"&gt;jquery.zSlide.js&lt;/a&gt;&lt;br /&gt;一个&lt;a href="http://www.zhangxinxu.com/jq/slide/font/iconic_stroke-webfont.ttf"&gt;字符集字体&lt;/a&gt;以及一些HTML&lt;br /&gt;没有使用任何图片&lt;/p&gt;&lt;p&gt;&lt;strong&gt;五、关于浏览&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;浏览方式有两种：&lt;br /&gt;其一为快捷键，PageUp键和PageDown，分别指往前和往后；&lt;br /&gt;其二为按钮（见右下角工具栏），有回到起始页，前进，后退以及快速索引。如下图：&lt;br /&gt;&lt;img class="alignnone" title="如果使用按钮访问zSlide下的slide页面" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_185117.png" alt="如果使用按钮访问zSlide下的slide页面 张鑫旭-鑫空间-鑫生活" width="250" height="171" /&gt;&lt;/p&gt;&lt;p&gt;zSlide插件下如果你要跨界浏览时，页面会提示&amp;ldquo;前面没有&amp;rdquo;或是&amp;ldquo;已经播放结束&amp;rdquo;，如下截图：&lt;br /&gt;&lt;img class="alignnone" title="zSlide跨界时候的提示" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_192836.png" alt="" width="448" height="248" /&gt;&lt;/p&gt;&lt;p&gt;您可能注意到了，zSlide插件含有鼠标隐藏功能，即鼠标如果在上demo页面主体区域保持不动超过3秒，鼠标就会隐藏，移动的时候又会出现。这是为了浏览的时候更好的体验，类似视频浏览~~&lt;/p&gt;&lt;p&gt;&lt;strong&gt;六、关于浏览器支持&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为使用了不少CSS3和HTML5的技术，以及ES5的些东西。因此，支持的浏览器为IE9+，最近版本的FireFox, Opera以及Chrome浏览器。综合来看，Chrome浏览器下的交互效果最好。&lt;/p&gt;&lt;p&gt;顺带一提，本插件不少idea和做法借鉴了jQuery Mobile.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;七、关于界面&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1.顶部&lt;/strong&gt;&lt;br /&gt;顶部为进度条，最右边的数字是总页面，会变的那个数字指当前所在页数。&lt;br /&gt;&lt;img class="alignnone" title="顶部进度条" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_190254.png" alt="zSlide顶部进度条" width="483" height="111" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. 主体&lt;/strong&gt;&lt;br /&gt;主体就是主体了，没什么好说的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3. 底部&lt;/strong&gt;&lt;br /&gt;底部左侧为版权信息，请保留。右侧为工具栏，包含一些交互和自定义的功能。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;提示：&lt;/strong&gt;顶部进度条以及底部的工具条可以通过双击页面的空白区域进行隐藏与显示的切换显示。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;八、关于底部工具条&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;底部工具栏上几个关于浏览的按钮上面已经展示了，不再赘述，现在着重讲讲其他两个重要的交互按钮。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. 定时提醒功能&lt;/strong&gt;&lt;br /&gt;右下角钟一样的图标代表的就是定时提醒功能。平时我们做文档演示应该都是有时间限制的，例如45分钟演讲，15分钟提问。可能我们讲得过于投入一下子忘了时间久不太好了，这时如果演示文档可以卖萌般地提下醒，那就很有意思地啦！&lt;br /&gt;&lt;img class="alignnone" title="zSlide下定时提醒功能图标按钮" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_192243.png" alt="zSlide下定时提醒功能图标按钮 张鑫旭-鑫空间-鑫生活" width="227" height="109" /&gt;&lt;/p&gt;&lt;p&gt;点击后会有类似下图的弹框：&lt;br /&gt;&lt;img class="alignnone" title="定时提醒功能的弹框" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_193055.png" alt="定时提醒功能的弹框 张鑫旭-鑫空间-鑫生活" width="427" height="293" /&gt;&lt;/p&gt;&lt;p&gt;其中总时间是必填的，小于720分钟，也就是12小时，该时间是一定会提醒的。结束前多少时间提醒可以输入多个以非数值分隔的时间值，插件会自动筛选其中合适的时间值（应小于总时间），点击确定按钮后进入定时提醒。&lt;/p&gt;&lt;p&gt;定时提醒功能使用了HTML5 localStorage存储就是，也就是当你不小于关闭了该页面，再次打开该页面的时候，如果检测到您本地有未过期的提醒时间，会提醒你是否使用该时间，如下截图：&lt;br /&gt;&lt;img class="alignnone" title="是否启用之前的提醒时间的提示" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_193643.png" alt="是否启用之前的提醒时间的提示 张鑫旭-鑫空间-鑫生活" width="418" height="257" /&gt;&lt;/p&gt;&lt;p&gt;zSlide插件走的是卖萌路线，其所有的提示都是&amp;ldquo;主人，~&amp;rdquo;开头，那时间提醒举例，根据距离的时间不同，其卖萌的提示也会有所差异，其中就是一个：&lt;br /&gt;&lt;img class="alignnone" title="时间提醒卖萌的提示" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_194113.png" alt="时间提醒卖萌的提示 张鑫旭-鑫空间-鑫生活" width="414" height="251" /&gt;&amp;nbsp;&lt;img class="alignnone" title="zSlide插件时间到了的时候的卖萌提醒" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_194418.png" alt="zSlide插件时间到了的时候的卖萌提醒 张鑫旭-鑫空间-鑫生活" width="409" height="218" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. 自定义背景功能&lt;/strong&gt;&lt;br /&gt;zSlide插件下的默认背景是我&lt;a href="http://www.zhangxinxu.com/"&gt;个人网站&lt;/a&gt;配色的深色基色&lt;code&gt;#34538b&lt;/code&gt;加上一个径向高亮渐变。您可以根据自己的喜好对其进行修改。&lt;/p&gt;&lt;p&gt;点击如下所示图标按钮：&lt;br /&gt;&lt;img class="alignnone" title="zSlide自定义背景按钮" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_195254.png" alt="zSlide自定义背景按钮 张鑫旭-鑫空间-鑫生活" width="189" height="99" /&gt;&lt;/p&gt;&lt;p&gt;在打开的弹框中您可以设置自己喜欢的背景色（建议使用深色背景，例如&lt;code&gt;#123456&lt;/code&gt;），或是自己喜欢的在线图片地址，或者直接从本地选择您喜欢的一张图片（&lt;a href="http://www.zhangxinxu.com/wordpress/?p=1923"&gt;HTML5 File文件Ajax上传本地预览&lt;/a&gt;）。&lt;/p&gt;&lt;p&gt;所有背景的修改都是即时预览的，且100%自适应于浏览器窗体，当您点击取消按钮关闭的时候背景会从预览状态还原。&lt;br /&gt;现在我们从本地随便选取一张图片（需小于500K），然后页面背景就会：&lt;br /&gt;&lt;img class="alignnone" title="zSlide自定义背景图片截图 " src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_201640.jpg" alt="zSlide自定义背景图片截图 张鑫旭-鑫空间-鑫生活" width="514" height="280" /&gt;&lt;/p&gt;&lt;p&gt;如果点击确定按钮的时候&amp;ldquo;记住我的选择&amp;rdquo;处于勾选状态，则下次打开这个页面的时候就会使用该背景图，否则，浏览器一旦关闭，背景还是旧的。&lt;br /&gt;&lt;img class="alignnone" title="zSlide自定义背景处于勾选状态 " src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_202018.png" alt="zSlide自定义背景处于勾选状态 张鑫旭-鑫空间-鑫生活" width="278" height="130" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3. 使用帮助&lt;/strong&gt;&lt;br /&gt;这就是个链接了，就是最右边的那个图标按钮，就是指向本文的。该功能不可自定义。&lt;br /&gt;&lt;img class="alignnone" title="zSlide使用帮助图标链接截图 张鑫旭-鑫空间-鑫生活" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_203526.png" alt="zSlide使用帮助图标链接截图 张鑫旭-鑫空间-鑫生活" width="131" height="116" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;关于工具按钮自定义&lt;/strong&gt;&lt;br /&gt;实际上，右下角的工具栏选项是可以自定义的。完整的工具栏选项如下：&lt;/p&gt;&lt;div class="zxx_code"&gt;$.zSlide.arrayTool = ["Home", "Time", "Background", "Prev", "Index", "Next"];&lt;/div&gt;&lt;p&gt;再初始化的之前，您可以通过改变该数组选项决定哪些工具栏项显示，例如，我们现在把&amp;ldquo;回到初始页&amp;rdquo;这个选项去掉，则如下代码：&lt;/p&gt;&lt;div class="zxx_code"&gt;$(function() {&lt;br/&gt;    $.zSlide.arrayTool = ["Time", "Background", "Prev", "Index", "Next"];&lt;br/&gt;    $.zSlide.init();&lt;br/&gt;});&lt;/div&gt;&lt;p&gt;&lt;strong&gt;九、关于代码部分的使用&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CSS部分&lt;/strong&gt;&lt;br /&gt;如下：&lt;/p&gt;&lt;div class="zxx_code"&gt;&amp;lt;link rel="stylesheet" href="css/jquery.zSlide-min.css" type="text/css" /&amp;gt;&lt;br/&gt;&amp;lt;ink rel="stylesheet" href="css/yourSlide.css" type="text/css" /&amp;gt;&lt;/div&gt;&lt;p&gt;因为幻灯片内容千差万别，因此，一般来讲，每个幻灯片都对应一个特别的内容相关的CSS文件，对应上面的&lt;code&gt;yourSlide.css&lt;/code&gt;。例如demo页面中的&lt;code&gt;demo.css&lt;/code&gt;，对动态载入的图片进行了一些特殊的样式设置。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;提示：&lt;/strong&gt;jquery.zSlide.css只对&lt;code&gt;body&lt;/code&gt;标签reset了一个&lt;code&gt;margin&lt;/code&gt;属性和微软雅黑字体，然后&lt;code&gt;a&lt;/code&gt;标签的颜色和点击样式，&lt;code&gt;pre&lt;/code&gt;标签的样式，其他所有的标签都没有reset。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;JS部分&lt;/strong&gt;&lt;br /&gt;如下：&lt;/p&gt;&lt;div class="zxx_code"&gt;&amp;lt;script src="js/jquery-min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br/&gt;&amp;lt;script src="js/jquery.zSlide-min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br/&gt;&amp;lt;script src="js/yourSlide.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br/&gt;&amp;lt;script&amp;gt;&lt;br/&gt;$(function() {&lt;br/&gt;    &lt;span&gt;/* 可以在初始化之前更改一些信息 */&lt;/span&gt;&lt;br/&gt;    $.zSlide.init();&lt;br/&gt;});&lt;br/&gt;&amp;lt;/script&amp;gt;&lt;/div&gt;&lt;p&gt;与CSS类似，幻灯片中可能会有一些特殊的交互。例如demo页面中为提高性能，对图片所做的的动态延时加载。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;提示：&lt;/strong&gt;zSlide插件采用的是字面量的书写风格，其中所有的参数，方法都是可以全局访问的，然而，除了上面提到的arrayTool参数，其他属性或方法不建议也没有必要去修改。另外zSlide插件中还内置了一个针对这类无滚动页面的弹出框插件zDialog，这个后面会进一步介绍。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;HTML部分&lt;/strong&gt;&lt;br /&gt;HTML部分的头部和尾部是固定不变的，请勿有任何修改。如下：&lt;/p&gt;&lt;div class="zxx_code"&gt;&amp;lt;div id="header" class="zsl_header" data-role="header"&amp;gt;&amp;lt;/div&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;&amp;lt;div id="footer" class="zsl_footer" data-role="footer"&amp;gt;&lt;br/&gt;    &lt;span&gt;&amp;lt;!-- 请保留版权信息 --&amp;gt;&lt;/span&gt;&lt;br/&gt;    &amp;copy; &amp;lt;a href="http://www.zhangxinxu.com/"&amp;gt;zhangxinxu&amp;lt;/a&amp;gt;&lt;br/&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;p&gt;主体部分是有着特定格式的列表。正如前面提到的，本插件借助了一些jQuery Mobile的做法，例如并没有采用HTML5的新标签，标签类似使用自定义属性&lt;code&gt;data-&lt;/code&gt;标示，且这个标示关系到交互行为，是必不可少的。&lt;/p&gt;&lt;p&gt;拿demo页面中第一个很简单的slide页面举例，如下HTML代码：&lt;/p&gt;&lt;div class="zxx_code"&gt;&amp;lt;div id="slide1" class="zsl_slide slide" data-role="slide"&amp;gt;&lt;br/&gt;    &amp;lt;h1 class="zsl_title"&amp;gt;Fade列表测试&amp;lt;/h1&amp;gt;&lt;br/&gt;    &amp;lt;div class="zsl_section"&amp;gt;&lt;br/&gt;        &amp;lt;p class="zsl_fade fade" data-role="fade"&amp;gt;这是data-role为fade的第1行元素&amp;lt;/p&amp;gt;&lt;br/&gt;        &amp;lt;p class="zsl_fade fade" data-role="fade"&amp;gt;这是data-role为fade的第2行元素&amp;lt;/p&amp;gt;&lt;br/&gt;    &amp;lt;/div&amp;gt;&lt;br/&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;p&gt;首先，每个slide页面需要包含在一个&lt;code&gt;data-role="slide"&lt;/code&gt;的&lt;code&gt;div&lt;/code&gt;标签中，其中类名&lt;code&gt;zsl_slide&lt;/code&gt;用做间距美化，&lt;code&gt;slide&lt;/code&gt;为webkit核心浏览器下页面切换动画效果所必须，&lt;code&gt;id&lt;/code&gt;是必须且唯一的（可以没有规律，当然有序的id便于识别）。&lt;/p&gt;&lt;p&gt;如果slide页面中有需要逐步呈现的元素，需要给这些元素设置&lt;code&gt;data-role="fade"&lt;/code&gt;，同时应用这两个类名&lt;code&gt;zsl_fade&lt;/code&gt;和&lt;code&gt;fade&lt;/code&gt;。&lt;br /&gt;一般来讲，&lt;code&gt;zsl_title&lt;/code&gt;和&lt;code&gt;zsl_section&lt;/code&gt;的结构使固定不变的。&lt;/p&gt;&lt;p&gt;在使用的时候，我们需要改动的就是&lt;code&gt;&amp;lt;div class="zsl_section"&amp;gt;&lt;/code&gt;之间的主体内容。且建议使用语义化的标签（div标签避免使用）。&lt;/p&gt;&lt;p&gt;特定的HTML，然后，其他所有的交互都交给zSlide完成，从使用上来讲不可不谓简单。只是，在制作演示文档的时候要花点功夫，因为无法像powerpoint一样可以拖动等可视化操作，但是，对于我们这类经常与浏览器打交道的前端开发者而言，这些都是小菜了，因此，zSlide可以说是专门针对前端开发人员使用的演示文档jQuery插件！&lt;/p&gt;&lt;p&gt;&lt;strong&gt;事件&lt;/strong&gt;&lt;br /&gt;add on 2012-01-04 内容太多，这个给忘了，补上。&lt;/p&gt;&lt;p&gt;您可以在&lt;code&gt;data-role="slide"&lt;/code&gt;的元素上绑定一个&lt;code&gt;slideload&lt;/code&gt;事件，当这个slide页面载入的时候就会执行该方法。例如demo页面中的图片的动态载入，其相关代码就是：&lt;/p&gt;&lt;div class="zxx_code"&gt;$("#slide3").bind("slideload", function() {&lt;br/&gt;    var that = $(this);&lt;br/&gt;    &lt;span&gt;//为了清楚看到延时加载的效果，这里设置了一个1秒的定时器&lt;br/&gt;    //...&lt;/span&gt;&lt;br/&gt;});&lt;/div&gt;&lt;p&gt;相信该事件API会很有用的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;页面间跳转&lt;/strong&gt;&lt;br /&gt;add on 2012-01-04&lt;/p&gt;&lt;p&gt;您可以在页面上使用a标签做自定义的slide页面间的跳转，例如：&lt;/p&gt;&lt;div class="zxx_code"&gt;&amp;lt;a href="#slide3"&amp;gt;跳跳跳&amp;lt;/a&amp;gt;&lt;/div&gt;&lt;p&gt;点击这个&amp;ldquo;跳跳跳&amp;rdquo;链接后，整个演示文档就会指向&lt;code&gt;id&lt;/code&gt;为&lt;code&gt;slide3&lt;/code&gt;的slide页面，实现了无刷新跳转。如果这个&lt;code&gt;id&lt;/code&gt;指向的元素不存在或是不是&lt;code&gt;data-role="slide"&lt;/code&gt;，则演示文档会跳转到第一页，这个是需要注意的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;十、内置zDialog插件介绍&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;zSlide插件中还内置了一个zDialog插件，用来显示一些提示文字或是工具栏的交互操作等。该插件可以全局访问，您可以随意使用，现在简单介绍下。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;zDialog概述&lt;/strong&gt;&lt;br /&gt;zDialog插件是个有针对性（专门针对这种无滚动页面设计的）的插件，其UI应用了很多CSS3属性，定位借助CSS完成（JS亦可调整，只在某些情况下），一次只能打开一个弹框，弹框关闭，里面所有的元素都会被remove，因此不能直接load当前页面上已经存在的元素，否则一次性玩完。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;br /&gt;与zSlide不同，zDialog提供了不少参数API，如下表：&lt;/p&gt;&lt;table class="params_table" style="width: 100%;" border="0" cellspacing="1" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th scope="col"&gt;标题&lt;/th&gt;&lt;th scope="col"&gt;描述&lt;/th&gt;&lt;th scope="col"&gt;默认&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;url&lt;/td&gt;&lt;td&gt;ajax页面地址，文字或HTML字符串&lt;/td&gt;&lt;td&gt;""&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ajax&lt;/td&gt;&lt;td&gt;布尔型 是否是ajax加载。如果是true,则url参数就当作ajax请求地址处理&lt;/td&gt;&lt;td&gt;true&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ajaxData&lt;/td&gt;&lt;td&gt;对象 ajax发送附带参数&lt;/td&gt;&lt;td&gt;{}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;overlay&lt;/td&gt;&lt;td&gt;布尔型 是否显示黑色浅透明遮罩层。默认是显示&lt;/td&gt;&lt;td&gt;true&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;closable&lt;/td&gt;&lt;td&gt;布尔型 是否显示关闭按钮。默认为不显示&lt;/td&gt;&lt;td&gt;false&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;title&lt;/td&gt;&lt;td&gt;字符串 弹框的标题。有则显示，无则不显示&lt;/td&gt;&lt;td&gt;&amp;ldquo;&amp;rdquo;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;pageContainer&lt;/td&gt;&lt;td&gt;jQuery元素对象 加载弹框HTML的容器&lt;/td&gt;&lt;td&gt;$("body")&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;onShow&lt;/td&gt;&lt;td&gt;函数 弹框显示时调用的方法&lt;/td&gt;&lt;td&gt;$.noop&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;onClose&lt;/td&gt;&lt;td&gt;函数 弹框完全关闭时调用的方法&lt;/td&gt;&lt;td&gt;$.noop&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;基本使用&lt;/strong&gt;如下：&lt;/p&gt;&lt;div class="zxx_code"&gt;$.zDialog.open({&lt;br/&gt;    url: 'ajax.php',&lt;br/&gt;    title: '测试',&lt;br/&gt;    closable: true,&lt;br/&gt;    onShow: function() {&lt;br/&gt;        alert('加载成功咯~~');&lt;br/&gt;    }&lt;br/&gt;});&lt;/div&gt;&lt;p&gt;一些&lt;strong&gt;内置的API方法&lt;/strong&gt;有：&lt;br /&gt;1. $.zDialog.alert(message, callback, options);&lt;br /&gt;&lt;img class="alignnone" title="zSlide插件时间到了的时候的卖萌提醒" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_194418.png" alt="zSlide插件时间到了的时候的卖萌提醒 张鑫旭-鑫空间-鑫生活" width="409" height="218" /&gt;&lt;br /&gt;例如上面这张图的效果就是如下一行代码搞定的：&lt;/p&gt;&lt;div class="zxx_code"&gt;$.zDialog.alert("主人，时间到了，喵~~");&lt;/div&gt;&lt;p&gt;&lt;code&gt;callback&lt;/code&gt;参数为点击确定按钮时候执行的回调，&lt;code&gt;options&lt;/code&gt;参数一般都是打酱油的。&lt;/p&gt;&lt;p&gt;2. $.zDialog.confirm(message, sureCall, cancelCall, options);&lt;br /&gt;确认提示框，例如下面这个效果即使使用的这个方法：&lt;br /&gt;&lt;img class="alignnone" title="是否启用之前的提醒时间的提示" src="http://image.zhangxinxu.com/image/blog/201201/2012-01-03_193643.png" alt="是否启用之前的提醒时间的提示 张鑫旭-鑫空间-鑫生活" width="418" height="257" /&gt;&lt;/p&gt;&lt;p&gt;各个参数的含义一目了然，我就不啰嗦了。&lt;code&gt;options&lt;/code&gt;参数同样一般都是打酱油的。&lt;/p&gt;&lt;p&gt;3. $.zDialog.remind(message, options);&lt;br /&gt;直接提示框，没有关闭按钮，例如：&lt;/p&gt;&lt;div class="zxx_code"&gt;$.zDialog.remind("页面跳转中...");&lt;/div&gt;&lt;p&gt;4. $.zDialog.loading(options);&lt;br /&gt;&amp;ldquo;加载中&amp;rdquo;效果提示框，例如ajax load页面的时候，插件会自动调用该方法。&lt;/p&gt;&lt;p&gt;5. $.zDialog.position();&lt;br /&gt;弹框的JS重定位。该方法用在弹框内容宽度超过最小宽度很多或是高度超过最小高度很多的时候使用，例如zSlide插件中的自定义背景效果的弹框&amp;mdash;&amp;mdash;&lt;/p&gt;&lt;div class="zxx_code"&gt;$.zDialog.open({&lt;br/&gt;    url: 'some HTML',&lt;br/&gt;    ajax: false&lt;br/&gt;}).position();&lt;/div&gt;&lt;p&gt;6. $.zDialog.close();&lt;br /&gt;弹框关闭方法，调用该方法会触发onClose回调，且Chrome等浏览器下会有pop动画效果。&lt;/p&gt;&lt;p&gt;7. $.zDialog.remove();&lt;br /&gt;弹框移出方法，调用该方法不会触发onClose回调，也没有任何动画效果，元素直接从页面上bye bye.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;转自：&lt;a href="http://www.zhangxinxu.com/wordpress/?p=2136"&gt;http://www.zhangxinxu.com/wordpress/?p=2136&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ATree/aggbug/2355781.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ATree/archive/2012/02/17/jquery-zSlide-js-CSS3-HTML5.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ATree/archive/2011/11/10/jQuery-vs-MooTools.html</id><title type="text">(jQuery) VS (MooTools) API与性能的比较</title><summary type="text">毋庸置疑的是jQuery和MooTools都是非常优秀的轻量级的JavaScript框架。jQuery以其出色的API，出色的插件机制，以及在DOM方面的关注使其大受欢迎。然而，在面对大型项目的时候，其在一些功能特性上的缺失往往需要借助插件。如果团队没有有牛人把关的话，插件的滥用，人人都插一手的代码会把项目代码质量逐渐变成狗屎的。一般而言，jQuery更适合与动态的中小站点。MooTools插件虽然在API &amp; DOM和上手容易程度上都上不及jQuery，但是，其API以及面向对象的设计思想似乎在实际的大项目中更有价值。</summary><published>2011-11-10T00:33:00Z</published><updated>2011-11-10T00:33:00Z</updated><author><name>zock</name><uri>http://www.cnblogs.com/ATree/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ATree/archive/2011/11/10/jQuery-vs-MooTools.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ATree/archive/2011/11/10/jQuery-vs-MooTools.html"/><content type="html">&lt;p&gt;&lt;strong&gt;一、API设计&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;就API的设计上来讲，无论是&lt;a title="Mootools" href="http://www.cnblogs.com/ATree/tag/Mootools/"&gt;MooTools&lt;/a&gt;，或是其他类似YUI的JS框架都比&lt;a title="JQuery" href="http://www.cnblogs.com/ATree/tag/JQuery/"&gt;jQuery&lt;/a&gt;略逊一筹。&lt;/p&gt;&lt;p id="jmTest"&gt;API是什么？根据某些著作的回答，API是对所需知识的抽象，它将系统的复杂性隐藏起来。例如汽车的方向盘，电视机上的按钮。一个API设计的好坏可以从下面几个方面评估：可理解性、一致性、预见性、简单性、保护性。&lt;/p&gt;&lt;div id="content_atree"&gt;&lt;em&gt;如果你看到这段文字，说明您正使用RSS阅读或转自《一棵树-博客园》，原文地址：&lt;a id="Editor_Edit_hlEntryLink" title="view: (jQuery) VS (MooTools) API与性能的比较" href="http://www.cnblogs.com/ATree/archive/2011/11/09/jQuery-vs-MooTools.html" target="_blank"&gt;http://www.cnblogs.com/ATree/archive/2011/11/09/jQuery-vs-MooTools.html&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;可理解性&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;例如&lt;code&gt;selector&lt;/code&gt;(选择器)。随便举个选择器的例子(jQuery)：&lt;/div&gt;&lt;div class="zxx_code"&gt;$("#jQuery div")&lt;/div&gt;&lt;p&gt;选择器的写法是与CSS的选择器是一脉相承的。因此对于很多写页面的人来讲，可以很轻松地使用jQuery找到自己想要的那根葱。jQuery后来的版本之所以把XPath干掉，或许就是因为理解性上的问题吧。当然，MooTools也是支持CSS选择器的，只不过，其不是使用一个美元符号$，而是两个$$，貌似是学习prototype框架，返回的是数组。&lt;/p&gt;&lt;div class="zxx_code"&gt;$$("#MooTools div")&lt;/div&gt;&lt;p&gt;如果MooTools只走到这一步，我觉得还好，貌似跟jQuery的可理解性打个小平手。只可惜，MooTools还有一个单个美元符号$的选择器，其中参数只能是元素的id，例如：&lt;/p&gt;&lt;div class="zxx_code"&gt;$("MooTools")&lt;/div&gt;&lt;p&gt;这玩意，选择的貌似是有个MooTools元素扩展方法的对象。如果不存在，应用元素方法的时候(eg: addClass)则会报错。&lt;/p&gt;&lt;p&gt;也就是说MooTools选择元素，根据用法的不同，有时候返回的可能就是数组，有时候又是元素对象。这难免让对JS熟悉，对CSS较熟悉的人员有了理解和使用上的困难了。不过这不能怪MooTools，设计架构上的不同导致MooTools有时候需要返回元素对象，而不是元素对象数组。&lt;/p&gt;&lt;p&gt;因此，从理解性上来说，MooTools逊于jQuery了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;一致性&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;JS框架的一致性的主要体现之一就是链式调用，例如(jQuery)：&lt;/div&gt;&lt;div class="zxx_code"&gt;$("#jQuery").css("color", "red").height(200);&lt;/div&gt;&lt;p&gt;MooTools也是支持链式调用的，例如(MooTools)：&lt;/p&gt;&lt;div class="zxx_code"&gt;$$("#MooTools").setStyle("color", "red").setStyle("height", 200);&lt;/div&gt;&lt;p&gt;在链式调用上，jQuery和MooTools基本上都是很OK的。&lt;/p&gt;&lt;p&gt;但是，在其他方面的一致性上，MooTools似乎又落于下风了。jQuery这个框架真的很神奇，一个&lt;code&gt;$&lt;/code&gt;符号就可以从广州走到北京，真可谓万能密匙啊。&lt;br /&gt;首先选择器，例如&lt;code&gt;$("#jQuery")&lt;/code&gt;肯定是&lt;code&gt;$&lt;/code&gt;符号，然后，其相关的其他些方法，例如插件机制之&lt;code&gt;$.fn.extend(object)&lt;/code&gt;，或者是Ajax请求&lt;code&gt;$.ajax([options])&lt;/code&gt;，又或是浏览器检测，数组对象方法等等等等都是&lt;code&gt;$&lt;/code&gt;符号横行的。&lt;/p&gt;&lt;p&gt;但是，MooTools桑中&lt;code&gt;$&lt;/code&gt;符号出现在选择器，让人难懂的&lt;code&gt;$A&lt;/code&gt;,&amp;nbsp;&lt;code&gt;$E&lt;/code&gt;，以及一些公共方法命名上，其余时候都回家睡觉觉了。&lt;br /&gt;继承需要&lt;code&gt;new Class()&lt;/code&gt;构造，Ajax请求为&lt;code&gt;new Request([options])&lt;/code&gt;，然后浏览器检测又是以&lt;code&gt;Browser&lt;/code&gt;开头。数组，字符串等方法又都是当前对象本身打头，如&lt;code&gt;myString.trim()&lt;/code&gt;。毫无一致性可言，显然，这个的学习成本和使用难度要比jQuery大多了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;预见性&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;好的API应该考虑到用户的无绪性选择(&lt;code&gt;selective cluelessness&lt;/code&gt;)以及预见未来可能发生的一些事情。&lt;/div&gt;&lt;p&gt;不知是John Resig(jQuery 之父)确实想的很远，还是因为幸运，或是只因为John是个天才，jQuery的设计让其似乎不会与未来发生冲突。&lt;br /&gt;举个老到啃不动的例子，过滤字符串的前后空格。jQuery的做法是：&lt;/p&gt;&lt;div class="zxx_code"&gt;$.trim(myString);&lt;/div&gt;&lt;p&gt;MooTools做法是：&lt;/p&gt;&lt;div class="zxx_code"&gt;myString.trim();&lt;/div&gt;&lt;p&gt;乍一看，似乎MooTools框架的做法更符合我们的理解 &amp;rarr; 字符串对象有个&lt;code&gt;trim&lt;/code&gt;方法，返回过滤前后空格的字符串方法。However，随着时间拖移，有些事情就开始发生变数了。&lt;/p&gt;&lt;p&gt;在ECMAScript 5(ES5)中，字符串是内置&lt;code&gt;trim&lt;/code&gt;方法的。我们可以做个小小的测试，如下代码：&lt;/p&gt;&lt;div class="zxx_code"&gt;alert((" foo ").trim());&lt;/div&gt;&lt;p&gt;您可以狠狠地点击这里：&lt;a class="a_link" href="http://www.zhangxinxu.com/study/201109/es5-trim-test.html" target="_blank"&gt;ES5 内置trim方法测试&lt;/a&gt;&lt;/p&gt;&lt;p&gt;例如，在我的FireFox 6浏览器下，弹出的就是&lt;code&gt;foo&lt;/code&gt;，如下截图：&lt;br /&gt;&lt;img src="http://image.zhangxinxu.com/image/blog/201109/2011-09-27_111730.png" alt="FireFox 6 弹出foo" width="278" height="187" /&gt;&lt;/p&gt;&lt;p&gt;对于一些有历史价值的浏览器，就不支持，例如IE7模式下：&lt;br /&gt;&lt;img id="testImage" src="http://image.zhangxinxu.com/image/blog/201109/2011-09-27_112537.png" alt="" width="457" height="211" /&gt;&lt;/p&gt;&lt;p&gt;同样类似的就是基于Function扩展的&lt;code&gt;bind&lt;/code&gt;方法，MooTools中有，但是，ES5中也内置了。只是，比较幸运的是，无论是字符串&lt;code&gt;trim&lt;/code&gt;方法，或是函数&lt;code&gt;bind&lt;/code&gt;方法，虽然名称冲突了，但是，所实现的功能确是一样的，因此，也算不上冲突了。但是，万一哪天遇到个不幸，MooTools中的某个方法与ES5中的方法同名但不同功能，然后，只能老泪纵横了！&lt;/p&gt;&lt;p&gt;再举个预见性的例子，选择器选择对象以及DOM对象。jQuery对jQuery对象和原生dom对象进行了分离，例如：&lt;/p&gt;&lt;div class="zxx_code"&gt;$("input").bind("focus", function() {&lt;br/&gt;    alert(this.value);    &lt;span&gt;// dom对象&lt;/span&gt;&lt;br/&gt;    alert($(this).val());   &lt;span&gt;// jQuery包装器对象&lt;/span&gt;&lt;br/&gt;});&lt;/div&gt;&lt;p&gt;但是，在MooTools中，一些方法是在原生DOM上扩展的，MooTools元素对象和原生dom是合体的，例如：&lt;/p&gt;&lt;div class="zxx_code"&gt;$$("input").addEvent("focus", function() {&lt;br/&gt;    alert(this.value);           &lt;span&gt;// dom对象&lt;/span&gt;&lt;br/&gt;    alert(this.get("value"));    &lt;span&gt;// 扩展后的dom对象&lt;/span&gt;&lt;br/&gt;});&lt;/div&gt;&lt;p&gt;&amp;ldquo;合体&amp;rdquo;的问题在于随着浏览器以及一些规范的发展，原生dom可能会支持其他的一些方法，这些方法有可能就和MooTools插件中DOM扩展方法冲突。好在MooTools的方法命名属于对称命名，且语义明显，这种设计可以有效避免与原生dom方法的冲突。但是，事情没有这简单&amp;hellip;&amp;hellip;下面你可以看到MooTools中DOM元素方法的设计的一些问题（当然，不可否认，这种设计使用上相对灵活些）。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;简单性&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;jQuery之所以让开发者恋恋不舍，原因之一就是其简单。jQuery的口号就是"write less, do more."&lt;/div&gt;&lt;p&gt;拿dom-style的API举例，MooTools, YUI等框架采用的是传统对称命名的方式(prop为property属性缩写)：&lt;/p&gt;&lt;div class="zxx_code"&gt;el.setStyle(prop, val);&lt;br/&gt;el.getStyle(prop);&lt;br/&gt;el.setStyles({ propA: valA, propB: valB });&lt;br/&gt;el.getStyles(propA, propB);  &lt;span&gt;// MooTools支持, 返回是个名-值对象&lt;/span&gt;&lt;/div&gt;&lt;p&gt;在jQuery里，一个CSS就把所有瓷器活都揽了：&lt;/p&gt;&lt;div class="zxx_code"&gt;el.css(prop);    &lt;span&gt;// 表示 getStyle&lt;/span&gt;&lt;br/&gt;el.css(prop, val);    &lt;span&gt;// 表示 setStyle&lt;/span&gt;&lt;br/&gt;el.css({ propA: valA, propB: valB });    &lt;span&gt;// 表示 setStyles &lt;/span&gt;&lt;br/&gt;el.css(prop, func);    &lt;span&gt;// func 是一个返回 val 值的函数&lt;/span&gt;   &lt;/div&gt;&lt;p&gt;虽然参数类似，但是jQuery只要记一个名字，而MooTools却要N个，且名字也比较长（必须完整且长，否则易出问题）。这也是为什么jQuery更容易上手的原因。而且，jQuery更近一步，还支持&lt;code&gt;func&lt;/code&gt;回调，且参数可以&lt;code&gt;map&lt;/code&gt;,&amp;nbsp;&lt;code&gt;val&lt;/code&gt;可以是函数，暗藏多多surprise啊。&lt;/p&gt;&lt;p&gt;显然，简单性这块又是jQuery好一些。&lt;br /&gt;这里，我还想说点其他相关的东西。jQuery框架的短命名设计确实好，于是我就想对MooTools的元素方法进行扩展，使等同于jQuery的命名书写方式，一是省些代码，二是方便熟悉jQuery的新员工上手，拿还是上面dom-style的例子，MooTools如下扩展处理：&lt;/p&gt;&lt;div class="zxx_code"&gt;Element.implement({&lt;br/&gt;    &lt;span&gt;//将mootools默认的setStyle以及setStyles方法转化为与jQuery类似的css()形式&lt;/span&gt;&lt;br/&gt;    css: function(key, value) {&lt;br/&gt;        if ($type(key) == 'object') {&lt;br/&gt;            for (var p in key) this.css(p, key[p]);&lt;br/&gt;            return this;&lt;br/&gt;        }&lt;br/&gt;        if(!$chk(value)){&lt;br/&gt;            return this.&lt;span&gt;getStyle&lt;/span&gt;(key);&lt;br/&gt;        }&lt;br/&gt;        this.&lt;span&gt;setStyle&lt;/span&gt;(key, value);&lt;br/&gt;        return this;&lt;br/&gt;    }&lt;br/&gt;});&lt;/div&gt;&lt;p&gt;于是，MooTools也支持CSS方法，例如可以直接&lt;code&gt;$("mootools").css({ border: "1px solid #ddd" });&lt;/code&gt;。恩，看上去不错，确实，上面的扩展在目前各个浏览器中是没有任何问题的。于是，初尝到了甜头，我们就想模拟其他jQuery包装器方法的扩展，例如&lt;code&gt;width/height&lt;/code&gt;方法，如下(&lt;code&gt;width&lt;/code&gt;举例)：&lt;/p&gt;&lt;div class="zxx_code"&gt;Element.implement({&lt;br/&gt;    width: function (val) {&lt;br/&gt;        if ($chk(val)) {&lt;br/&gt;            return this.setStyle("width", val);&lt;br/&gt;        } else {&lt;br/&gt;            return this.getWidth();&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;});&lt;/div&gt;&lt;p&gt;看上去不错，不是吗？但是，人生不如意事八九，上面MooTools框架对dom进行的&lt;code&gt;width&lt;/code&gt;方法扩展是有问题的。我们都知道，&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;元素是有&lt;code&gt;width&lt;/code&gt;属性的。正如上面提到的，MooTools框架的元素方法是在DOM上面直接&amp;ldquo;合体&amp;rdquo;扩展的。于是乎，对于图片而言，使用上面扩展的&lt;code&gt;width&lt;/code&gt;方法是会嗝屁的&amp;mdash;&amp;mdash;原生属性与扩展方法冲突。&lt;/p&gt;&lt;div class="zxx_code"&gt;alert($("image").width()); &lt;span&gt;//报错，显示$("image").width不是function&lt;/span&gt;&lt;/div&gt;&lt;p&gt;由此又进一步证实了jQuery在API设计上更能避免一些当下或未来潜在的冲突，更具远见性。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;保护性&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;jQuery有个多库共存机制，可以有效地保护其他框架都在争夺的$符号，有效避免了一些兼容性的问题。&lt;/div&gt;&lt;div class="zxx_code"&gt;jQuery.noConflict();&lt;br/&gt;(function($) {&lt;br/&gt;  $(function() {&lt;br/&gt;    &lt;span&gt;// 使用 $ 作为 jQuery 别名的代码&lt;/span&gt;&lt;br/&gt;  });&lt;br/&gt;})(jQuery);&lt;br/&gt;&lt;span&gt;// 其他用 $ 作为别名的库的代码&lt;/span&gt;&lt;/div&gt;&lt;p&gt;而MooTools中似乎并无这样的机制。&lt;/p&gt;&lt;p&gt;总结：就API设计这点来讲，jQuery几乎从各个方面都强于MooTools，这也是jQuery大行其道的主要原因。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;二、性能&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;选择器性能&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;MooTools框架官方页面提供了选择器性能测试页面：&lt;a href="http://mootools.net/slickspeed/" target="_blank"&gt;speed/validity selectors test for frameworks&lt;/a&gt;&lt;/p&gt;&lt;p&gt;点击右上角的"start tests"按钮，一段时间后就可以看到各个框架下各个选择器测试结果了。下表为我联系测试三次后的结果记录，可以看到，jQuery选择器的总体性能略比prototype低，比MooTools要强。但是，在我们实际些页面做交互的时候，其中选择器的差异基本上可以忽略不记（YUI在&lt;code&gt;:nth-child&lt;/code&gt;选择器上的糟糕表现肯定要提防的）。&lt;/p&gt;&lt;table class="params_table" style="width: 100%;" border="0" cellspacing="1" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th scope="col"&gt;&amp;nbsp;&lt;/th&gt;&lt;th scope="col"&gt;MooTools 1.2&lt;/th&gt;&lt;th scope="col"&gt;MooTools 1.3.1&lt;/th&gt;&lt;th scope="col"&gt;JQuery 1.5.1&lt;/th&gt;&lt;th scope="col"&gt;Prototype 1.7&lt;/th&gt;&lt;th scope="col"&gt;YUI 2.8.2 Selector&lt;/th&gt;&lt;th scope="col"&gt;Dojo 1.5&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope="row"&gt;第一次测试总时间&lt;/th&gt;&lt;td&gt;75&lt;/td&gt;&lt;td&gt;67&lt;/td&gt;&lt;td&gt;37&lt;/td&gt;&lt;td&gt;34&lt;/td&gt;&lt;td&gt;685&lt;/td&gt;&lt;td&gt;49&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope="row"&gt;第二次测试总时间&lt;/th&gt;&lt;td&gt;66&amp;nbsp;&lt;/td&gt;&lt;td&gt;56&amp;nbsp;&lt;/td&gt;&lt;td&gt;28&amp;nbsp;&lt;/td&gt;&lt;td&gt;26&lt;/td&gt;&lt;td&gt;668&amp;nbsp;&lt;/td&gt;&lt;td&gt;48&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th scope="row"&gt;第三次测试总时间&lt;/th&gt;&lt;td&gt;67&lt;/td&gt;&lt;td&gt;55&lt;/td&gt;&lt;td&gt;30&lt;/td&gt;&lt;td&gt;30&lt;/td&gt;&lt;td&gt;663&lt;/td&gt;&lt;td&gt;43&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;img src="http://image.zhangxinxu.com/image/blog/201109/2011-09-27_172010.png" alt="" width="514" height="268" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;dom操作性能&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;本来想从网上找一下MooTools和jQuery框架在dom操作这块的性能对比数据，结果发现，压根就没有，连个沾边的都没有。在这艰难困苦的时候，想起了伟大领袖毛主席的一句话：&amp;ldquo;自力更生，艰苦创业&amp;rdquo;。心中的小宇宙顿时爆发了，快刀乱麻，一番折腾后弄出了自己想要的测试页面。&lt;/p&gt;&lt;p&gt;您可以狠狠地点击这里：&lt;a class="a_link" href="http://www.zhangxinxu.com/study/201109/jquery-mootools-dom-operate-speed-test.html" target="_blank"&gt;MooTools与jQuery一些dom操作性能对比&lt;/a&gt;&lt;/p&gt;&lt;p&gt;下面就是测试结果哈：&lt;/p&gt;&lt;table class="table_test"&gt;&lt;thead id="thead"&gt;&lt;tr&gt;&lt;th class="selectors-title"&gt;attr&lt;/th&gt;&lt;th class="framework"&gt;MooTools 1.3.1&lt;/th&gt;&lt;th class="framework"&gt;JQuery 1.5.1&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody id="tbody"&gt;&lt;tr&gt;&lt;th class="selector"&gt;setStyle/css&lt;/th&gt;&lt;td class="test bad"&gt;79 ms | 1 found&lt;/td&gt;&lt;td class="test good"&gt;53 ms | 1 found&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th class="selector"&gt;setStyles/cssMulti&lt;/th&gt;&lt;td class="test bad"&gt;200 ms | 1 found&lt;/td&gt;&lt;td class="test good"&gt;109 ms | 1 found&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th class="selector"&gt;setProperty/attr&lt;/th&gt;&lt;td class="test good"&gt;37 ms | 1 found&lt;/td&gt;&lt;td class="test bad"&gt;43 ms | 1 found&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th class="selector"&gt;setProperties/attrMulti&lt;/th&gt;&lt;td class="test good"&gt;51 ms | 1 found&lt;/td&gt;&lt;td class="test bad"&gt;55 ms | 1 found&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th class="selector"&gt;addClass&lt;/th&gt;&lt;td class="test bad"&gt;40 ms | 1 found&lt;/td&gt;&lt;td class="test good"&gt;18 ms | 1 found&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th class="selector"&gt;addClassMulti&lt;/th&gt;&lt;td class="test bad"&gt;54 ms | 1 found&lt;/td&gt;&lt;td class="test good"&gt;25 ms | 1 found&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th class="selector"&gt;hasClass&lt;/th&gt;&lt;td class="test bad"&gt;75 ms | 1 found&lt;/td&gt;&lt;td class="test good"&gt;24 ms | 1 found&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th class="selector"&gt;removeClass&lt;/th&gt;&lt;td class="test bad"&gt;118 ms | 1 found&lt;/td&gt;&lt;td class="test good"&gt;23 ms | 1 found&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th class="selector"&gt;removeClassMulti&lt;/th&gt;&lt;td class="test bad"&gt;109 ms | 1 found&lt;/td&gt;&lt;td class="test good"&gt;10 ms | 1 found&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;tfoot id="tfoot"&gt;&lt;tr&gt;&lt;th class="score-title"&gt;&lt;strong&gt;最终结果(越小越好)&lt;/strong&gt;&lt;/th&gt;&lt;td class="score"&gt;&amp;nbsp;763&amp;nbsp;&lt;/td&gt;&lt;td class="score"&gt;&amp;nbsp;360&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/tfoot&gt;&lt;/table&gt;&lt;p&gt;可以看到，除了&lt;code&gt;setProperty/attr&lt;/code&gt;和&lt;code&gt;setProperties/attrMulti&lt;/code&gt;方法MooTools框架性能是略微占优外，其余一些dom相关操作都完败jQuery。&lt;/p&gt;&lt;p&gt;小小总结：就性能这块。MooTools框架无论是选择器或是其他一些方法性能都逊于jQuery。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;三、MooTools的优势在于？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;根据上面两项的对比，MooTools框架在API方面没有jQuery优秀，一些DOM相关操作性能也没有jQuery好，那我们还有什么理由选择MooTools框架呢？MooTools框架的优势在什么地方呢？&lt;/p&gt;&lt;p&gt;在讲述MooTools优势之前我想讲点题外话，有位MooTools团队成员曾说如如下让人值得思考的话：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;The MooTools team (of which I am a part) has never really focused on how popular the framework is. We are interested in writing it for our own use and for its own sake, but we don't really spend much energy trying to convince other people to use it. We don't consider ourselves adversaries to other frameworks - as I've heard it put on numerous recent occassions, we're at war with the browsers, not each other. In my own posts on the topic, my suggestion to people is to try a couple of options and choose the framework that suits your needs and your styles. You really can't make a bad choice (so please stop arguing about it!). jQuery, Prototype. YUI, Dojo, MooTools - we're all doing the same things just using different methods.&lt;/p&gt;&lt;p&gt;MooTools团队（我也是其中之一）从来没有真正关注过这个框架有 多受欢迎。我们只是对写这个框架感兴趣，为我们自己使用和它本身目的去写，但是我们真的没有花很多精力去让其他人去使用这个框架。我们从不认为其它框架是 我们的竞争对手&amp;mdash;&amp;mdash;因为我曾经在很多场合都听说过这样的话，我们在和浏览器进行斗争，而不是相互斗争。在我的这篇文章中，我给你们的建议是：多尝试一些选择，然后选择适合你的需求和你的风格的框架。你真的不能做一个坏的选择（因此，请停止争吵！）。jQuery、Prototype、YUI、Dojo、 MooTools&amp;mdash;&amp;mdash;我们都只是用不同的方法在做同样的事。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;当初我第一次听史仲冬说MooTools库的时候，心里有嘀咕：这玩意，基本上都没听过，也没有什么人使用，应该是个稀奇古怪，糟糕的框架吧。但是，当我逐渐了解这个JS框架后，越来越喜欢之，其喜欢程度已经超过jQuery，因为它比jQuery更适合当前我所做的项目&amp;mdash;&amp;mdash;项目大，大数据量处理以及很多复杂交互。&lt;/p&gt;&lt;p&gt;jQuery的因为其出色的API，使得即使不怎么懂JavaScript的人也能写出一些自以为靠谱的代码。再加上jQuery的重心放在了DOM上，这正好讨了热衷于页面效果交互的一些designer和csser的欢心。如果要构建中小型动态Web站点，用jQuery没错。快速、简单、优雅、漂亮。如果我是一个设计者，我也会使用它的。&lt;/p&gt;&lt;p&gt;但是，如果是有着成百上千页面的大项目，有些大数据量交互与处理的项目，多人合作，多模块化的项目，jQuery往往就显得底气不足，往往需要各类插件补充。要知道，jQuery插件成百上千，但大多都是狗屎。如果没有牛人把控，项目最后也就变成了狗屎！&lt;/p&gt;&lt;p&gt;MooTools虽然也能用在中小项目上，但是，其潜力的发挥要在大型、需要编写大量JavaScript的应用的网站项目上。这就是MooTools的优势。当然，我说话都是讲证据的，下面我就挑几点说说为何大型网站项目更适合MooTools而不是jQuery。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;更多的对象方法扩展&lt;/strong&gt;&lt;br /&gt;虽然说，MooTools框架直接在Array, Function对象上做方法扩展有可能会造成语后来JavaScript规范出现重复或冲突的情况，但是，不可否认的是，这些对象方法的扩展对我们的开发节约了很多的功夫。&lt;/p&gt;&lt;p&gt;例如字符串方法的扩展。在jQuery中，字符串相关操作的方法貌似就只有一个&lt;code&gt;trim&lt;/code&gt;。&lt;br /&gt;但是，在MooTools中，框架自带字符串扩展方法就有14个之多，例如字符串内容检测的&lt;code&gt;contains&lt;/code&gt;方法，清除整个字符串中多余的空白字符串的&lt;code&gt;clean&lt;/code&gt;方法，转义正则表达式敏感字符的&lt;code&gt;escapeRegExp&lt;/code&gt;方法，或是取整&lt;code&gt;toInt()&lt;/code&gt;以及rgb颜色和16进制颜色相关转化的字符串方法等等。在大数据量交互的时候，字符串相关处理是很多的，MooTools框架自带的这些字符串扩展方法不可不谓带来N多便捷。&lt;/p&gt;&lt;p&gt;不仅仅是字符串，MooTools对数值，函数以及数组对象都进行了扩展。尤其数组，除了其原生的方法外，MooTools还对其扩展了近20个方法。这使得偶们在处理数组的时候基本上所向披靡了。总之，MooTools框架在各类JavaScript类型对象上做了新方法的扩展，以便我们可以更轻松更简单地应付各类复杂应用和众多数据处理。这显然与jQuery重在DOM的设计理念不同了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;数据处理利器之Hash概念&lt;/strong&gt;&lt;br /&gt;Hash，俗称哈希，是jQuery中没有而MooTools中有且很赞的一个玩意。Hash是一个重新实现的Object({}), 被专门用于数据的存取，和原来的Object({})的区别是： 它不会在进行存值，取值或迭代的时候处理对象的prototype中的内容。在MooTools中，Hash对象和Array对象(json基本构成啦)联合使用，不是我吹，再TM庞杂的数据，都能轻松应付。这让我想起了我们小秘书餐厅详细页的选菜交互，如果没有Hash这个玩意，我可真不知道该如何下手；或句话说，如果不是使用的MooTools作为框架，而是jQuery；这里的复杂的交互实现估计就是一场梦了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;面向对象的设计思想&lt;/strong&gt;&lt;br /&gt;MooTools是一款面向对象的设计思想框架。讲求继承，模块化与重用性。虽然说其&lt;code&gt;new Class({})&lt;/code&gt;的构造有些让人不好理解，使用也颇有些既定规则，但是，实际上，这玩意要是能&amp;ldquo;挺过去&amp;rdquo;，还真的很有用的。举个关于半透明遮罩层的例子吧。我们构建一个名叫Overlay的类，然后其相关的代码就如下：&lt;/p&gt;&lt;div class="zxx_code"&gt;var Overlay = new Class({&lt;br/&gt;    Implements: [Options, Events],&lt;br/&gt;    getOptions: function() {&lt;br/&gt;        return {&lt;br/&gt;            name:'',&lt;br/&gt;            duration: 200,&lt;br/&gt;            colour: '#000',&lt;br/&gt;            opacity: 0.35,&lt;br/&gt;            zIndex: 99,&lt;br/&gt;            container: document.body,&lt;br/&gt;            onClick: $empty&lt;br/&gt;        };&lt;br/&gt;    },&lt;br/&gt;    initialize: function(options) {&lt;br/&gt;        &lt;span&gt;//......&lt;/span&gt;&lt;br/&gt;        return this.position();&lt;br/&gt;    },&lt;br/&gt;    position: function() {&lt;br/&gt;        &lt;span&gt;//......&lt;/span&gt;&lt;br/&gt;    },&lt;br/&gt;    show: function() {&lt;br/&gt;        &lt;span&gt;//......&lt;/span&gt;&lt;br/&gt;    },&lt;br/&gt;    hide: function(dispose) {&lt;br/&gt;        &lt;span&gt;//......&lt;/span&gt;&lt;br/&gt;    },&lt;br/&gt;    dispose: function() {&lt;br/&gt;        &lt;span&gt;//......&lt;/span&gt;&lt;br/&gt;    }&lt;br/&gt;});&lt;/div&gt;&lt;p&gt;于是，当我们需要半透明遮罩层的时候，直接：&lt;/p&gt;&lt;div class="zxx_code"&gt;var myOverlay = new Overlay();&lt;/div&gt;&lt;p&gt;Overlay类中的&lt;code&gt;position&lt;/code&gt;,&amp;nbsp;&lt;code&gt;hide&lt;/code&gt;,&amp;nbsp;&lt;code&gt;show&lt;/code&gt;等方法都是外部可见的。我们可是使用类似：&lt;/p&gt;&lt;div class="zxx_code"&gt;myOverlay.hide()&lt;/div&gt;&lt;p&gt;让遮罩层隐藏。当然，我们可以再定义一个新的类，这个类继承或使用Overlay类，例如我们很常用的弹框效果咯，等等。虽然，MooTools这种强制面向对象风格的设计有些淡化了JavaScript语言本身的一些优美特性。但是，当项目庞大，JavaScript代码量巨大的时候，这种面向对象的设计理念还是相当受用的。项目越大，偶们所节省的代码量就越多。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Cookie的读写&lt;/strong&gt;&lt;br /&gt;MooTools框架自带Cookie读写的方法，支持指定域和路径。而jQuery框架中要想实现Cookie的读写，需要借助于专门的cookie插件，额外的插件，显然jQuery就折腾了。&lt;a href="http://www.zhangxinxu.com/wordpress/2011/09/html5-localstorage%e6%9c%ac%e5%9c%b0%e5%ad%98%e5%82%a8%e5%ae%9e%e9%99%85%e5%ba%94%e7%94%a8%e4%b8%be%e4%be%8b/"&gt;HTML5 localStorage本地存储实际应用&lt;/a&gt;这篇文章的IE浏览器Cookie的读写就是使用MooTools框架自带的Cookie方法。很简单，很好使用。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;swf文件的载人&lt;/strong&gt;&lt;br /&gt;MooTools框架自带&lt;code&gt;Swiff&lt;/code&gt;类，可以实现页面上flash文件的载入，而不需要求助google的&lt;code&gt;swfobject&lt;/code&gt;方法。&lt;/p&gt;&lt;div id="swfBox"&gt;&lt;object id="Swiff_NaN" width="300" height="300" data="http://www.zhangxinxu.com/study/flash/as3_clock_2.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://www.zhangxinxu.com/study/flash/as3_clock_2.swf" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;p&gt;上面这个钟表flash的效果代码如下：&lt;/p&gt;&lt;div class="zxx_code"&gt;var obj = new Swiff('http://www.zhangxinxu.com/study/flash/as3_clock_2.swf', {&lt;br/&gt;    width: 300,&lt;br/&gt;    height: 300,&lt;br/&gt;    container: $("swfBox"),&lt;br/&gt;    params: {&lt;br/&gt;        wmode: 'opaque',&lt;br/&gt;        bgcolor: '#eeeeee'&lt;br/&gt;    }&lt;br/&gt;});&lt;/div&gt;&lt;p&gt;&lt;strong&gt;更全面的动画效果&lt;/strong&gt;&lt;br /&gt;MooTools框架的动画效果实际上要比jQuery的强些，但是，不足在于其使用的API要比jQuery逊色。&lt;br /&gt;说MooTools框架动画要比jQuery强，其中之一就是MooTools动画内置了贝塞尔运动曲线关键字。如：&lt;code&gt;'linear'&lt;/code&gt;,&amp;nbsp;&lt;code&gt;'quad:in'&lt;/code&gt;,&amp;nbsp;&lt;code&gt;'back:in'&lt;/code&gt;,&lt;code&gt;'bounce:out'&lt;/code&gt;,&amp;nbsp;&lt;code&gt;'elastic:out'&lt;/code&gt;,&amp;nbsp;&lt;code&gt;'sine:in:out'&lt;/code&gt;等等（下图为Fx.Transitions方法之&lt;code&gt;expo&lt;/code&gt;），而jQuery实现类似缓动效果，还需要借助&lt;code&gt;ease&lt;/code&gt;插件。&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.zhangxinxu.com/jq/mt/assets/images/graphs/Expo.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;form表单序列化提交&lt;/strong&gt;&lt;br /&gt;MooTools自身携带HTML表单控件元素数据序列化方法，例如：&lt;/p&gt;&lt;div class="zxx_code"&gt;$('myForm').toQueryString(); &lt;span&gt;//返回 "email=bob@bob.com&amp;amp;zipCode=90210"&lt;/span&gt;&lt;/div&gt;&lt;p&gt;表单元素自身携带了ajax提交方法，如下示例：&lt;/p&gt;&lt;div class="zxx_code"&gt;$('loginForm').addEvent('submit', function(e){&lt;br/&gt;    e.stop(); &lt;span&gt; //不提交form&lt;/span&gt;&lt;br/&gt;    $('loginForm').send({&lt;br/&gt;     onComplete: function(result) {&lt;br/&gt;         $('loginPopup').set('html', result); &lt;span&gt;//显示结果&lt;/span&gt;&lt;br/&gt;         (function(){&lt;br/&gt;             $('loginPopup').hide();&lt;br/&gt;         }.delay(1000)); &lt;span&gt;//一秒钟后隐藏&lt;/span&gt;&lt;br/&gt;     }&lt;br/&gt;    });&lt;br/&gt;});&lt;/div&gt;&lt;p&gt;而jQuery框架要实现类似的功能，还需要专门的表单序列化插件。我靠，这东一个插件，西一个插件，而且插件质量良莠不齐，搞多了会死人的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;四、最后的对比总结&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;首先，毋庸置疑的是jQuery和MooTools都是非常优秀的轻量级的JavaScript框架。&lt;/p&gt;&lt;p&gt;jQuery以其出色的API，出色的插件机制，以及在DOM方面的关注使其大受欢迎。然而，在面对大型项目的时候，其在一些功能特性上的缺失往往需要借助插件。如果团队没有有牛人把关的话，插件的滥用，人人都插一手的代码会把项目代码质量逐渐变成狗屎的。一般而言，jQuery更适合与动态的中小站点。&lt;/p&gt;&lt;p&gt;MooTools插件虽然在API &amp;amp; DOM和上手容易程度上都上不及jQuery，但是，其API以及面向对象的设计思想似乎在实际的大项目中更有价值。&lt;/p&gt;&lt;p&gt;因此，如果我要折腾我的个人网站，应该会使用jQuery。但是，如果是公司的大的网站项目，我会坚定不移选择MooTools，因为更适合。&lt;/p&gt;&lt;p&gt;我JS水平尚浅，基本上都是些表象的对比，欢迎吐槽。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;转自：张鑫旭-鑫空间-鑫生活&amp;nbsp;&lt;a href="http://www.zhangxinxu.com/wordpress/?p=1963"&gt;http://www.zhangxinxu.com/wordpress/?p=1963&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ATree/aggbug/2243774.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ATree/archive/2011/11/10/jQuery-vs-MooTools.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ATree/archive/2011/11/10/JS-appendChild-insertBefore.html</id><title type="text">JS(JavaScript)插入节点的方法appendChild与insertBefore</title><summary type="text">appendChild() 方法：可向节点的子节点列表的末尾添加新的子节点。语法：appendChild(newchild)insertBefore() 方法：可在已有的子节点前插入一个新的子节点。语法 ：insertBefore(newchild,refchild)相同之处：插入子节点不同之处：实现原理方法不同。appendChild方法是在父级节点中的子节点的末尾添加新的节点（相对于父级节点 来说）。  insertBefore 方法 是在已有的节点前添加新的节点（相对于子节点来说的）。来看个这个简单的实例：在id为box-con 的末尾添加一个子节点div</summary><published>2011-11-10T00:31:00Z</published><updated>2011-11-10T00:31:00Z</updated><author><name>zock</name><uri>http://www.cnblogs.com/ATree/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ATree/archive/2011/11/10/JS-appendChild-insertBefore.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ATree/archive/2011/11/10/JS-appendChild-insertBefore.html"/><content type="html">&lt;p&gt;首先 从定义来理解 这两个方法：&lt;/p&gt;&lt;p&gt;appendChild() 方法：可向节点的子节点列表的末尾添加新的子节点。语法：appendChild(newchild)&lt;/p&gt;&lt;p&gt;insertBefore() 方法：可在已有的子节点前插入一个新的子节点。语法 ：insertBefore(newchild,refchild)&lt;/p&gt;&lt;p&gt;相同之处：插入子节点&lt;/p&gt;&lt;p&gt;不同之处：实现原理方法不同。&lt;/p&gt;&lt;p&gt;　appendChild方法是在父级节点中的子节点的末尾添加新的节点（相对于父级节点 来说）。&lt;/p&gt;&lt;p&gt; &amp;nbsp; insertBefore 方法 是在已有的节点前添加新的节点（相对于子节点来说的）。&lt;/p&gt;&lt;div id="content_atree"&gt;&lt;em&gt;如果你看到这段文字，说明您正使用RSS阅读或转自《一棵树-博客园》，原文地址：&lt;a id="Editor_Edit_hlEntryLink" title="view: JS(JavaScript)插入节点的方法appendChild与insertBefore" href="http://www.cnblogs.com/ATree/archive/2011/09/26/JS-appendChild-insertBefore.html" target="_blank"&gt;http://www.cnblogs.com/ATree/archive/2011/09/26/JS-appendChild-insertBefore.html&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;&lt;p&gt;来看个这个简单的实例：在id为box-con 的末尾添加一个子节点div&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="margin: 0px;"&gt;&lt;div style="padding: 0px; margin: 0px;"&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #800000; padding: 0px; margin: 0px;"&gt;div &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #ff0000; padding: 0px; margin: 0px;"&gt;class&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;="btns"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #800000; padding: 0px; margin: 0px;"&gt;input &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #ff0000; padding: 0px; margin: 0px;"&gt;type&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;="button"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #ff0000; padding: 0px; margin: 0px;"&gt; value&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;="插入元素"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #ff0000; padding: 0px; margin: 0px;"&gt; id&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;="creatbtn"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #800000; padding: 0px; margin: 0px;"&gt;div&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #800000; padding: 0px; margin: 0px;"&gt;div&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #ff0000; padding: 0px; margin: 0px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #ff0000; padding: 0px; margin: 0px;"&gt; id&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;="box-one"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #800000; padding: 0px; margin: 0px;"&gt;p &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #ff0000; padding: 0px; margin: 0px;"&gt;class&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;="con2"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #ff0000; padding: 0px; margin: 0px;"&gt; id&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;="p1"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;1&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #800000; padding: 0px; margin: 0px;"&gt;p&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #800000; padding: 0px; margin: 0px;"&gt;p &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #ff0000; padding: 0px; margin: 0px;"&gt;class&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;="con2"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;2&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #800000; padding: 0px; margin: 0px;"&gt;p&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #800000; padding: 0px; margin: 0px;"&gt;p &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #ff0000; padding: 0px; margin: 0px;"&gt;class&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;="con2"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;3&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #800000; padding: 0px; margin: 0px;"&gt;p&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #800000; padding: 0px; margin: 0px;"&gt;div&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; background-color: #faf7ef;"&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="margin: 0px;"&gt;&lt;div style="padding: 0px; margin: 0px;"&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;window.onload &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;function&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; () {&lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;var&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; btn &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; document.getElementById(&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;creatbtn&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;);&lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;br style="padding: 0px; margin: 0px;" /&gt;    btn.onclick &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;function&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;() {&lt;br style="padding: 0px; margin: 0px;" /&gt;        insertEle();&lt;br style="padding: 0px; margin: 0px;" /&gt;    }&lt;br style="padding: 0px; margin: 0px;" /&gt;}&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;function&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; insertEle() {        &lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;var&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; oTest &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; document.getElementById(&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;box-one&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;);&lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;var&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; newNode &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; document.createElement(&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;div&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;);&lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;br style="padding: 0px; margin: 0px;" /&gt;    newNode.innerHTML &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; This is  a newcon &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;;&lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #008000; padding: 0px; margin: 0px;"&gt;//&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #008000; padding: 0px; margin: 0px;"&gt;oTest.appendChild(newNode);&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #008000; padding: 0px; margin: 0px;"&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;    oTeset.insertBefore(newNode,&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;null&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;); &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #008000; padding: 0px; margin: 0px;"&gt;//&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #008000; padding: 0px; margin: 0px;"&gt; 这两种方法均可实&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #008000; padding: 0px; margin: 0px;"&gt;现&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;这个insertBefore 的第一个参数 和appendChild的一样，都是那个新的节点变量，而insert第二个参数不仅可以为null 。也可以这样写呢&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="margin: 0px;"&gt;&lt;div style="padding: 0px; margin: 0px;"&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;function&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; insertEle() {        &lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;var&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; oTest &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; document.getElementById(&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;box-one&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;);&lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;var&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; newNode &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; document.createElement(&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;div&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;);&lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;var&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; reforeNode &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; document.getElementById(&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;p1&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;);&lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;br style="padding: 0px; margin: 0px;" /&gt;    newNode.innerHTML &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; This is  a newcon &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #008000; padding: 0px; margin: 0px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #008000; padding: 0px; margin: 0px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #008000; padding: 0px; margin: 0px;"&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;    oTest.insertBefore(newNode,reforeNode); &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #008000; padding: 0px; margin: 0px;"&gt;//&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #008000; padding: 0px; margin: 0px;"&gt;新建的元素节点插入到 id为p1的元素前面&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; background-color: #faf7ef;"&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;或者&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="margin: 0px;"&gt;&lt;div style="padding: 0px; margin: 0px;"&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;function&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; insertEle() {        &lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;var&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; oTest &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; document.getElementById(&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;box-one&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;);&lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;var&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; newNode &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; document.createElement(&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;div&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;);&lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #0000ff; padding: 0px; margin: 0px;"&gt;var&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; reforeNode &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; document.getElementById(&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;p1&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;);&lt;br style="padding: 0px; margin: 0px;" /&gt;    &lt;br style="padding: 0px; margin: 0px;" /&gt;    newNode.innerHTML &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;=&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt; This is  a newcon &lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;"&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 1.5; color: #000000; padding: 0px; margin: 0px;"&gt;;&lt;br style="padding: 0px; margin: 0px;" /&gt;    oTest.insertBefore(newNode,reforeNode.nextSibling);//新建的元素节点插入到 id为p1后面节点元素的 前面，&lt;br style="padding: 0px; margin: 0px;" /&gt;也就是说 插入id为P1节点元素的后面。&lt;br style="padding: 0px; margin: 0px;" /&gt;&lt;br style="padding: 0px; margin: 0px;" /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;这里想说的是 nextSibling :某个元素之后紧跟的元素（处于同一树层级中）。&lt;/p&gt;&lt;p&gt;reforeNode.nextSibling ：取得的是reforeNode对象的紧跟着的下一个节点。&lt;/p&gt;&lt;p&gt;previousSibling - 取得某节点的上一个同级节点&lt;/p&gt;&lt;p&gt;由于可见insertBefore()方法的特性是在已有的子节点前面插入新的节点但是两种情况结合起来发现&lt;strong style="padding: 0px; margin: 0px;"&gt;&lt;span style="color: #ff0000; padding: 0px; margin: 0px;"&gt;insertBefore()方法插入节点，是可以在子节点列表的任意位置。&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ATree/aggbug/2191250.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ATree/archive/2011/11/10/JS-appendChild-insertBefore.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ATree/archive/2011/11/10/Performance-Application.html</id><title type="text">你会如何优化应用程序的性能？</title><summary type="text">使用分析器。你可以使用类似于MVC-MiniProfiler的工具来分析方法调用，使用类似于.NET Memory Profiler或者Redgate ANTS Memory profiler之类的内存分析器来跟踪内存使用情况。如果可以的话，要拥有可查询的日志——StackExchange团队有后台执行的进程，它会解析原始的日志，并把它插入到大型的、专门的SQL Server实例中。如果无法查询日志，那么你就无法绘制出统计图并查看趋势或者模式。理解GC是如何工作的——.NET中的垃圾回收器支持三代对象（GEN 0到GEN 2），而存放时间最长的数据会使用GEN-2。GEN-2的扫描频率最低，执行的成本最高，甚至可能会堵塞其它线程。Sam建议阅读Rico的《Garbage Collector Basics and Performance Hints》一文以获得更多细节。</summary><published>2011-11-10T00:30:00Z</published><updated>2011-11-10T00:30:00Z</updated><author><name>zock</name><uri>http://www.cnblogs.com/ATree/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ATree/archive/2011/11/10/Performance-Application.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ATree/archive/2011/11/10/Performance-Application.html"/><content type="html">&lt;p&gt;&lt;a href="http://stackexchange.com/"&gt;StackExchange&lt;/a&gt;是构建在ASP.NET和SQL Server基础之上的项目。最近，&lt;a href="http://samsaffron.com/archive/2011/10/28/in-managed-code-we-trust-our-recent-battles-with-the-net-garbage-collector"&gt;Sam Saffron&lt;/a&gt;和&lt;a href="http://marcgravell.blogspot.com/2011/10/assault-by-gc.html"&gt;Marc Gravell&lt;/a&gt;分别撰写了博客，其中讲述了他们发现和解决性能问题的经验，在该过程中最终追踪到了.NET GC GEN-2对象。大家可以从他们的博文中吸取很多关于优化生产环境中应用程序性能的经验。&lt;/p&gt;&lt;p&gt;问题是由自定义标签引擎引起的，它会在内存中存放大型对象列表。这两篇博文都值得一读，而Sam的文章则更详细地讲述了如何诊断问题。其中主要的应对方法包括：&lt;/p&gt;&lt;div id="content_atree"&gt;&lt;em&gt;如果你看到这段文字，说明您正使用RSS阅读或转自《一棵树-博客园》，原文地址：&lt;a id="Editor_Edit_hlEntryLink" title="view: 你会如何优化应用程序的性能？" href="http://www.cnblogs.com/ATree/archive/2011/11/10/Performance-Application.html" target="_blank"&gt;http://www.cnblogs.com/ATree/archive/2011/11/10/Performance-Application.html&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;使用分析器。你可以使用类似于&lt;a href="http://code.google.com/p/mvc-mini-profiler/"&gt;MVC-MiniProfiler&lt;/a&gt;的工具来分析方法调用，使用类似于&lt;a href="http://memprofiler.com/"&gt;.NET Memory Profiler&lt;/a&gt;或者&lt;a href="http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/"&gt;Redgate ANTS Memory profiler&lt;/a&gt;之类的内存分析器来跟踪内存使用情况。&lt;/li&gt;&lt;li&gt;如果可以的话，要拥有可查询的日志&amp;mdash;&amp;mdash;StackExchange团队有后台执行的进程，它会解析原始的日志，并把它插入到大型的、专门的SQL Server实例中。如果无法查询日志，那么你就无法绘制出统计图并查看趋势或者模式。&lt;/li&gt;&lt;li&gt;理解GC是如何工作的&amp;mdash;&amp;mdash;.NET中的垃圾回收器支持三代对象（GEN 0到GEN 2），而存放时间最长的数据会使用GEN-2。GEN-2的扫描频率最低，执行的成本最高，甚至可能会堵塞其它线程。Sam建议阅读Rico的&lt;a href="http://msdn.microsoft.com/en-us/library/ms973837.aspx"&gt;《Garbage Collector Basics and Performance Hints》&lt;/a&gt;一文以获得更多细节。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;最后，团队采取了多项优化措施，包括针对应用程序的特定部分，从对象数组切换到索引数组，从类切换到结构体等。第一项措施是一种很常用的模式，这样数组就只针对主要的不可变列表的索引；而第二项并不常用，Sam建议只在有超过50万个对象以上才使用它，这样在达到第二代垃圾回收器标准的时候就会很快释放内存。&lt;/p&gt;&lt;p&gt;StackExchange团队对性能问题非常关注&amp;mdash;&amp;mdash;比方说，你可以看到StackOverflow在三个不同的等级上&lt;a href="http://meta.stackoverflow.com/questions/69164/does-stackoverflow-use-caching-and-if-so-how"&gt;使用caching&lt;/a&gt;，从而提升反应时间，减少服务器的负载。&lt;/p&gt;&lt;p&gt;在MSDN上都有很多关于性能和可伸缩性的资源可供参考，包括这篇&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163854.aspx"&gt;Rob Howard撰写的文章&lt;/a&gt;。最后，引用Sam的话：&amp;ldquo;做很少的工作总是要比做更多工作消耗的资源少。&amp;rdquo;&lt;/p&gt;&lt;p&gt;你在扩展ASP.NET应用程序的时候，也有发现和解决瓶颈问题的类似经验和大家分享吗？&lt;/p&gt;&lt;p&gt;查看英文原文：&lt;a href="http://www.infoq.com/news/2011/10/stackexchange-performance"&gt;How Do You Tune Your Application For Performance?&lt;/a&gt;(译者：侯伯薇 转自：infoQ)&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ATree/aggbug/2243802.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ATree/archive/2011/11/10/Performance-Application.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
