怎樣用DHTML與XML制作Ajax幻燈片_AJAX教程
推薦:怎樣處理書(shū)簽和后退按鈕本文將展示一個(gè)開(kāi)源JavaScript庫(kù),該腳本庫(kù)給AJAX應(yīng)用程序帶來(lái)了書(shū)簽和后退按鈕支持。在學(xué)習(xí)完這個(gè)教程后,開(kāi)發(fā)人員將能夠獲得對(duì)一個(gè)AJAX問(wèn)題的解決方案(甚至連Google Maps和Gmail現(xiàn)在都不提供該解決方案):一個(gè)強(qiáng)大的、可用的書(shū)簽和后退前進(jìn)功能,其操作行
Ajax 幻燈片放映
個(gè)人圖像管理應(yīng)用程序(如 Macintosh® 上的 Apple® iPhoto®)使得幻燈片瀏覽廣為人知。在幻燈片瀏覽中,圖像按照時(shí)間順序先后淡入淡出。此外,圖片還通過(guò)所謂的 “Ken Burns Effect” 進(jìn)行移動(dòng)和縮放。
在該例中,我讓瀏覽器從服務(wù)器上下載一個(gè)圖像列表。然后使用動(dòng)態(tài) HTML(DHTML)把圖片列表組成一個(gè)幻燈片。我使用隨機(jī)的緩慢移動(dòng)、縮放和漸變來(lái)改變圖片,實(shí)現(xiàn)了令人滿意的 Ken Burns Effect 版本,而不需要下載 Macromedia® Flash 或其他重量級(jí)的動(dòng)畫(huà)工具。
體系結(jié)構(gòu)
要了解 Ajax 有何不同,首先必須理解當(dāng)前的 Web 編程模型�?蛻魴C(jī)和服務(wù)器之間的簡(jiǎn)單交互如 圖 1 所示。
圖 1. 客戶機(jī)-服務(wù)器交互的 Web V1.0 模型
Web 瀏覽器或者客戶機(jī) 向 Web 服務(wù)器發(fā)出 GET 或 POST 請(qǐng)求。服務(wù)器格式化 HTML 響應(yīng)。客戶機(jī)解析 HTML 并顯示給用戶。如果用戶單擊其他鏈接和按鈕,就向服務(wù)器發(fā)出另一個(gè)請(qǐng)求,用服務(wù)器返回的新頁(yè)面替換當(dāng)前頁(yè)面。
新模型具有更多的異步特色,如 圖 2 所示。
圖 2. 客戶機(jī)-服務(wù)器交互的 Ajax 模型
在新的模型中,和以前一樣,服務(wù)器也返回 HTML 頁(yè)面。但是這個(gè)頁(yè)面中有一些 JavaScript 代碼。在需要的時(shí)候,這些代碼向服務(wù)器請(qǐng)求更多信息。這些請(qǐng)求可以是簡(jiǎn)單的 GET 請(qǐng)求(Representational State Transfer (REST) 服務(wù))或者 POST 請(qǐng)求(SOAP)。
然后,JavaScript 代碼解析響應(yīng)(通常用 XML 編碼)并動(dòng)態(tài)更新頁(yè)面以反映新的數(shù)據(jù)。除了 XML 外,還返回 JavaScript Serialized Object Notation(JSON)格式編碼的數(shù)據(jù)。瀏覽器很容易理解這類(lèi)數(shù)據(jù),但其他類(lèi)型的客戶機(jī)則不行。返回 XML 的意義在于瀏覽器之外的其他客戶機(jī)也能解釋數(shù)據(jù)。選擇由您來(lái)決定并依賴(lài)于具體的應(yīng)用程序。
開(kāi)發(fā) Ajax 幻燈片的第一步是結(jié)合 REST 數(shù)據(jù)服務(wù)。該例中使用 PHP 頁(yè)面返回所有可用的幻燈片圖像及其大�。▽捄透撸K袌D像都放在 images 目錄中。文件名格式為 name_width_height.jpg,比如 oso1_768_700.jpg 表示該文件是我的狗 Oso 的照片,寬 768 像素,高 700 像素。我堅(jiān)持使用這種命名方式,因?yàn)檫@樣就很容易確定圖片的寬和高,而不用費(fèi)力去打開(kāi) Adobe® PhotoShop® 或 Macromedia Fireworks。
我使用 清單 1 所示的 PHP 服務(wù)器代碼來(lái)提供圖片列表。
清單 1. slides.php 服務(wù)器頁(yè)面
<?php
header( "Content-type: text/xml" );
?>
<slides>
<?php
if (handle = opendir('images')) {
while (false !== (file = readdir(handle)))
{
if ( preg_match( "/[.]jpg/", file ) ) {
preg_match( "/_(\d+)_(\d+)[.]/", file, found );
?>
<slide src="images/<?php echo file; ?>"
width="<?php echo found[1]; ?>"
height="<?php echo found[2]; ?>" /><?php echo( "\n" ); ?>
<?php
}
}
closedir(handle);
}
?>
</slides>
代碼很簡(jiǎn)單。首先將內(nèi)容類(lèi)型設(shè)置為 XML。讓瀏覽器將該文檔識(shí)別為 XML 并為其創(chuàng)建文檔對(duì)象模型(DOM)至關(guān)重要。代碼從 <slides> 標(biāo)記開(kāi)始,然后讀取圖片目錄并為遇到的每個(gè)圖片創(chuàng)建 <slide> 標(biāo)記。最后腳本結(jié)束 <slides> 標(biāo)記。
如果用 Mozilla® Firefox® 瀏覽器打開(kāi)(在我的機(jī)器上)本地主機(jī) kenburns 目錄中的該頁(yè)面,就會(huì)看到 圖 3 所示的結(jié)果。
圖 3. slides.php 服務(wù)器腳本的輸出
一共三幅圖片:我的女兒和我的兩條狗。當(dāng)然在這里可以增加任何需要的細(xì)節(jié)或者多媒體,但我盡量保持例子的簡(jiǎn)單性。
檢索 XML
下一步就是編寫(xiě)一個(gè) HTML 頁(yè)面(如 清單 2 所示)從服務(wù)器讀取數(shù)據(jù)并檢驗(yàn)瀏覽器和服務(wù)器之間使用的 Ajax 連接。這段 HTML 代碼包含內(nèi)嵌的 JavaScript 代碼,檢索 XML 并打開(kāi)一個(gè)警告窗口顯示服務(wù)器返回的文本。
清單 2. 簡(jiǎn)單的 Ajax 讀取數(shù)據(jù)頁(yè)面
<html>
<body>
<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>
</body>
</html>
代碼從指定的 URL 獲取 XML 內(nèi)容,然后 loadXMLDoc 函數(shù)啟動(dòng) Ajax 請(qǐng)求。檢索頁(yè)面的請(qǐng)求異步發(fā)出并返回結(jié)果。請(qǐng)求完成后,對(duì)結(jié)果調(diào)用 processReqChange 函數(shù)。這里用 processReqChange 函數(shù)在警告窗口中顯示 responseText 的函數(shù)值。在我的 Firefox 瀏覽器中調(diào)用該頁(yè)面的結(jié)果如 圖 4 所示。
圖 4. 在警告窗口中顯示的 XML
開(kāi)局不錯(cuò)。毫無(wú)疑問(wèn),我們從服務(wù)器取回了 XML 數(shù)據(jù)。但是有必要指出幾點(diǎn)。首先要注意 URL 使用了絕對(duì)路徑,包括域名等等。對(duì)于 Ajax 來(lái)說(shuō)這是唯一有效的 URL 格式。編寫(xiě) Ajax JavaScript 代碼的服務(wù)器代碼總是創(chuàng)建有效的、完整格式的 URL。
這里不那么明顯的另一點(diǎn)是 Ajax 的安全保護(hù)措施。JavaScript 代碼不能請(qǐng)求任意的 URL。URL 的域名必須和該頁(yè)面相同。在這里域名就是 localhost。但必須指出不能呈現(xiàn) www.mycompany.com 的 HTML 但卻讓腳本從 data.mycompany.com 檢索數(shù)據(jù)。域必須完全相同,包括子域名。
有趣的另一點(diǎn)是 loadXMLDoc 中的代碼,似乎是費(fèi)力地創(chuàng)建一個(gè)請(qǐng)求對(duì)象。為何這么麻煩呢?Internet Explorer 7 的預(yù)覽版沒(méi)有內(nèi)建 XMLHTTPRequest 對(duì)象類(lèi)型。因此必須使用 Microsoft ActiveX® 控件。
最后在 processReqChange 函數(shù)中,可以看到我在查看 readyState 是否等于 4,status 是否設(shè)為 200。readyState 的值 4 表示事務(wù)已經(jīng)完成。status 的值 200 表示頁(yè)面是有效的。如果沒(méi)有找到頁(yè)面,就可能會(huì)得到錯(cuò)誤消息 404,就像您在瀏覽器中看到的那樣。這里沒(méi)有處理異常情況,因?yàn)檫@僅僅是一個(gè)例子,不過(guò)發(fā)布的 Ajax 代碼應(yīng)該處理返回錯(cuò)誤的請(qǐng)求。
動(dòng)態(tài)創(chuàng)建 HTML
在說(shuō)明如何創(chuàng)建幻燈片放映之前,首先擴(kuò)展現(xiàn)在的例子,讓 processReqChange 函數(shù)用服務(wù)器返回的 XML 請(qǐng)求結(jié)果創(chuàng)建一個(gè) HTML 表格。這樣做可以驗(yàn)證兩件事:能夠讀取 XML 并能夠根據(jù) XML 動(dòng)態(tài)創(chuàng)建 HTML。
清單 3 顯示了修改后的代碼,它將從返回的 XML 創(chuàng)建表格。
清單 3. 改進(jìn)的測(cè)試頁(yè)面
<html>
<body>
<table>
<tbody id="dataTable">
</tbody>
</table>
<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>
</body>
</html>
在瀏覽器中打開(kāi)該頁(yè)面將顯示 圖 5 所示的結(jié)果。
圖 5. 修改后的測(cè)試頁(yè)
修改后的 processReqChange 代碼現(xiàn)在查看 responseXML 對(duì)象而不是 responseText 文本。此外,它還使用 getElementsByTagName 訪問(wèn)所有的 <slide> 標(biāo)記。然后解析 src、width 和 height 屬性,并使用 document 對(duì)象的 createElement 方法創(chuàng)建行和單元格來(lái)存放數(shù)據(jù)。該方法使用的 createElement 遠(yuǎn)比過(guò)去的老方法健壯,原來(lái)要建立一個(gè)包含表格內(nèi)容的 HTML 字符串,然后用 innerHTML 將數(shù)據(jù)添加到已有的元素中。
創(chuàng)建幻燈片放映
現(xiàn)在已經(jīng)有了能夠確定幻燈片中圖像的 Web 服務(wù),還需要顯示這些幻燈片并執(zhí)行 Ken-Burns-Effect 動(dòng)畫(huà)的客戶端代碼。為此必須將執(zhí)行三種基本功能的 JavaScript 對(duì)象結(jié)合起來(lái):
1、封裝圖像
2、提供基本的動(dòng)畫(huà)引擎
3、實(shí)現(xiàn)特效(比如移動(dòng)、縮放和漸變)
封裝圖像
首先從圖像容器開(kāi)始,我創(chuàng)建一個(gè)類(lèi) 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';
}
幻燈片中每幅圖片都有一個(gè)對(duì)應(yīng)的 ImageInfo 對(duì)象。該對(duì)象封裝了圖像信息:src、width 和 height。該對(duì)象還包含對(duì)在文檔中顯示圖像的 HTML <img> 標(biāo)記的引用,以及移動(dòng)圖像、設(shè)置透明度等的 helper 方法。注意,在 Firefox 和其他基于 Gecko® 的瀏覽器中,MozOpacity 樣式用于設(shè)置不透明性。Internet Explorer 中則使用過(guò)濾器效果。
創(chuàng)建簡(jiǎn)單的動(dòng)畫(huà)引擎
下面我們來(lái)編寫(xiě)一個(gè)簡(jiǎn)單的動(dòng)畫(huà)引擎。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 包含兩個(gè)類(lèi):Animation 和 AnimationManager。AnimationManager 類(lèi)控制定時(shí)器并向其 Animation 對(duì)象列表中的第一項(xiàng)發(fā)送動(dòng)畫(huà)消息。當(dāng) Animation 對(duì)象報(bào)告自己已經(jīng)完成的時(shí)候,該類(lèi)就轉(zhuǎn)向下一項(xiàng),依此類(lèi)推。
Animation 在一定的時(shí)間(按秒數(shù)指定)內(nèi)對(duì)特定圖片應(yīng)用一系列特效。Animation 對(duì)象需要計(jì)算完成度消息并將其發(fā)送給每種特效的 apply 方法。特效然后根據(jù)這個(gè)百分比計(jì)算應(yīng)該如何處理圖像。比如,移動(dòng)特效知道起點(diǎn)和終點(diǎn),可以根據(jù)這個(gè)百分比計(jì)算應(yīng)該將圖像放到何處。如果是 50%,圖像應(yīng)該移到起點(diǎn)和終點(diǎn)之間。
作為我工作的一部分,同時(shí)也為了撰寫(xiě)本文,我考察了大量的 JavaScript 動(dòng)畫(huà)代碼。JavaScript 動(dòng)畫(huà)經(jīng)常因?yàn)椴环(wěn)定而受到指責(zé),因?yàn)樗?JavaScript 動(dòng)畫(huà)都使用 window.setInterval 方法來(lái)完成。這是一個(gè)定時(shí)器方法,同時(shí)指定了回調(diào)時(shí)間間隔和回調(diào)函數(shù)。Web 上的大部分代碼都要求每次調(diào)用該函數(shù)時(shí)動(dòng)畫(huà)移動(dòng)一步。但這并不能真正工作,因?yàn)楦嬖V瀏覽器的間隔僅僅是一個(gè)建議。如果規(guī)定 20 毫秒,但實(shí)際上可能第一次在 25 毫秒時(shí)調(diào)用,下一次卻要等到一秒鐘以后。瀏覽器是單線程的,因此不能依賴(lài)于定時(shí)器。
解決方案是使用 Date 對(duì)象的 valueOf 方法確定動(dòng)畫(huà)開(kāi)始了多長(zhǎng)時(shí)間。這個(gè)時(shí)間差是用毫秒計(jì)的,用于確定當(dāng) setInterval 定時(shí)器離開(kāi)時(shí)動(dòng)畫(huà)應(yīng)該執(zhí)行百分之多少。該方法可以提供規(guī)定的任意長(zhǎng)時(shí)間的平滑動(dòng)畫(huà)。
執(zhí)行特效
三個(gè)核心類(lèi)的最后一個(gè)是 Ken Burns Effects。這些特效通過(guò) Animation 對(duì)象應(yīng)用于圖像,如 清單 6 所示。
清單 6. KenBurnsAnimations.js
function KenBurnsFader( img, windowSize )
{
this.img = img;
this.windowSize = windowSize;
}
KenBurnsFader.prototype.apply = function( percent )
{
var opacity = 100;
if ( percent <= this.windowSize )
opacity = ( percent / this.windowSize ) * 100;
else 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 );
}
這三個(gè)類(lèi)分別處理應(yīng)用于圖像的不同特效。KenBurnsFader 類(lèi)使用不透明度處理圖像的淡入淡出。KenBurnsZoomer 類(lèi)處理圖像的縮放,從最初的大小到最終的大小。KenBurnsMover 類(lèi)處理圖像的移動(dòng),從起點(diǎn)到終點(diǎn)(用圖像的百分比指定)。
經(jīng)過(guò)一些試驗(yàn)后,我發(fā)現(xiàn)最吸引人的移動(dòng)特效是相對(duì)于窗口中心從一個(gè)角移動(dòng)到另一個(gè)角。KenBurnsMover 類(lèi)的 apply 方法包含一些復(fù)雜的數(shù)學(xué)運(yùn)算,不僅相對(duì)于包含圖像的 <div> 標(biāo)記的中心來(lái)移動(dòng),還要計(jì)算圖像和 <div> 標(biāo)記的相對(duì)大小,這樣在小窗口中移動(dòng)的距離就小,在大窗口中移動(dòng)的距離就大。放大倍數(shù)根據(jù)窗口的高度確定。
實(shí)現(xiàn)非 Ajax DHTML
有了這些基礎(chǔ)類(lèi)之后,就可以實(shí)現(xiàn)幻燈片的非 Ajax DHTML 版本來(lái)進(jìn)行測(cè)試了,如 清單 7 所示。
清單 7. 非 Ajax 幻燈片放映
<html>
<head>
<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>
</head>
<body>
<div style="position:relative;width:100%;height:100%;overflow:hidden;"
id="imgContainer">
</div>
<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>
</body>
</html>
不用電影是很難說(shuō)明上述代碼在瀏覽器中的運(yùn)行結(jié)果的。因此我抓了一個(gè)快照,如 圖 6 所示。
圖 6. 幻燈片放映的快照
該頁(yè)面首先通過(guò) <script> 標(biāo)記的 src 屬性引入基類(lèi)。安裝這些類(lèi)之后,增加兩個(gè)函數(shù)將整個(gè)機(jī)制組織到一起:load_slides 和 start_slides。load_slides 函數(shù)接收一個(gè)數(shù)組,包括圖像的 src、width 和 height,然后創(chuàng)建 <image> 標(biāo)記和動(dòng)畫(huà)。start_slides 函數(shù)從第一項(xiàng)開(kāi)始啟動(dòng)幻燈片放映。
附加在動(dòng)畫(huà)管理器上的另一個(gè)方法 on_finished 在動(dòng)畫(huà)完成時(shí)調(diào)用。我使用該通知移動(dòng)到下一張幻燈片,如果已經(jīng)完成所有幻燈片的動(dòng)畫(huà),則回到列表中的第一張。
再回到 load_slides,要注意它引用了一個(gè)名為 g_directions 的數(shù)組。該數(shù)組包含一些隨機(jī)范圍,幻燈片加載程序用它來(lái)規(guī)定圖片移動(dòng)的起點(diǎn)和終點(diǎn)。最理想的效果是從一個(gè)角到另一個(gè)角。從注釋中可以看到,這些值規(guī)定幻燈片的移動(dòng)范圍為東北、東南、西北和西南的任意組合。最后的 <script> 標(biāo)記定義了一個(gè)圖像數(shù)組,然后使用 load_slides 和 start_slides 函數(shù)啟動(dòng)幻燈片放映。
分享:打造Ajax簡(jiǎn)單相冊(cè)演示地址 源文件下載 AJAX(Asynchronous JavaScript And XML)是一種運(yùn)用JavaScript和可擴(kuò)展標(biāo)記語(yǔ)言(XML),在網(wǎng)絡(luò)瀏覽器和服務(wù)器之間傳送或接受數(shù)據(jù)的技術(shù)。主要應(yīng)用于Ria(Rich internet applications)的開(kāi)發(fā)上。 xml問(wèn)題終于在今天還是解決了。最后在FireFo
- Ajax中瀏覽器的緩存問(wèn)題解決方法
- AJAX和WebService實(shí)現(xiàn)省市縣三級(jí)聯(lián)動(dòng)具體代碼
- ajax 登錄功能簡(jiǎn)單實(shí)現(xiàn)(未連接數(shù)據(jù)庫(kù))
- AJAX和WebService實(shí)現(xiàn)郵箱驗(yàn)證(無(wú)刷新驗(yàn)證郵件地址是否合法)
- AJAX和三層架構(gòu)實(shí)現(xiàn)分頁(yè)功能具體思路及代碼
- 使用AJAX返回WebService里的集合具體實(shí)現(xiàn)
- AJAX獲取服務(wù)器當(dāng)前時(shí)間及時(shí)間格式輸出處理
- ajax傳遞多個(gè)參數(shù)具體實(shí)現(xiàn)
- ajax傳遞一個(gè)參數(shù)具體實(shí)現(xiàn)
- 滑輪滾動(dòng)到頁(yè)面底部ajax加載數(shù)據(jù)配合jsonp實(shí)現(xiàn)探討
- jQery ajax——load()方法示例介紹
- jQuery+Ajax實(shí)現(xiàn)表格數(shù)據(jù)不同列標(biāo)題排序(為表格注入活力)
AJAX教程Rss訂閱編程教程搜索
AJAX教程推薦
- AJAX教程之AJAX的jQuery實(shí)現(xiàn)入門(mén)(一)
- ajax傳遞一個(gè)參數(shù)具體實(shí)現(xiàn)
- 談在AJAX中GET回的ResponseText中文亂碼的最簡(jiǎn)解決辦法
- AJAX和WebService實(shí)現(xiàn)郵箱驗(yàn)證(無(wú)刷新驗(yàn)證郵件地址是否合法)
- 淺談Ajax的缺點(diǎn)
- ajax中文亂碼問(wèn)題解決方案
- 解析AJAX進(jìn)度條
- ajax跨域訪問(wèn)代理文件下載(asp、php、asp.net)
- XMLHTTP組件相關(guān)技術(shù)資料
- Ajax與JSON的一些學(xué)習(xí)總結(jié)
猜你也喜歡看這些
- JQuery的ajax的用法在asp中使用$.ajax()實(shí)現(xiàn)
- 如何根據(jù)郵編自動(dòng)完成地址信息
- Ajax好在什么地方?
- JQuery+ajax實(shí)現(xiàn)批量上傳圖片(自寫(xiě))
- 實(shí)現(xiàn)基于Ajax的無(wú)限級(jí)菜單
- 雙劍合璧 Ajax和RSS做個(gè)人門(mén)戶網(wǎng)站
- 利用Ajax實(shí)現(xiàn)在腳本里傳值實(shí)例介紹
- 實(shí)例解析AJAX開(kāi)發(fā)簡(jiǎn)略
- 揭秘Ajax 及其入門(mén)基礎(chǔ)(續(xù))
- 用AJAX編寫(xiě)用戶注冊(cè)實(shí)例及技術(shù)小結(jié)
- 相關(guān)鏈接:
- 教程說(shuō)明:
AJAX教程-怎樣用DHTML與XML制作Ajax幻燈片
。