`

[转] 使用 DHTML 与 XML 制作 Ajax 幻灯片

 
阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>

使用 DHTML 与 XML 制作 Ajax 幻灯片

Jack Herrington (jack_d_herrington@codegeneration.net), 高级软件工程师, Code Generation Network
2006 年 5 月 23 日

学习如何创建通过 “Ken Burns Effects” 实现动画的 Ajax 客户端幻灯片放映。通过本文,您将了解如何创建 Ajax XML 数据源、从客户机请求 XML 并用 XML 动态地创建活动的 HTML 元素。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->

如果说 Web 2.0 革命有一个时髦词的话,那就是 Asynchronous JavaScript and XML(Ajax)。应用程序的客户端交互,如 Google Maps™ 地图服务和 Gmail™ 网络邮件服务,使得 Ajax 不仅是一个振奋人心的词汇,而且具有实用价值。Ajax 技术包括超文本标记语言(HTML)、JavaScript 代码、级联样式表(CSS)、XML 和异步 Web 请求,与我们所见的 Web V1.0 相比能创建更令人信服的 Web 交互。当然,这些技术自 Microsoft® Internet Explorer® V4 发布以来就存在了,但是直到最近才通过其他一些引人注目的应用显示出其优势。

实现 Ajax 很难吗?Ajax 模型的每个成分都很容易学习。但关键在于将这些成分结合起来,融为一体。通常这是一个复合性的问题,因为客户端编码和服务器端编码由不同的人来做。本文说明一个人如何在一两个小时中就能编写出小型的基于 Ajax 的幻灯片放映应用程序。

Ajax 幻灯片放映

个人图像管理应用程序(如 Macintosh® 上的 Apple® iPhoto®)使得幻灯片浏览广为人知。在幻灯片浏览中,图像按照时间顺序先后淡入淡出。此外,图片还通过所谓的 “Ken Burns Effect” 进行移动和缩放。

在该例中,我让浏览器从服务器上下载一个图像列表。然后使用动态 HTML(DHTML)把图片列表组成一个幻灯片。我使用随机的缓慢移动、缩放和渐变来改变图片,实现了令人满意的 Ken Burns Effect 版本,而不需要下载 Macromedia® Flash 或其他重量级的动画工具。


体系结构

要了解 Ajax 有何不同,首先必须理解当前的 Web 编程模型。客户机和服务器之间的简单交互如 图 1 所示。



图 1. 客户机-服务器交互的 Web V1.0 模型
客户机-服务器交互的 Web V1.0 模型

Web 浏览器或者客户机 向 Web 服务器发出 GETPOST 请求。服务器格式化 HTML 响应。客户机解析 HTML 并显示给用户。如果用户单击其他链接和按钮,就向服务器发出另一个请求,用服务器返回的新页面替换当前页面。

新模型具有更多的异步特色,如 图 2 所示。

图品URL:http://www-128.ibm.com/developerworks/cn/xml/x-ajaxslideshow/sequence2_372_188.gif

图 2. 客户机-服务器交互的 Ajax 模型
Ajax 客户机-服务器交互

在新的模型中,和以前一样,服务器也返回 HTML 页面。但是这个页面中有一些 JavaScript 代码。在需要的时候,这些代码向服务器请求更多信息。这些请求可以是简单的 GET 请求(Representational State Transfer (REST) 服务)或者 POST 请求(SOAP)。

然后,JavaScript 代码解析响应(通常用 XML 编码)并动态更新页面以反映新的数据。除了 XML 外,还返回 JavaScript Serialized Object Notation(JSON)格式编码的数据。浏览器很容易理解这类数据,但其他类型的客户机则不行。返回 XML 的意义在于浏览器之外的其他客户机也能解释数据。选择由您来决定并依赖于具体的应用程序。


提供图片信息

开发 Ajax 幻灯片的第一步是结合 REST 数据服务。该例中使用 PHP 页面返回所有可用的幻灯片图像及其大小(宽和高)。所有图像都放在 images 目录中。文件名格式为 name_width_height.jpg,比如 oso1_768_700.jpg 表示该文件是我的狗 Oso 的照片,宽 768 像素,高 700 像素。我坚持使用这种命名方式,因为这样就很容易确定图片的宽和高,而不用费力去打开 Adobe® PhotoShop® 或 Macromedia Fireworks。

我使用 清单 1 所示的 PHP 服务器代码来提供图片列表。



清单 1. slides.php 服务器页面

<?phpheader ( "Content-type: text/xml" );?><slides><?phpif ($handle = opendir('images')) {while (false !== ($file = readdir($handle))){        if ( preg_match( "/[.]jpg$/", $file ) ) {                preg_match( "/_(/d+)_(/d+)[.]/", $file, $found );?><slide src="images/&lt;?php%20echo%20%24file;%20?&gt;" width="&lt;?php echo $found[1]; ?&gt;" height="&lt;?php echo $found[2]; ?&gt;"></slide><?php echo( "/n" ); ?><?php }}closedir($handle);}?></slides>

代码很简单。首先将内容类型设置为 XML。让浏览器将该文档识别为 XML 并为其创建文档对象模型(DOM)至关重要。代码从 <slides></slides> 标记开始,然后读取图片目录并为遇到的每个图片创建 <slide></slide> 标记。最后脚本结束 <slides></slides> 标记。

如果用 Mozilla® Firefox® 浏览器打开(在我的机器上)本地主机 kenburns 目录中的该页面,就会看到 图 3 所示的结果。

图片URL:http://www-128.ibm.com/developerworks/cn/xml/x-ajaxslideshow/slides_400_293.jpg

图 3. slides.php 服务器脚本的输出
slides.php 服务器脚本的输出

一共三幅图片:我的女儿和我的两条狗。当然在这里可以增加任何需要的细节或者多媒体,但我尽量保持例子的简单性。



检索 XML

下一步就是编写一个 HTML 页面(如 清单 2 所示)从服务器读取数据并检验浏览器和服务器之间使用的 Ajax 连接。这段 HTML 代码包含内嵌的 JavaScript 代码,检索 XML 并打开一个警告窗口显示服务器返回的文本。



清单 2. 简单的 Ajax 读取数据页面

<script>function processReqChange(){ if (req.readyState == 4 && req.status == 200 && req.responseXML != null)  {    alert( req.responseText );  }}function loadXMLDoc( url ){  req = false;  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("");  }}loadXMLDoc( "http://localhost/kenburns/slides.php" );</script>

代码从指定的 URL 获取 XML 内容,然后 loadXMLDoc 函数启动 Ajax 请求。检索页面的请求异步发出并返回结果。请求完成后,对结果调用 processReqChange 函数。这里用 processReqChange 函数在警告窗口中显示 responseText 的函数值。在我的 Firefox 浏览器中调用该页面的结果如 图 4 所示。



图 4. 在警告窗口中显示的 XML
图片URL:http://www-128.ibm.com/developerworks/cn/xml/x-ajaxslideshow/test1_400_291.jpg

警告窗口中的 XML

开局不错。毫无疑问,我们从服务器取回了 XML 数据。但是有必要指出几点。首先要注意 URL 使用了绝对路径,包括域名等等。对于 Ajax 来说这是唯一有效的 URL 格式。编写 Ajax JavaScript 代码的服务器代码总是创建有效的、完整格式的 URL。

这里不那么明显的另一点是 Ajax 的安全保护措施。JavaScript 代码不能请求任意的 URL。URL 的域名必须和该页面相同。在这里域名就是 localhost。但必须指出不能呈现 www.mycompany.com 的 HTML 但却让脚本从 data.mycompany.com 检索数据。域必须完全相同,包括子域名。

有趣的另一点是 loadXMLDoc 中的代码,似乎是费力地创建一个请求对象。为何这么麻烦呢?Internet Explorer 7 的预览版没有内建 XMLHTTPRequest 对象类型。因此必须使用 Microsoft ActiveX® 控件。

最后在 processReqChange 函数中,可以看到我在查看 readyState 是否等于 4status 是否设为 200readyState 的值 4 表示事务已经完成。status 的值 200 表示页面是有效的。如果没有找到页面,就可能会得到错误消息 404,就像您在浏览器中看到的那样。这里没有处理异常情况,因为这仅仅是一个例子,不过发布的 Ajax 代码应该处理返回错误的请求。



动态创建 HTML

在说明如何创建幻灯片放映之前,首先扩展现在的例子,让 processReqChange 函数用服务器返回的 XML 请求结果创建一个 HTML 表格。这样做可以验证两件事:能够读取 XML 并能够根据 XML 动态创建 HTML。

清单 3 显示了修改后的代码,它将从返回的 XML 创建表格。



清单 3. 改进的测试页面


<script>function processReqChange(){ if (req.readyState == 4 && req.status == 200 && req.responseXML != null) { var dto = document.getElementById( 'dataTable' ); var items = []; var nl = req.responseXML.getElementsByTagName( 'slide' ); for( var i = 0; i < nl.length; i++ ) { var nli = nl.item( i ); var src = nli.getAttribute( 'src' ).toString(); var width = parseInt( nli.getAttribute( 'width' ).toString() ); var height = parseInt( nli.getAttribute( 'height' ).toString() ); var trNode = document.createElement( 'tr' ); var srcNode = document.createElement( 'td' ); srcNode.innerHTML = src; trNode.appendChild( srcNode ); var widthNode = document.createElement( 'td' ); widthNode.innerHTML = width.toString(); trNode.appendChild( widthNode ); var heightNode = document.createElement( 'td' ); heightNode.innerHTML = height.toString(); trNode.appendChild( heightNode ); dto.appendChild( trNode ); } load_slides( items ); start_slides(); }}function loadXMLDoc( url ){ req = false; 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(""); }}loadXMLDoc( "http://localhost/kenburns/slides.php" );</script>

在浏览器中打开该页面将显示 图 5 所示的结果。



图 5. 修改后的测试页
图片URL:http://www-128.ibm.com/developerworks/cn/xml/x-ajaxslideshow/test2_400_290.jpg

修改后的测试页

修改后的 processReqChange 代码现在查看 responseXML 对象而不是 responseText 文本。此外,它还使用 getElementsByTagName 访问所有的 <slide></slide> 标记。然后解析 srcwidthheight 属性,并使用 document 对象的 createElement 方法创建行和单元格来存放数据。该方法使用的 createElement 远比过去的老方法健壮,原来要建立一个包含表格内容的 HTML 字符串,然后用 innerHTML 将数据添加到已有的元素中。

创建幻灯片放映

现在已经有了能够确定幻灯片中图像的 Web 服务,还需要显示这些幻灯片并执行 Ken-Burns-Effect 动画的客户端代码。为此必须将执行三种基本功能的 JavaScript 对象结合起来:

  1. 封装图像
  2. 提供基本的动画引擎
  3. 实现特效(比如移动、缩放和渐变)

封装图像

首先从图像容器开始,我创建一个类 ImageInfo,如 清单 4 所示。



清单 4. ImageInfo.js

function ImageInfo( src, width, height, htmlObj ){  this.src = src;  this.width = width;  this.height = height;  this.current_width = width;  this.current_height = height;  this.htmlObj = htmlObj;  this.htmlObj.src = this.src;  this.htmlObj.width = this.current_width;  this.htmlObj.height = this.current_height;}ImageInfo.prototype.set_opacity = function( opacity ){  this.htmlObj.style.MozOpacity = opacity / 100;  var f = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+opacity+')';  this.htmlObj.style.filter = f;}ImageInfo.prototype.set_position = function( x, y ){  this.htmlObj.style.left = x+'px';  this.htmlObj.style.top = y+'px';}ImageInfo.prototype.set_size = function( w, h ){  this.current_width = w;  this.current_height = h;  this.htmlObj.width = this.current_width;  this.htmlObj.height = this.current_height;}ImageInfo.prototype.get_image = function(){  return this.htmlObj;}ImageInfo.prototype.hide = function(){  this.htmlObj.style.visibility = 'hidden';}ImageInfo.prototype.show = function(){  this.htmlObj.style.visibility = 'visible';}

幻灯片中每幅图片都有一个对应的 ImageInfo 对象。该对象封装了图像信息:srcwidthheight。该对象还包含对在文档中显示图像的 HTML 标记的引用,以及移动图像、设置透明度等的 helper 方法。注意,在 Firefox 和其他基于 Gecko® 的浏览器中,MozOpacity 样式用于设置不透明性。Internet Explorer 中则使用过滤器效果。

创建简单的动画引擎

下面我们来编写一个简单的动画引擎。Animation.js 文件中的代码如 清单 5 所示。



清单 5. Animation.js

function Animation( am, img, seconds, effects ){  this.img = img;  this.animationManager = am;  this.seconds = seconds;  this.effects = effects;  this.startMS = 0;}Animation.prototype.start = function(){  this.animationManager.add( this );  this.startMS = 0;  this.img.hide();  for( var e in this.effects )  {    this.effects[e].apply( 0 );  }  this.img.show();}Animation.prototype.animate = function(){  var d = new Date();  if ( this.startMS == 0 )    this.startMS = d.valueOf();  var p = (((d.valueOf()-this.startMS)/1000)/this.seconds)*100;  for( var e in this.effects )    this.effects[e].apply( p );}Animation.prototype.done = function(){  var d = new Date();  return ( ( d.valueOf() - this.startMS ) / 1000 ) > this.seconds;}function AnimationManager( speed ){   this.animations = [];   var self = this;   window.setInterval( function() { self.idle(); }, speed );}AnimationManager.prototype.add = function( anim ){  this.animations.push( anim );}AnimationManager.prototype.idle = function(){  if ( this.animations.length > 0 )  {    this.animations[0].animate();    if ( this.animations[0].done() )      this.animations.shift();    if ( this.animations.length == 0 )      this.on_finished();  }}AnimationManager.prototype.on_finished = function(){}

清单 5 包含两个类:AnimationAnimationManagerAnimationManager 类控制定时器并向其 Animation 对象列表中的第一项发送动画消息。当 Animation 对象报告自己已经完成的时候,该类就转向下一项,依此类推。

Animation 在一定的时间(按秒数指定)内对特定图片应用一系列特效。Animation 对象需要计算完成度消息并将其发送给每种特效的 apply 方法。特效然后根据这个百分比计算应该如何处理图像。比如,移动特效知道起点和终点,可以根据这个百分比计算应该将图像放到何处。如果是 50%,图像应该移到起点和终点之间。

作为我工作的一部分,同时也为了撰写本文,我考察了大量的 JavaScript 动画代码。JavaScript 动画经常因为不稳定而受到指责,因为所有 JavaScript 动画都使用 window.setInterval 方法来完成。这是一个定时器方法,同时指定了回调时间间隔和回调函数。Web 上的大部分代码都要求每次调用该函数时动画移动一步。但这并不能真正工作,因为告诉浏览器的间隔仅仅是一个建议。如果规定 20 毫秒,但实际上可能第一次在 25 毫秒时调用,下一次却要等到一秒钟以后。浏览器是单线程的,因此不能依赖于定时器。

解决方案是使用 Date 对象的 valueOf 方法确定动画开始了多长时间。这个时间差是用毫秒计的,用于确定当 setInterval 定时器离开时动画应该执行百分之多少。该方法可以提供规定的任意长时间的平滑动画。

执行特效

三个核心类的最后一个是 Ken Burns Effects。这些特效通过 Animation 对象应用于图像,如 清单 6 所示。



清单 6. KenBurnsAnimations.js

function KenBurnsFader( img, windowSize ){  this.img = img;  this.windowSize = windowSize;}KenBurnsFader.prototype.apply = function( percent ){  var opacity = 100;  if ( percent = ( 100 - this.windowSize ) )    opacity = ( ( 100 - percent ) / this.windowSize ) * 100;  this.img.set_opacity( opacity );}function KenBurnsZoomer( img, start, end, cw, ch ){  this.start = start;  this.end = end;  this.img = img;  var wr = this.img.width / cw;  var nw = this.img.width * wr;   var nh = this.img.height * wr;   this.sw = ( nw * ( this.start / 100 ) );  this.ew = ( nw * ( this.end / 100 ) );  this.sh = ( nh * ( this.start / 100 ) );  this.eh = ( nh * ( this.end / 100 ) );  this.dw = ( this.ew - this.sw ) / 100;  this.dh = ( this.eh - this.sh ) / 100;}KenBurnsZoomer.prototype.apply = function( percent ){  this.img.set_size(    this.sw + ( this.dw * percent ),    this.sh + ( this.dh * percent ) );}function KenBurnsMover( img, sx, sy, ex, ey, cw, ch ){  this.img = img;  this.sx = sx / 100;  this.ex = ex / 100;  this.sy = sy / 100;  this.ey = ey / 100;  this.cw = cw;  this.ch = ch;  this.wr = this.img.width / this.cw;}KenBurnsMover.prototype.apply = function( percent ){  var nw = this.img.current_width * this.wr;  var nh = this.img.current_height * this.wr;  var cntw = ( ( this.cw / 2 ) - ( nw / 2 ) );  var cnth = ( ( this.ch / 2 ) - ( nh / 2 ) );  var sx = ( nw * this.sx );  var ex = ( nw * this.ex );  var sy = ( nh * this.sy );  var ey = ( nh * this.ey );  var dx = ( ex - sx ) / 100;  var dy = ( ey - sy ) / 100;  var x = cntw + sx + ( dx * percent );  var y = cntw + sy + ( dy * percent );  this.img.set_position( x, y );}

这三个类分别处理应用于图像的不同特效。KenBurnsFader 类使用不透明度处理图像的淡入淡出。KenBurnsZoomer 类处理图像的缩放,从最初的大小到最终的大小。KenBurnsMover 类处理图像的移动,从起点到终点(用图像的百分比指定)。

经过一些试验后,我发现最吸引人的移动特效是相对于窗口中心从一个角移动到另一个角。KenBurnsMover 类的 apply 方法包含一些复杂的数学运算,不仅相对于包含图像的

标记的中心来移动,还要计算图像和
标记的相对大小,这样在小窗口中移动的距离就小,在大窗口中移动的距离就大。放大倍数根据窗口的高度确定。

实现非 Ajax DHTML

有了这些基础类之后,就可以实现幻灯片的非 Ajax DHTML 版本来进行测试了,如 清单 7 所示。



清单 7. 非 Ajax 幻灯片放映

<style type="text/css">body { background: black; margin: 0px; padding: 0px; }</style><script src="KenBurnsAnimations.js"></script><script src="Animation.js"></script><script src="ImageInfo.js"></script><script>var g_animationManager = new AnimationManager( 50 );var g_current_slide = 0;var g_slides = [];var g_directions = [{ sx: [ -30, 0 ], ex: [ 5, 40 ], sy: [ -30, 0 ], ey: [ 5, 40 ] }, // nw -> se{ sx: [ 5, 40 ], ex: [ -30, 0 ], sy: [ 5, 40 ], ey: [ -30, 0 ] }, // ne -> sw{ sx: [ 5, 40 ], ex: [ -30, 0 ], sy: [ 5, 40 ], ey: [ -30, 0 ] }, // se -> nw{ sx: [ -30, 0 ], ex: [ 5, 40 ], sy: [ 5, 40 ], ey: [ -30, 0 ] } // sw -> ne];g_animationManager.on_finished = function(){  g_current_slide++;  if ( g_current_slide >= g_slides.length )    g_current_slide = 0;  g_slides[ g_current_slide ].start();}function rnd( start, end ){  return ( Math.random() * ( end - start ) ) + start;}function load_slides( images ){  var ic = document.getElementById( 'imgContainer' );  for( var i in images )  {    var img = images[i];    var imgObj = document.createElement( 'img' );    imgObj.style.position = 'absolute';    imgObj.style.left = '0px';    imgObj.style.top = '0px';    imgObj.style.visibility = 'hidden';    ic.appendChild( imgObj );    var ii = new ImageInfo( img.src, img.width, img.height, imgObj );        var szoom = rnd( 50, 100 );        var ezoom = rnd( 70, 120 );        var d = parseInt( ( Math.random() * g_directions.length ).toString() );        var di = g_directions[ d ];        var sx = rnd( di.sx[0], di.sx[1] );        var sy = rnd( di.sy[0], di.sy[1] );        var ex = rnd( di.ex[0], di.ex[1] );        var ey = rnd( di.ey[0], di.ey[1] );    g_slides.push(       new Animation( g_animationManager, ii, 10,        [ new KenBurnsZoomer( ii, szoom, ezoom, ic.clientWidth, ic.clientHeight ),          new KenBurnsMover( ii, sx, sy, ex, ey, ic.clientWidth, ic.clientHeight ),          new KenBurnsFader( ii, 30 ) ] )    );  }}function start_slides(){  g_slides[ g_current_slide ].start();}</script>
<script>var images = [{ src: 'images/megan1_875_700.jpg', width: 875, height: 700 },{ src: 'images/oso1_875_700.jpg', width: 875, height: 700 },{ src: 'images/oso2_873_700.jpg', width: 873, height: 700 }];load_slides( images );start_slides();</script>

不用电影是很难说明上述代码在浏览器中的运行结果的。因此我抓了一个快照,如 图 6 所示。



图 6. 幻灯片放映的快照
图片URL:http://www-128.ibm.com/developerworks/cn/xml/x-ajaxslideshow/kenburns_400_288.jpg

快照

该页面首先通过 <script></script> 标记的 src 属性引入基类。安装这些类之后,增加两个函数将整个机制组织到一起:load_slidesstart_slidesload_slides 函数接收一个数组,包括图像的 srcwidthheight,然后创建 标记和动画。start_slides 函数从第一项开始启动幻灯片放映。

附加在动画管理器上的另一个方法 on_finished 在动画完成时调用。我使用该通知移动到下一张幻灯片,如果已经完成所有幻灯片的动画,则回到列表中的第一张。

再回到 load_slides,要注意它引用了一个名为 g_directions 的数组。该数组包含一些随机范围,幻灯片加载程序用它来规定图片移动的起点和终点。最理想的效果是从一个角到另一个角。从注释中可以看到,这些值规定幻灯片的移动范围为东北、东南、西北和西南的任意组合。最后的 <script></script> 标记定义了一个图像数组,然后使用 load_slidesstart_slides 函数启动幻灯片放映。

创建 Ajax 幻灯片放映

最后一步是创建 Ajax 版本的幻灯片放映。这意味着要使用从 slides.php 服务获得的内容代替硬编码的图像列表。

Ajax 版本的幻灯片放映代码如 清单 8 所示。



清单 8. Ajax 幻灯片代码

<style type="text/css">body { background: black; margin: 0px; padding: 0px; }</style><script src="KenBurnsAnimations.js"></script><script src="Animation.js"></script><script src="ImageInfo.js"></script><script src="SlideShow.js"></script>
<script>function processReqChange(){ if (req.readyState == 4 && req.status == 200 && req.responseXML != null) { var items = []; var nl = req.responseXML.getElementsByTagName( 'slide' ); for( var i = 0; i < nl.length; i++ ) { var nli = nl.item( i ); var src = nli.getAttribute( 'src' ).toString(); var width = parseInt( nli.getAttribute( 'width' ).toString() ); var height = parseInt( nli.getAttribute( 'height' ).toString() ); items.push( { src: src, width: width, height: height } ); } load_slides( items ); start_slides(); }}function loadXMLDoc( url ){ req = false; 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(""); }}loadXMLDoc( "http://localhost/kenburns/slides.php" );</script>

我把 start_slidesload_slides 函数移到了外部 JavaScript 文件 SlidesShow.js 中,以免该文件过大。代码的其他部分和 清单 2 中的 Ajax 测试页类似。只不过这些代码没有插入警告窗口,也没有把数据插入一个表格,而是创建了一个幻灯片信息数组,然后调用 load_slidesstart_slides

如此而已!这样就可以使用 Ken Burns Effect 动态地移动、缩放和渐变图像的 Ajax 幻灯片。

结束语

本文中尽可能地使用了面向对象的 JavaScript 代码。JavaScript 是一种完全面向对象的语言,虽然可能不使用 classinterface 关键字,但仍然可以保持代码的清晰性和可维护性。如果可以的话,我建议您使用 Ajax 框架。这里没有使用框架是因为我想介绍一种轻型的 Ajax 解决方案。但现在的框架(有很多)更容易编写更具可移植性的 Ajax 和 DHTML 代码。

除了本文中介绍的之外,关于 Ajax 幻灯片我还有以下建议:

  • 使用基于时间的动画。用 setInterval 代码实现基于步骤的动画看起来有些抖动。
  • 对可视化元素用 DHTML 建立代码原型,然后再增加 Ajax 内容。这意味着可以离线编写 DHTML 代码。
  • 将连接到服务器的 Ajax 代码和呈现数据的 DHTML 用户界面(UI)组件分开。这样即便不使用 Ajax 获取数据,也仍然能够使用那些界面组件。
  • 使用 createElementappendChild 函数而不是 innerHTML 来改变页面内容。
  • 一定要针对所有希望支持的浏览器检查客户端代码。此外,还要记录下您所遇到的兼容性问题以及解决这些问题的方法。尽量将固定的客户端代码封装成可重用的 JavaScript helper 函数和类。
  • 对于复杂的界面(包括多重动画),编码之前应首先使用情节串连板与客户一起确定他们所需要的效果。情节串连板是代码规范的动画版本。JavaScript 动画写起来很快,因此在编码之前明确目标是值得的,否则可能走不少冤枉路。
  • 从职业的角度来看,仅关注数据库和业务逻辑的 Web V1.0 时代的 “后端工程师”,在 Web V2.0 时代中作用是有限的。必须认识到并非所有对服务器的请求都要借助于 HTML。Ajax 和 DHTML 对那些愿意花钱提高其技能的真正的工程师来说是现实的工具。前端不仅仅是设计人员的前端。

过去,通常需要 Flash 或者类似的应用程序才能实现本文这样的动态幻灯片放映。现代化的浏览器为 DHTML 提供了不透明性这类丰富的特效支持(Internet Explorer 甚至支持旋转、模糊等),再加上 Ajax,仅仅在浏览器中就能实现令人眩目的效果。这意味着客户不再需要下载奇怪的扩展或者运行有可能不安全的应用程序。他们可能偶尔看到了您的网页,令人震惊的图像效果会让他们经常来光顾。

下载源代码:Code and file samples for this article
http://download.boulder.ibm.com/ibmdl/pub/software/dw/xml/x-ajaxslideshow/kenburns.zip

原文来自:http://www-128.ibm.com/developerworks/cn/xml/x-ajaxslideshow/index.html
本blog只是处于传播技术的观点,所有权归IBM所有




<script type="text/javascript"> new Ad(4, 'ad_cen'); </script>
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
<script type="text/javascript"> var fileName = '2276837'; var commentscount = 0; var islock = false </script><script type="text/javascript" src="http://static.blog.csdn.net/scripts/comment.js"></script>
<script type="text/javascript"> new Ad(5, 'ad_bot'); </script>
分享到:
评论

相关推荐

    【前端素材】大数据-设备环境监测平台.zip

    大数据技术指的是用于处理和分析大规模数据集的技术和工具。以下是一些常见的大数据技术和工具: Hadoop:Apache Hadoop是一个用于分布式存储和处理大规模数据的开源框架。它包括Hadoop Distributed File System(HDFS)用于数据存储和MapReduce用于数据处理。 Spark:Apache Spark是一个快速、通用的集群计算系统,提供了比MapReduce更快的数据处理能力。它支持内存计算和更多复杂的数据处理流程。 NoSQL数据库:NoSQL数据库(如MongoDB、Cassandra等)则更适用于处理这类数据。 数据仓库:数据仓库是一个用于集成和分析大规模数据的存储系统,一些知名的数据仓库包括Snowflake、Amazon Redshift等。 数据湖:数据湖是一个存储结构化和非结构化数据的存储池,用于支持数据分析和机器学习应用。 机器学习:大数据技术也广泛应用于机器学习领域,支持大规模数据的模型训练和预测分析。 流式处理:针对实时数据处理需求,流式处理技术(如Apache Kafka、Apache Flink)可以实时。

    倍福GSDML-V2.31-Pepperl+Fuchs-PxV100-20210104.xml

    倍福GSDML-V2.31-Pepperl+Fuchs-PxV100-20210104.xml

    【前端素材】大数据-地图数据可视化.zip

    大数据技术指的是用于处理和分析大规模数据集的技术和工具。以下是一些常见的大数据技术和工具: Hadoop:Apache Hadoop是一个用于分布式存储和处理大规模数据的开源框架。它包括Hadoop Distributed File System(HDFS)用于数据存储和MapReduce用于数据处理。 Spark:Apache Spark是一个快速、通用的集群计算系统,提供了比MapReduce更快的数据处理能力。它支持内存计算和更多复杂的数据处理流程。 NoSQL数据库:NoSQL数据库(如MongoDB、Cassandra等)则更适用于处理这类数据。 数据仓库:数据仓库是一个用于集成和分析大规模数据的存储系统,一些知名的数据仓库包括Snowflake、Amazon Redshift等。 数据湖:数据湖是一个存储结构化和非结构化数据的存储池,用于支持数据分析和机器学习应用。 机器学习:大数据技术也广泛应用于机器学习领域,支持大规模数据的模型训练和预测分析。 流式处理:针对实时数据处理需求,流式处理技术(如Apache Kafka、Apache Flink)可以实时。

    使用WADL文件的工具(高分项目).zip

    Java SSM项目是一种使用Java语言和SSM框架(Spring + Spring MVC + MyBatis)开发的Web应用程序。SSM是一种常用的Java开发框架组合,它结合了Spring框架、Spring MVC框架和MyBatis框架的优点,能够快速构建可靠、高效的企业级应用。 1. Spring框架:Spring是一个轻量级的Java开发框架,提供了丰富的功能和模块,用于开发企业级应用。它包括IoC(Inverse of Control,控制反转)容器、AOP(Aspect-Oriented Programming,面向切面编程)等特性,可以简化开发过程、提高代码的可维护性和可测试性。 2. Spring MVC框架:Spring MVC是基于Spring框架的Web框架,用于开发Web应用程序。它采用MVC(Model-View-Controller,模型-视图-控制器)的架构模式,将应用程序分为模型层、视图层和控制器层,提供了处理请求、渲染视图和管理流程的功能。 3. MyBatis框架:MyBatis是一个持久层框架,用于与数据库进行交互。它提供了一种将数据库操作与Java对象映射起来的方式,避免了手动编写繁琐的SQL语句,并提供了事务管理和缓存等功能,简化了数据库访问的过程

    库提供工具,用于检测N +1查询并计算使用Spring和Hibernate生成的查询(高分毕设).zip

    Java SSM项目是一种使用Java语言和SSM框架(Spring + Spring MVC + MyBatis)开发的Web应用程序。SSM是一种常用的Java开发框架组合,它结合了Spring框架、Spring MVC框架和MyBatis框架的优点,能够快速构建可靠、高效的企业级应用。 1. Spring框架:Spring是一个轻量级的Java开发框架,提供了丰富的功能和模块,用于开发企业级应用。它包括IoC(Inverse of Control,控制反转)容器、AOP(Aspect-Oriented Programming,面向切面编程)等特性,可以简化开发过程、提高代码的可维护性和可测试性。 2. Spring MVC框架:Spring MVC是基于Spring框架的Web框架,用于开发Web应用程序。它采用MVC(Model-View-Controller,模型-视图-控制器)的架构模式,将应用程序分为模型层、视图层和控制器层,提供了处理请求、渲染视图和管理流程的功能。 3. MyBatis框架:MyBatis是一个持久层框架,用于与数据库进行交互。它提供了一种将数据库操作与Java对象映射起来的方式,避免了手动编写繁琐的SQL语句,并提供了事务管理和缓存等功能,简化了数据库访问的过程

    node-v12.16.0-x86.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    安全实践-工业互联网安全实践与趋势分析dr.pptx

    安全实践-工业互联网安全实践与趋势分析dr.pptx

    人工智能技术的演进与应用

    人工智能(AI)的演进与应用是一个跨越数十年的历程,它不仅改变了我们的技术景观,也深刻影响了我们的日常生活。PPT详细介绍了AI的历史与演变、AI技术的应用现状、AI伦理、安全与社会责任、AI的未来发展趋势、AI未来发展对人们生活的各种影响。 探索AI的历史渊源,审视其当前应用领域的现状,思考AI伦理、安全与社会责任等重要议题,以及展望AI的未来发展趋势。最后,我们将共同探讨AI与人类共生的未来可能性。AI与人类将共生共创美好未来 AI的训练模式与技术进步,推动了AI的快速发展和应用。 AI技术的应用现状广泛而深入,涵盖了医疗健康、教育、交通与城市规划以及创意产业等多个领域。

    036ssm-jsp-mysql二手手机回收平台系统.zip(可运行源码+数据库文件+文档)

    L文主要是对二手手机回收平台系统进行了介绍,包括研究的现状,还有涉及的开发背景,然后还对系统的设计目标进行了论述,还有系统的需求,以及整个的设计方案,对系统的设计以及实现,也都论述的比较细致,最后对二手手机回收平台系统进行了一些具体测试。 本文以Java为开发技术,实现了一个二手手机回收平台系统。二手手机回收平台系统的主要使用者分为管理员;个人中心、用户管理、手机品牌管理、手机商城管理、手机回收管理、手机估价管理、系统管理、订单管理,前台首页;首页、手机商城、新闻资讯、我的、跳转到后台、购物车,用户;个人中心、手机回收管理、手机估价管理、我的收藏管理、订单管理等功能。通过这些功能模块的设计,基本上实现了整个二手手机回收平台系统的过程。 具体在系统设计上,采用了B/S的结构,同时,也使用Java技术在动态页面上进行了设计,后台上采用Mysql数据库,是一个非常优秀的二手手机回收平台系统。 关键词 :二手手机回收平台系统;Java技术;Mysql数据库;B/S结构

    小程序-63-微信小程序校园失物招领--LW-源码.zip

    提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

    【微信小程序毕业设计】高校校园交友系统开发项目(源码+演示视频+说明).rar

    【微信小程序毕业设计】高校校园交友系统开发项目(源码+演示视频+说明).rar 【项目技术】 微信小程序开发工具+java后端+mysql 【演示视频-编号:262】 https://pan.quark.cn/s/cb634e7c02b5 【实现功能】 个人中心管理,用户信息管理,兴趣爱好管理,公告类型管理,轮播图管理,公告信息管理等

    027ssm-jsp-mysql弹幕视频网站.zip(可运行源码+数据库文件+文档)

    弹幕视频网站是以实际运用为开发背景,运用软件工程开发方法,采用jsp技术构建的一个管理系统。整个开发过程首先对软件系统进行需求分析,得出系统的主要功能。接着对系统进行总体设计和详细设计。总体设计主要包括系统总体结构设计、系统数据结构设计、系统功能设计和系统安全设计等;详细设计主要包括模块实现的关键代码,系统数据库访问和主要功能模块的具体实现等。最后对系统进行功能测试,并对测试结果进行分析总结,及时改进系统中存在的不足,为以后的系统维护提供了方便,也为今后开发类似系统提供了借鉴和帮助。 本弹幕视频网站采用的数据库是Mysql,使用JSP技术开发。在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。 关键词:弹幕视频网站,JSP技术,Mysql数据库

    基于java的-117-jspm基于Java的学生综合测评管理系统--LW-源码.zip

    提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

    小程序-72-学生购电小程序-源码.zip

    提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

    大模型时代 最大化CPU价值的优化策略-何普江.pdf

    大模型时代 最大化CPU价值的优化策略-何普江

    node-v16.9.1-linux-armv7l.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    【前端素材】大数据-智慧物流.zip

    大数据技术指的是用于处理和分析大规模数据集的技术和工具。以下是一些常见的大数据技术和工具: Hadoop:Apache Hadoop是一个用于分布式存储和处理大规模数据的开源框架。它包括Hadoop Distributed File System(HDFS)用于数据存储和MapReduce用于数据处理。 Spark:Apache Spark是一个快速、通用的集群计算系统,提供了比MapReduce更快的数据处理能力。它支持内存计算和更多复杂的数据处理流程。 NoSQL数据库:NoSQL数据库(如MongoDB、Cassandra等)则更适用于处理这类数据。 数据仓库:数据仓库是一个用于集成和分析大规模数据的存储系统,一些知名的数据仓库包括Snowflake、Amazon Redshift等。 数据湖:数据湖是一个存储结构化和非结构化数据的存储池,用于支持数据分析和机器学习应用。 机器学习:大数据技术也广泛应用于机器学习领域,支持大规模数据的模型训练和预测分析。 流式处理:针对实时数据处理需求,流式处理技术(如Apache Kafka、Apache Flink)可以实时。

    node-v16.11.0-linux-armv7l.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    【前端素材】大数据-北京市行政执法信息服务平台.zip

    大数据技术指的是用于处理和分析大规模数据集的技术和工具。以下是一些常见的大数据技术和工具: Hadoop:Apache Hadoop是一个用于分布式存储和处理大规模数据的开源框架。它包括Hadoop Distributed File System(HDFS)用于数据存储和MapReduce用于数据处理。 Spark:Apache Spark是一个快速、通用的集群计算系统,提供了比MapReduce更快的数据处理能力。它支持内存计算和更多复杂的数据处理流程。 NoSQL数据库:NoSQL数据库(如MongoDB、Cassandra等)则更适用于处理这类数据。 数据仓库:数据仓库是一个用于集成和分析大规模数据的存储系统,一些知名的数据仓库包括Snowflake、Amazon Redshift等。 数据湖:数据湖是一个存储结构化和非结构化数据的存储池,用于支持数据分析和机器学习应用。 机器学习:大数据技术也广泛应用于机器学习领域,支持大规模数据的模型训练和预测分析。 流式处理:针对实时数据处理需求,流式处理技术(如Apache Kafka、Apache Flink)可以实时。

    【前端素材】大数据-设备监测大屏.zip

    大数据技术指的是用于处理和分析大规模数据集的技术和工具。以下是一些常见的大数据技术和工具: Hadoop:Apache Hadoop是一个用于分布式存储和处理大规模数据的开源框架。它包括Hadoop Distributed File System(HDFS)用于数据存储和MapReduce用于数据处理。 Spark:Apache Spark是一个快速、通用的集群计算系统,提供了比MapReduce更快的数据处理能力。它支持内存计算和更多复杂的数据处理流程。 NoSQL数据库:NoSQL数据库(如MongoDB、Cassandra等)则更适用于处理这类数据。 数据仓库:数据仓库是一个用于集成和分析大规模数据的存储系统,一些知名的数据仓库包括Snowflake、Amazon Redshift等。 数据湖:数据湖是一个存储结构化和非结构化数据的存储池,用于支持数据分析和机器学习应用。 机器学习:大数据技术也广泛应用于机器学习领域,支持大规模数据的模型训练和预测分析。 流式处理:针对实时数据处理需求,流式处理技术(如Apache Kafka、Apache Flink)可以实时。

Global site tag (gtag.js) - Google Analytics