精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (10)
|
||
---|---|---|
作者 | 正文 | |
发表时间:2008-12-25
最后修改:2008-12-26
本文介绍了五种常见 Ajax 设计模式。它们在使用 HTML、XML 和 JavaScript 代码从服务器获取数据方面有所不同。我先介绍最简单的模式,它将使用来自服务器的新 HTML 页面来更新页面。
模式1:替换 HTML 片段 最常见的 Ajax 任务也许就是向服务器请求更新的 HTML 并使用它更新部分页面。可能需要周期性地完成这一任务 —— 比如,更新股市报价。也可能要按需更新 —— 比如,对搜索请求进行响应。
清单1
中的代码从服务器请求一个页面然后将内容放入页面主体的 清单 1. Pat1_replace_div.html <html> <script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 ) { var dobj = document.getElementById( 'htmlDiv' ); dobj.innerHTML = req.responseText; } } function loadUrl( url ) { if(window.XMLHttpRequest) { try { req = new XMLHttpRequest(); } catch(e) { req = false; } } else if(window.ActiveXObject) { try { req = new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) { try { req = new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) { req = false; } } } if(req) { req.onreadystatechange = processReqChange; req.open('GET', url, true); req.send(''); } } var url = window.location.toString(); url = url.replace( /pat1_replace_div.html/, 'pat1_content.html' ); loadUrl( url ); </script> <body> Dynamic content is shown between here:<br/> <div id="htmlDiv" style="border:1px solid black;padding:10px;"> </div> And here.<br/> </body> </html> 清单2 展示了代码请求的内容。 清单 2. Pat1_content.html HTML encoded content goes here. 在 Firefox 中加载页面后,可以看到 图 1 所示的结果。
现在回到 清单1
中的代码,来观察一些内容。第一个要注意的是
将 暂时回到
该模式的另一种变体就是创建一个选项卡样式的显示。 清单3 展示了一个简单的选项卡式 Ajax 界面。
清单 3. Pat1_tabs.html <html> <script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 ) { var dobj = document.getElementById( 'tabDiv' ); dobj.innerHTML = req.responseText; } } function loadUrl( tab ) { var url = window.location.toString(); url = url.replace( /pat1_tabs.html/, tab ); ... } function tab1() { loadUrl( 'pat1_tab1_content.html' ); } function tab2() { loadUrl( 'pat1_tab2_content.html' ); } tab1(); </script> <body> <a href="javascript: void tab1();">Tab 1<a> <a href="javascript: void tab2();">Tab 2<a> <div id="tabDiv" style="border:1px solid black;padding:10px;"> </div> </body> </html>
清单4 显示了第一个选项卡的内容。
Tab 1 content
清单 5 显示了第二个选项卡的内容。 Tab 2 content
当我在自己的浏览器上显示该页面时,我看到了第一个选项卡,如 图 2 所示
然后单击第二个选项卡的链接。浏览器检索第二个选项卡的内容然后将它显示在选项卡区域,如 图 3 所示。
这是该设计模式的最典型用法 —— 从用户那里获得请求并使用新的内容更新部分显示,本例演示了创建选项卡显示的技巧。应用程序端的价值就是您可以为用户下载非常轻量级的页面,用户可以根据自己的需求访问这些内容。 在 Ajax 出现之前,最常见的技术是将所有的选项卡都放在页面上,然后根据需要显示或隐藏它们。这就是说即使从来不查看第二个选项卡,也会为其创建 HTML,既浪费服务器时间又浪费带宽。使用这种新的 Ajax 方法,只有当用户请求第二个选项卡时才会为其创建 HTML。
该模式的另一个变化就是 Read more 链接,如 图 4 所示。
假如想希望阅读更多关于我遛狗的经历,可以单击 Read more 链接,使该链接替换为完整的故事,如 图 5 所示。
这样做的好处是顾客可以在无需刷新页面的情况下获得更多内容。
清单 6 显示了该页的代码。 <html> <script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 ) { var dobj = document.getElementById( "moreSpan" ); dobj.innerHTML = req.responseText; } } function loadUrl( url ) { ... } function getMore() { var url = window.location.toString(); url = url.replace( /pat1_readmore.html/, 'pat1_readmore_content.html' ); loadUrl( url ); } </script> <body> <h1>Walking the dog</h1> I took my dog for a walk today. <span id="moreSpan"> <a href="javascript: void getMore()">Read more...</a> </span> </body> </html>
清单 7 显示了 “read more” 部分的内容。
这些代码演示的是 为页面获取新的 HTML 只是其中一件事情,如果您希望 JavaScript 代码在页面中使用数据执行一些更智能化的任务该怎么办呢?如何使用结构化的方式将数据发送到浏览器呢?毫无疑问,这正是使用 XML 的原因。
模式 2. 读取 XML 数据 出于某些原因,Ajax 已成为 XML 的同义词,尽管 XML 不是绝对必要的。从上面几个例子可以看出,您完全可以返回简单的文本甚至是 HTML 片段 —— 或者 Extensible HTML(XHTML)—— 代码。但是发送 XML 自有其优势所在。 清单 8 显示的 Ajax 代码首先向服务器请求图书记录,然后将数据显示在页面内的表格中。
<html> <head> <script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 && req.responseXML ) { var dtable = document.getElementById( 'dataBody' ); var nl = req.responseXML.getElementsByTagName( 'book' ); for( var i = 0; i < nl.length; i++ ) { var nli = nl.item( i ); var elAuthor = nli.getElementsByTagName( 'author' ); var author = elAuthor.item(0).firstChild.nodeValue; var elTitle = nli.getElementsByTagName( 'title' ); var title = elTitle.item(0).firstChild.nodeValue; var elTr = dtable.insertRow( -1 ); var elAuthorTd = elTr.insertCell( -1 ); elAuthorTd.innerHTML = author; var elTitleTd = elTr.insertCell( -1 ); elTitleTd.innerHTML = title; } } } function loadXMLDoc( url ) { if(window.XMLHttpRequest) { try { req = new XMLHttpRequest(); } catch(e) { req = false; } } else if(window.ActiveXObject) { try { req = new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) { try { req = new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) { req = false; } } } if(req) { req.onreadystatechange = processReqChange; req.open('GET', url, true); req.send(''); } } var url = window.location.toString(); url = url.replace( /pat2_xml.html/, 'pat2_xml_data.xml' ); loadXMLDoc( url ); </script> </head> <body> <table cellspacing="0" cellpadding="3" width="100%"> <tbody id="dataBody"> <tr> <th width="20%">Author</th> <th width="80%">Title</th> </tr> </tbody> </table> </body> </html>
清单 9 显示了该页面的数据。
<books> <book> <author>Jack Herrington</author> <title>Code Generation in Action</title> </book> <book> <author>Jack Herrington</author> <title>Podcasting Hacks</title> </book> <book> <author>Jack Herrington</author> <title>PHP Hacks</title> </book> </books> 在浏览器中加载页面时,我看到了如 图 6 所示的结果.
此页面和上一个模式中显示的页面之间最大的区别就是 通过使用 这是 XML 数据的最基本应用。更复杂的 JavaScript 代码可以执行客户端排序或根据返回的数据进行搜索。 遗憾的是,传递 XML 数据的缺点是需要浏览器多花费一些时间来解析整个 XML 文档。同样,JavaScript 代码在 XML 中查找数据也很复杂(参见 清单 8 )。一个替代办法是从服务器请求 JavaScript 代码。
从服务器请求 JavaScript 数据这种技术通常用于 JavaScript Object Notation (JSON)这种良好的代码。返回 JavaScript 数据的优点就是能够使浏览器高效地解析并创建使用起来更加简单的 JavaScript 数据结构。 让我们将 清单 8 中从服务器读取 XML 的代码修改为从服务器读取 JavaScript 数据的代码。新代码如 清单 10 所示。
<html><head><script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 ) { var dtable = document.getElementById( 'dataBody' ); var books = eval( req.responseText ); for( var b in books ) { var elTr = dtable.insertRow( -1 ); var elAuthorTd = elTr.insertCell( -1 ); elAuthorTd.innerHTML = books[b].author; var elTitleTd = elTr.insertCell( -1 ); elTitleTd.innerHTML = books[b].title; } } } ...
所有的 HTML 代码保持不变。 清单 11 显示了来自服务器的 JavaScript 数据。
[ { author: 'Jack Herrington', title: 'Code Generation in Action' }, { author: 'Jack Herrington', title: 'Podcasting Hacks' }, { author: 'Jack Herrington', title: 'PHP Hacks' } ] 为什么众多 Ajax 应用程序工程师更喜欢使用 JavaScript 代码而不是 XML 来对数据编码?答案很明显。JavaScript 代码更容易读取和管理,并且也更容易被浏览器处理。 收集和显示所有的数据之后,即可看到 Ajax 的重点就是显示当前数据 —— 当前 最重要的部分。那么,如何保证总是能够从服务器获得最新的数据呢?
浏览器会尝试化 Web 流量,所以如果您对同一个 URL 请求两次,很可能还不如重新请求一次页面,您的浏览器将仅仅使用浏览器缓存中存储的页面。所以,Ajax 应用程序中另一个常见模式是使用 URL 中的随机元素来保证浏览器不会返回一个缓存的结果。 向URL添加当前时间的数字值。 清单 12 展示了这一技巧
<html> <script> ... function loadUrl( url ) { url = url + "?t="+((new Date()).valueOf()); ... } ... 代码取自 清单 1
,对 URL 字符串执行了一些额外的 JavaScript 文本操作。我将 URL 连接到一个新的参数
最后要演示的这个模式是第一个模式的高级版本:包含来自服务器内容的 为更新显示页面中的多个区域,我使用了服务器的 XML 响应,它包含每个部分的数据。然后,使用一个正则表达式将响应分解为单个部分。清单 13 显示了这种技巧。
<html> <head> <script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 ) { var one = req.responseText.match( /\<one\>(.*?)\<\/one\>/ ); document.getElementById( 'divOne' ).innerHTML = one[1]; var two = req.responseText.match( /\<two\>(.*?)\<\/two\>/ ); document.getElementById( 'divTwo' ).innerHTML = two[1]; } } function loadXMLDoc( url ) { ... } var url = window.location.toString(); url = url.replace( /pat5_multi_segment.html/, 'pat5_data.xml' ); loadXMLDoc( url ); </script> </head> <body> This is the content for segment one:<br/> <div id="divOne" style="border:1px solid black;padding:10px;"> </div> And segment two:<br/> <div id="divTwo" style="border:1px solid black;padding:10px;"> </div> </body> </html>
清单 14 展示了来自服务器的数据。
<segments> <one>Content for segment one</one> <two>Content for segment <b>two</b></two> </segments>
在浏览器中加载这段代码时,将看到 图 7 所示的结果。
在页面代码中,我还可以使用 XML 响应,因为服务器返回的是有效的 XML。但是使用正则表达式比从 XML 代码中分解单独部分更加简单。
Ajax 的功能之强大与之被误解和误用的程度相当。本文中演示的模式为在 Web 应用程序中使用 Ajax 提供了一个不错的起点。除了使用这里提供的代码,我还建议您关注以下 Web 2.0 革命带来的某些出色的 Ajax 和 Web UI 库。其中最主要的是 Prototype.js 库,它提供了向浏览器发送以及从浏览器获取数据的简便方法,以及浏览器间兼容的方法更新 Web 页面内容。使用这些库的价值在于工程师可以在广泛的浏览器和平台上专注地维护和测试它们,这样可省去大量的工作和麻烦。 无论从哪方面说,就像本文中的模式演示的那样,Ajax 可以为您的应用程序添加动态行为。
原载: http://www.ibm.com/developerworks/cn/xml/x-ajaxxml2/ 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
||
返回顶楼 | ||
发表时间:2008-12-30
又长见识了~~~
觉得xml看似简单其实有点难。。。 |
||
返回顶楼 | ||
发表时间:2009-02-17
不错嘛,看过试用过先,OK!
|
||
返回顶楼 | ||
发表时间:2009-02-25
很好,谢谢了,最近需要使用XML作为传输的格式,获益匪浅。
|
||
返回顶楼 | ||
发表时间:2009-02-25
用JSON足矣,XML数据量太庞大了
|
||
返回顶楼 | ||
发表时间:2009-02-25
好文~~
json效率貌似高点 浏览器get时才有缓存的情况,我一般用Math.random。 -- 模式3读取的是json数据,可以考虑下js脚本~ |
||
返回顶楼 | ||
浏览 7676 次