站长百科 | 数字化技能提升教程 数字化时代生存宝典
首页
数字化百科
电子书
▼
建站程序
开发
服务器
办公软件
开发教程
▼
服务器教程
软件使用教程
运营教程
热门电子书
▼
CSS教程
WordPress教程
导航
程序频道
推广频道
网赚频道
人物频道
网站程序
网页制作
云计算
服务器
CMS
论坛
网店
虚拟主机
cPanel
网址导航
WIKI使用导航
WIKI首页
热点词条
最新资讯
网站程序
站长人物
页面分类
使用帮助
编辑测试
创建条目
网站地图
站长百科导航
站长百科
主机侦探
IDCtalk云说
跨境电商导航
WordPress啦
站长专题
网站推广
网站程序
网站赚钱
虚拟主机
cPanel
网址导航专题
云计算
微博营销
虚拟主机管理系统
开放平台
WIKI程序与应用
美国十大主机
编辑“
Ajax- 与服务器通信1
”(章节)
人物百科
|
营销百科
|
网赚百科
|
站长工具
|
网站程序
|
域名主机
|
互联网公司
|
分类索引
跳转至:
导航
、
搜索
警告:
您没有登录。如果您做出任意编辑,您的IP地址将会公开可见。如果您
登录
或
创建
一个账户,您的编辑将归属于您的用户名,且将享受其他好处。
反垃圾检查。
不要
加入这个!
== 使用W3C DOM动态编辑页面 == Web最初只是作为媒介向各处分发静态的文本文档,如今它本身已经发展为一个应用开发平台。遗留的企业系统通常通过纯文本的终端部署,或者作为客户—服务器应用部署,这些遗留系统正在被完全通过Web浏览器部署的系统所取代。<br> 随着最终用户越来越习惯于使用基于Web的应用,他们开始有了新的要求,需要一种更丰富的用户体验。用户不再满足于完全页面刷新,即每次在页面上编辑一些数据时页面都会完全刷新。他们想立即看到结果,而不是坐等与服务器完成完整的往返通信。<br> 你已经了解了解析服务器发送的XML消息是多么容易。W3C DOM提供了一些属性和方法,使你能轻松地遍历XML结构,并抽取所需的数据。<br> 前面的例子对于服务器发送的XML响应并没有做多少有用的事情。在警告框中显示XML文档的值没有太大的实际意义。你真正想做到的是让用户享有丰富的客户体验,不再遭遇一般Web应用中常见的连续页面刷新问题。页面连续刷新不仅使用户不满意,还会浪费服务器上宝贵的处理器时间,因为页面刷新需要重新构建整个页面的内容,而且会不必要地使用网络带宽来传送刷新的页面。<br> 当然,最好的解决办法是根据需要修改页面上已有的内容。如果页面上大多数数据没有改变,则不应刷新整个页面,只需要修改页面中信息有变化的部分。<br> 以往,在Web浏览器的限制之下,这一点很难做到。浏览器只是一个工具,它解释特殊的标记(HTML),并根据一组预定的规则显示这些标记。Web以及Web浏览器原来只是为了显示静态的信息,如果不以新页面的形式从服务器请求新的数据,这些信息不会改变。<br> 除了一些例外情况,当前的浏览器都使用W3C DOM来表示Web页面的内容。这样做可以确保在不同的浏览器上Web页面会以同样的方式呈现,同时在不同的浏览器上,用于修改页面内容的脚本也会有相同的表现。Web浏览器的W3C DOM和JavaScript实现越来越成熟,这大大简化了在浏览器上动态创建内容的任务。原来总是要苦心积虑地解决浏览器间的不兼容性,如今这已经不太需要。表3-3列出了用于动态创建内容的DOM属性和方法。<br> 表3-3 动态创建内容时所用的W3C DOM属性和方法<br> document.createElement(tagName)<br> 文档对象上的createElement方法可以创建由tagName指定的元素。如果以串div作为方法参数,就会生成一个div元素<br> document.createTextNode(text)<br> 文档对象的createTextNode方法会创建一个包含静态文本的节点<br> <element>.appendChild(childNode)<br> appendChild方法将指定的节点增加到当前元素的子节点列表(作为一个新的子节点)。例如,可以增加一个option元素,作为select元素的子节点<br> <element>.getAttribute(name)<br> <element>.setAttribute(name, value)<br> 这些方法分别获得和设置元素中name属性的值<br> <element>.insertBefore(newNode, targetNode)<br> 这个方法将节点newNode作为当前元素的子节点插到targetNode元素前面<br> <element>.removeAttribute(name)<br> 这个方法从元素中删除属性name<br> <element>.removeChild(childNode)<br> 这个方法从元素中删除子元素childNode <br> <element>.replaceChild(newNode, oldNode)<br> 这个方法将节点oldNode替换为节点newNode<br> <element>.hasChildnodes()<br> 这个方法返回一个布尔值,指示元素是否有子元素<br> 关于浏览器的不兼容性<br> <br> 尽管当前Web浏览器中W3C DOM和JavaScript的实现在不断改进,但还是存在一些特异性和不兼容性,这使得应用DOM和JavaScript进行开发时很是头疼。<br> IE的W3C DOM和JavaScript实现最受限制。2000年初,一些统计称IE占据了整个浏览器市场95%的份额,由于没有竞争压力,Microsoft决定不完全实现各个Web标准。 <br> 这些特异问题大多都能得到解决,不过这样做会让脚本更是混乱不堪而且不合标准。例如,如果使用appendChild将<tr>元素直接增加到<table>中,则在IE中这一行并不出现,但在其他浏览器中却会显示出来。对此的解决之道是,将<tr>元素增加到表的<tbody>元素中,这种解决办法在所有浏览器中都能正确工作。<br> 关于setAttribute方法,IE也有麻烦。IE不能使用setAttribute正确地设置class属性。对此有一个跨浏览器的解决方法,即同时使用setAttribute("class", "new- ClassName") 和setAttribute("className","newClassName")。另外,在IE中不能使用setAttribute设置style属性。最能保证浏览器兼容的技术不是<element>.setA- ttribute("style, "font-weight:bold;"),而是<element>.style.cssText = "font - weight:bold;"。<br> 本书中的例子会尽可能地遵循W3C DOM和JavaScript标准,不过如果必须确保大多数当前浏览器的兼容性,可能也会稍稍偏离标准。<br> 下面的例子展示了如何使用W3C DOM和JavaScript来动态创建内容。这个例子是假想的房地产清单搜索引擎,点击表单上的Search(搜索)按钮,会使用XMLHttpRequest对象以XML格式获取结果。使用JavaScript处理响应XML,从而生成一个表,其中列出搜索到的结果(见图3-3)。<br> [[Image:Image006.jpg]] 图3-3 使用W3C DOM方法和JavaScript动态创建搜索结果 <br> 服务器返回的XML很简单(见代码清单3-5)。根节点properties包含了得到的所有property元素。每个property元素包含3个子元素:address、price和comments。<br> 代码清单3-5 dynamicContent.xml<br> <?xml version="1.0" encoding="UTF-8"?><br> <properties><br> <property><br> <address>812 Gwyn Ave</address><br> <price>$100,000</price><br> <comments>Quiet, serene neighborhood</comments><br> </property><br> <property><br> <address>3308 James Ave S</address><br> <price>$110,000</price><br> <comments>Close to schools, shopping, entertainment</comments><br> </property><br> <property><br> <address>98320 County Rd 113</address><br> <price>$115,000</price><br> <comments>Small acreage outside of town</comments><br> </property><br> </properties><br> 具体向服务器发送请求并对服务器响应做出回应的JavaScript与前面的例子是一样的。不过,从handleReadyStateChange函数开始有所不同。假设请求成功地完成,接下来第一件事就是调用clearPreviousResults函数,将以前搜索所创建的内容删除。<br> clearPreviousResults函数完成两个任务:删除出现在最上面的“Results”标题文本,并从结果表中清除所有行。首先使用hasChildNodes方法查看可能包括标题文本的span元素是否有子元素。应该知道,只有hasChildNodes方法返回true时才存在标题文本。如果确实返回true,则删除span元素的第一个(也是惟一的)子节点,因为这个子节点表示的就是标题文本。<br> clearPreviousResults的下一个任务是在显示搜索结果的表中删除所有行。所有结果行都是tbody节点的子节点,所以先使用document.getElementById方法得到该tbody节点的引用。一旦有了tbody节点,只要这个tbody节点还有子节点(tr元素)就进行迭代处理。每次迭代时都会从表体中删除childNodes集合中的第一个子节点。当表体中再没有更多的表行时,迭代结束。<br> 搜索结果表在parseResults函数中建立。这个函数首先创建一个名为results的局部变量,这是使用XMLHttpRequest对象的responseXML属性得到的XML文档。<br> 使用getElementsByTagName方法来获得XML文档中包含所有property元素的数组,然后将这个数组赋给局部变量properties。一旦有了property元素的数组,可以迭代处理数组中的各个元素,并获得property的address、price和comments。<br> var properties = results.getElementsByTagName("property"); for(var i = 0; i < properties.length; i++) { property = properties[i]; address = property.getElementsByTagName("address")[0].firstChild.nodeValue; price = property.getElementsByTagName("price")[0].firstChild.nodeValue; comments = property.getElementsByTagName("comments")[0].firstChild.nodeValue; addTableRow(address, price, comments); } 下面来仔细分析这个循环,因为这正是parseResults函数的核心。在for循环中,首先得到数组中的下一个元素,并把它赋给局部变量property。接下来,对于你感兴趣的各个子元素(address、price和comments),分别获得它们的节点值。<br> 请考虑address元素,这是property元素的一个子元素。首先在property元素上调用getElementsByTagName方法来得到单个address元素。getElementsByTagName方法返回一个数组,不过因为你知道有且仅有一个address元素,所以可以使用[0]记法来引用这个元素。<br> 沿着XML结构继续向下,现在有了address标记的引用,你需要得到它的文本内容。记住,文本实际上是父元素的一个子节点,所以可以使用firstChild属性来访问address元素的文本节点。有了文本节点后,可以引用文本节点的nodeValue属性来得到文本。<br> 采用同样的办法来得到price和comments元素的值,并把各个值分别赋给局部变量price和comments。再将address、price和comments传递给名为addTableRow的辅助函数,它会用这些结果数据具体建立一个表行。<br> addTableRow函数使用W3C DOM方法和JavaScript建立一个表行。使用document.cre- ateElement方法创建一个row对象,之后,再使用名为createCellWithText的辅助函数分别为address、price和comments值创建一个cell对象。createCellWithText函数会创建并返回一个以指定的文本作为单元格内容的cell对象。<br> createCellWithText函数首先使用document.createElement方法创建一个td元素,然后使用document.createTextNode方法创建一个包含所需文本的文本节点,所得到的文本节点追加到td元素。这个函数再把新创建的td元素返回给调用函数(addTableRow)。 <br> addTableRow函数对address、price和comments值重复调用createCellWithText函数,每一次向tr元素追加一个新创建的td元素。一旦向row(行)增加了所有cell(单元格),这个row就将被增加到表的tbody元素中。<br> 就这么多!你已经成功地读取了服务器返回的XML文档,而且动态创建了一个结果表。代码清单3-6显示了这个例子完整的JavaScript和可扩展HTML代码。<br> 代码清单3-6 dynamicContent.html<br> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"<br> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><br> <html xmlns="http://www.w3.org/1999/xhtml"><br> <head><br> <title>Dynamically Editing Page Content</title><br> <script type="text/javascript"><br> var xmlHttp;<br> function createXMLHttpRequest() {<br> if (window.ActiveXObject) {<br> xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");<br> }<br> else if (window.XMLHttpRequest) {<br> xmlHttp = new XMLHttpRequest();<br> }<br> }<br> function doSearch() {<br> createXMLHttpRequest();<br> xmlHttp.onreadystatechange = handleStateChange;<br> xmlHttp.open("GET", "dynamicContent.xml", true);<br> xmlHttp.send(null);<br> }<br> function handleStateChange() {<br> if(xmlHttp.readyState == 4) {<br> if(xmlHttp.status == 200) {<br> clearPreviousResults();<br> parseResults();<br> }<br> }<br> }<br> function clearPreviousResults() {<br> var header = document.getElementById("header");<br> if(header.hasChildNodes()) {<br> header.removeChild(header.childNodes[0]);<br> }<br> var tableBody = document.getElementById("resultsBody");<br> while(tableBody.childNodes.length > 0) {<br> tableBody.removeChild(tableBody.childNodes[0]);<br> }<br> }<br> function parseResults() {<br> var results = xmlHttp.responseXML;<br> var property = null;<br> var address = "";<br> var price = "";<br> var comments = "";<br> var properties = results.getElementsByTagName("property");<br> for(var i = 0; i < properties.length; i++) {<br> property = properties[i];<br> address = property.getElementsByTagName("address")[0].firstChild.nodeValue;<br> price = property.getElementsByTagName("price")[0].firstChild.nodeValue;<br> comments = property.getElementsByTagName("comments")[0]<br> .firstChild.nodeValue;<br> addTableRow(address, price, comments);<br> }<br> var header = document.createElement("h2");<br> var headerText = document.createTextNode("Results:");<br> header.appendChild(headerText);<br> document.getElementById("header").appendChild(header);<br> document.getElementById("resultsTable").setAttribute("border", "1");<br> }<br> function addTableRow(address, price, comments) {<br> var row = document.createElement("tr");<br> var cell = createCellWithText(address);<br> row.appendChild(cell);<br> cell = createCellWithText(price);<br> row.appendChild(cell);<br> cell = createCellWithText(comments);<br> row.appendChild(cell);<br> document.getElementById("resultsBody").appendChild(row);<br> }<br> function createCellWithText(text) {<br> var cell = document.createElement("td");<br> var textNode = document.createTextNode(text);<br> cell.appendChild(textNode);<br> return cell;<br> }<br> </script><br> </head><br> <body><br> <nowiki> <h1>Search Real Estate Listings</h1> </nowiki><br> <nowiki><form action="#"> </nowiki><br> <nowiki>Show listings from </nowiki><br> <nowiki><select> </nowiki><br> <nowiki><option value="50000">$50,000</option> </nowiki><br> <nowiki><option value="100000">$100,000</option> </nowiki><br> <nowiki><option value="150000">$150,000</option> </nowiki><br> <nowiki></select> </nowiki><br> <nowiki>to </nowiki><br> <nowiki><select> </nowiki><br> <nowiki><option value="100000">$100,000</option> </nowiki><br> <nowiki><option value="150000">$150,000</option> </nowiki><br> <nowiki><option value="200000">$200,000</option> </nowiki><br> <nowiki></select> </nowiki><br> <nowiki><input type="button" value="Search" onclick="doSearch();"/> </nowiki><br> </form><br> <nowiki><span id="header"> </nowiki><br> <nowiki></span> </nowiki><br> <nowiki><table id="resultsTable" width="75%" border="0"> </nowiki><br> <nowiki><tbody id="resultsBody"> </nowiki><br> <nowiki></tbody> </nowiki><br> <nowiki></table> </nowiki><br> </body><br> </html><br> [[category:Ajax]]
摘要:
请注意,您对站长百科的所有贡献都可能被其他贡献者编辑,修改或删除。如果您不希望您的文字被任意修改和再散布,请不要提交。
您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源(参阅
Wordpress-mediawiki:版权
的细节)。
未经许可,请勿提交受版权保护的作品!
取消
编辑帮助
(在新窗口中打开)