标题:Ajax和XML:五种常见Ajax模式适合什么人群:java开发人员、jsp页面设计人员、Ajax开发人员、Ajax爱好者、深入学习Ajax的人员可以解决什么问题:使用Ajax技术播放电影和幻灯片正文:简单的视频选择首先来看网站,网站上有一个电影列表可供选择—一个不用改变页面就能选择不同电影的网站。页面代码如清单1所示。清单1.index.htmlhtmlheadscriptsrc=prototype.js/script/headbodydivid=movieHost/divdivid=movieList/divscriptfunctionsetMovie(url){$('movieHost').innerHTML='';varelEmbed=document.createElement('embed');elEmbed.src=url;$('movieHost').appendChild(elEmbed);}newAjax.Request('movies.xml',{method:'get',onSuccess:function(transport){varmovieTags=transport.responseXML.getElementsByTagName('movie');$('movieList').innerHTML='';varbFirst=true;for(varb=0;bmovieTags.length;b++){varurl=movieTags[b].getAttribute('url');vartitle=movieTags[b].getAttribute('title');if(bFirst){setMovie(url);bFirst=false;}varhtml='ahref=javascript:voidsetMovie(\''+url+'\');';html+=title+'/abr/';$('movieList').innerHTML+=html;}}});/script/body/html该页面使用Prototype.js这个很棒的JavaScript库向movies.xml数据源发送Ajax请求。返回数据后通过getElementsByTagName()方法查找所有电影标签。对每个电影标签,代码检索URL和标题。如果检索的标签是列表中的第一部电影,脚本立即开始放映这部电影。否则添加一个anchor标签作为movieListdiv的电影选择器。电影选择器anchor调用setMovie()函数打开指定的电影。播放电影的方法很简单,首先将movieHostdiv标签置空,即删除原来的电影。然后将内容设置为embed标签,其URL由电影列表指定。embed标签是在页面中播放电影最简单的方法,但是存在跨浏览器的问题。另一种办法是同时使用object和embed标签。这个简单的例子中,movies.xml只是一个平面文件,包含一些我自己的家庭短片的引用。该文件如清单2所示。清单2.movies.xmlmoviesmovieurl=spider.movtitle=Spider/movieurl=swing.movtitle=SwingSet/movieurl=water.movtitle=WaterSplash//movies打开该页面时,显示的结果如图1所示。图1.简单的电影列表页面最上方是一部由embed标签播放的电影,下面是其他影片列表。点击其中的任何链接,正在播放的电影就变成所选择的电影。显然,这个系统不适合大型的视频资料库,还需要对影片列表进行某种搜索。可搜索的电影列表要添加搜索功能,必须添加一个搜索框,如清单3所示。其中增加了搜索输入字段q。清单3.添加搜索功能htmlheadscriptsrc=prototype.js/script/headbodytabletrtdvalign=topinputtype=textid=qonkeyup=search()divid=movieList/div/tdtdvalign=topdivid=movieHost/div/td/tr/tablescriptfunctionsetMovie(url){$('movieHost').innerHTML='';varelEmbed=document.createElement('embed');elEmbed.src=url;$('movieHost').appendChild(elEmbed);}functionsearch(){newAjax.Request('search.php?q='+escape($('q').value),{method:'get',onSuccess:function(transport){varmovieTags=transport.responseXML.getElementsByTagName('movie');$('movieList').innerHTML='';varbFirst=true;for(varb=0;bmovieTags.length;b++){varurl=movieTags[b].getAttribute('url');vartitle=movieTags[b].getAttribute('title');if(bFirst){setMovie(url);bFirst=false;}varhtml='ahref=javascript:voidsetMovie(\''+url+'\');';html+=title+'/abr/';$('movieList').innerHTML+=html;}}});}/script/body/html在key-up事件中指定search()方法将被调用。search()方法和Ajax.Request调用类似,除了向search.php页面传递查询字符串。search.php脚本返回和原来相同的XML格式,因此不需要修改XML解析的代码。我承认对于自己的习惯来说,key-up上的search()函数反映有点太快。理想情况下,系统应该在执行搜索之前等待一秒左右以便输入完整的搜索文本,避免列表不停地闪烁。使用window.setTimeout()方法很容易实现这种行为。清单4显示了经过修改的search.php脚本。清单4.search.php?phpheader('content-type:text/xml');$movies=array();$movies['spider.mov']='Spider';$movies['swing.mov']='SwingSet';$movies['water.mov']='WaterSplash';?movies?phpforeach($moviesas$k=$v){if(strlen($_GET['q'])0&&preg_match('/'.$_GET['q'].'/i',$v)){?movieurl=?phpecho($k)?title=?phpecho($v)?/?php}}?/movies脚本一开始建立了一个数组保存全部电影。为了简化起见,这里对电影进行了硬编码。实际应用的时候这些元素很可能取自电影清单的数据库。接下来的代码遍历列表,把搜索查询的正则表达式应用于每个电影的标题。如果匹配则输出包含URL和名称的movie标签。打开页面并输入s,将看到图2所示的页面。图2.简单的电影查询页面如果按下Delete建并输入water,就会看到图3所示的页面。图3.搜索与“water”相关的电影的查询页面虽然本文主要讨论如何使用DynamicHTML(DHTML)和Ajax建立前端应用程序,但视频共享网站决不是这么简单。视频分享基础先暂时离开实践问题讨论一些更具理论性的东西,视频共享中更加复杂的问题。涉及到三个主要问题:如何存储和传输视频如何处理不同的视频格式如何从上传文件中获得缩略图和视频信息视频存储是一个实实在在的问题—特别是对于小应用程序而言视频文件非常大,需要大容量的硬盘空间来存储。将其传递给客户还面临着带宽的挑战。可以自己购买设备安装到托管设施中。或者使用AmazonS3这样的服务,只需很低的价格就能上传任何资料(数据库备份、图片、电影等等)到Amazon数据中心,以及提供给其他客户。和建立数据中心的大量投资相比可以先考虑一下这些服务。下一个问题—视频格式—提出了一个有趣的挑战。存在多种视频格式,没有任何一种播放器能支持所有格式。事实上多数播放器只能处理自己挑选的视频格式。为了方便用户,也许最好以某种格式为标准然后将所有传来的视频都转化成这种格式。有一种非常方便的工具,即命令行应用程序FFmpeg。它不仅能把一种视频格式转化成另一种,还能拾取画面的快照从而为用户提供视频缩略图。选择何种视频格式作为标准可能很麻烦。目前Flash视频具有明显的优势,但是WindowsMedia®,特别是随着MicrosoftSilverlight(原来的WPF/Everywhere)的发布,正在赢得越来越多的支持。FFmpeg几乎能将任何影片格式转化成Flash视频格式,这一点很吸引人。而且有一些免费和开源的Flash播放器很容易嵌入到网站上。将这些播放器和上述代码结合起来就能建立一个完整的、以Ajax为前端的端到端视频分享解决方案。但Web上不仅仅有视频,图像共享也很重要。幻灯片放映清单5显示了一个简单的基于DHTML的幻灯片,数据来自XML文件。清单5.index.htmlhtmlheadscriptsrc=prototype.js/script/headbodybgcolor=blackdivstyle=text-align:center;imgid=imgItemsrc=style=display:none;brdivid=imgTitlestyle=color:white;font-family:arial;font-size:24pt;/div/divscriptvarg_images=[];varg_slideIndex=0;functionshowSlide(){$('imgTitle').hide();$('imgItem').hide();varheight=600;varwidth=(height/g_images[g_slideIndex].height)*g_images[g_slideIndex].width;$('imgItem').src=g_images[g_slideIndex].src;$('imgItem').width=width;$('imgItem').height=height;$('imgTitle').innerHTML=g_images[g_slideIndex].title;$('imgTitle').show();$('imgItem').show();g_slideIndex++;if(g_slideIndex=g_images.length)g_slideIndex=0;}newAjax.Request('images.xml',{method:'get',onSuccess:function(transport){varimageTags=transport.responseXML.getElementsByTagName('image');for(varb=0;bimageTags.length;b++){g_images.push({src:imageTags[b].getAttrib