譯自:[http://net.tutsplus.com/tutorials/html-css-techniques/how-to-create-presentation-slides-with-html-and-css-2/](http://net.tutsplus.com/tutorials/html-css-techniques/how-to-create-presentation-slides-with-html-and-css-2/)
[](http://net.tutsplus.com/tutorials/html-css-techniques/how-to-create-presentation-slides-with-html-and-css-2/)譯者:蔣宇捷(轉載請標明出處-http://blog.csdn.net/hfahe)
[下載源文件](https://github.com/JeffreyWay/Presentation-for-WordCamp)[示例](http://namepk.sinaapp.com/demo/slides/)(用向左向右鍵翻頁,Ctrl加+或者-鍵放大縮小)
? 我曾經嘗試過許多種軟件來創建幻燈片,但是為什么不使用我們已經熟悉的工具,而是去學習另外一種程序?我們可以輕松的使用HTML和CSS來創建漂亮的幻燈片。我下面將向你展示實現的方法。

**0-**目錄結構
? 在我們開始前,讓我們來創建相當簡單的目錄結構。我們將需要以下文件:
·index.html
·css/style.css
·js/scripts.js
·img/
·slides/
? 一個簡單的基本模版。Slides目錄目前為空,我們稍后將填充它。
**1-**編寫**HTML**
? 讓我們開始為幻燈片頁面創建基本的HTML頁面。將下面的代碼粘貼到index.html文件里。
~~~
<!DOCTYPE HTML><html><head> <meta charset="utf-8"> <link href="style.css" rel="stylesheet" /> <title>My Great Presentation</title></head><body> <div class="wrap"> <div id="slides"> <!-- load in slides --> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script></body></html>
~~~
? 上面的代碼需要一些精簡,我們要感謝HTML5。例如script和link標簽不再有type屬性,更簡潔的DOCTYPE,簡單有趣的meta charset標簽。
**2-**幻燈片
*Load()**方法是一個從服務器載入數據的**AJAX**方法,并在選定的元素中插入返回的**HTML**代碼。***
? ?現在你可能覺得奇怪我們如何處理每一條幻燈片。我們這里有多種選擇方式。我們可以用div包裹每一張幻燈片,并且在#slides容器里放置一大段的HTML代碼。我的直覺告訴我這種方式會使得每一個獨立的幻燈片的編輯過程更為耗時,因為我們隨后必須要從幻燈片所有的標記里查找我們所需的。在這個教程里我們采用替代方案,我選擇將每一個幻燈片放在單獨的.html文件里。我們稍候可以使用jQuery的load()方法來加載每一張幻燈片,并將它們添加到容器里。
創建一系列有編號的HTML文件,并且將它們放在slides目錄里,就像如下所示:
o???slides/
o???0.html
o???1.html
o???2.html
o???3.html
o???4.html
? 在每一個這樣的文件中,我們將為我們所需的幻燈片插入HTML標記。作為示例,讓我們創建一個“關于我們”幻燈片。
1.html
~~~
<div> <h3> About Me</h3> <ul> <li> Nettuts+ Editor</li> <li> Envato Marketplaces Manager</li> <li>Wicked WordPress Themes</li> <li>Theme Tumblr Like a Pro</li> </ul></div>?
~~~
? 可以使用任何你想要的內容來編寫這個文件。
**3-**加載幻燈片
? 在關注幻燈片的樣式之前,我們需要使用jQuery將這些幻燈片載入到文檔里。但是比起創建大量的變量和方法,我們將把所有的內容存儲到一個名為Slides的變量里。
~~~
var Slides = {};?
~~~
? 然后,載入這些幻燈片到文檔的過程將被存儲到一個名為loadContent()的方法里。讓我們開始創建編寫代碼。
~~~
var Slides = { loadContent : function() { }}?
~~~
? 要加載slides目錄下的所有幻燈片,我們首先必須要知道要有多少個幻燈片。但是Javascript并沒有訪問文件系統的權限,所以我們在初始化對象前必須要傳遞進幻燈片的數量。
? 以此為前提,讓我們創建init()方法來作為控制器。這個方法將會接受一個參數來制定幻燈片的總張數。這將會分配給Slides對象的一個屬性。
~~~
var Slides = { totalSlides : '', init : function( totalSlides ) { // If nothing was passed to this function, we can't continue. if ( !totalSlides ) throw new Error('Please pass the total number of slides to the init method'); Slides.totalSlides = totalSlides; // Load the slides Slides.loadContent(); }, loadContent : function() { }}?
? 這非常好,但是除非我們調用init()方法,沒有代碼將會被執行。
var Slides = { totalSlides : '', init : function( totalSlides ) { // If nothing was passed to this function, we can't continue. if ( !totalSlides ) throw new Error("Please pass the total number of slides to the init method"); Slides.totalSlides = totalSlides; // Load the slides Slides.loadContent(); }, loadContent : function() { }}// All right; let's do this. We'll assume that we've created 6 slides, total.Slides.init( 6 );?
~~~
**4-**三種加載幻燈片的方法
? 讓我們開始加載幻燈片的第一步,我們稍后將逐步改進代碼。
~~~
loadContent : function() { for ( var i = 0; i < Slides.totalSlides; i++ ) { $('<div id="#slide-' + i + '"></div>') .load('slides/' + i + '.html') .appendTo( $('#slides') ); }}?
~~~
? 在上面,我們為指定的所有幻燈片創建了一個新的div元素。每個div會有一個名為slide-n的id。在創建每個元素后,我們載入slides文件夾下存儲的幻燈片內容。一旦這些HTML片段從服務器獲得,我們將新創建的div添加到slides容器中。
**我們可以做得更好**
? 這些代碼確實能夠工作,但是我們可以做得更好。以上代碼有如下問題:
·**遍歷:**對于每個幻燈片,我們遍歷slides元素的DOM節點。這是沒有必要而且造成了浪費。同時,一旦我們在項目中一直使用slides容器節點,有理由將它存儲為我們slides對象的一個屬性。我們立即將這么來做。
·**重繪**:以上代碼將造成很多頁面重繪,這將增加頁面的加載時間。比起多次調用appendTo()方法(在我們的例子中是6次),讓我們限制重繪為一次。
**遍歷**
讓我們先修復遍歷的問題。
~~~
var Slides = { totalSlides : '', container : $( "#slides" ), init() { ... }, loadContent() { ... }}?
~~~
? 采用這種方式我們可以一次性的在slides元素中查找出文檔。
????? **如果你還對這么做的優點心存疑慮,可以把它想象成跳到一個池子中,來尋找一個硬幣。每次你調用**$('#slides')**時,**Javascript**引擎會進入變量池來一次又一次的尋找這個硬幣。但是,如果我們換成將**$('#slides')**存儲在一個變量里,**Javascript**引擎將不必用到變量池。它將會記住硬幣在哪兒。***
**重繪**
? 現在,我們開始考慮討厭的重繪問題。有兩種方法來限制頁面重繪,我們將都會進行嘗試。
**文檔片段**
? Javascript文檔片段允許我們存儲HTML塊。比起我們之前多次更改DOM樹的做法,我們只需調用appendTo()方法一次。
????? *[*這里*](http://ejohn.org/blog/dom-documentfragments/)*有文檔片段更多的相關信息。***
~~~
loadContent : function() { var frag = document.createDocumentFragment(), bit; for ( var i = 0; i < Slides.totalSlides; i++ ) { bit = $('<div id="#slide-' + i + '">'</div>') .load('slides/' + i + '.html')[0]; frag.appendChild(bit); } Slides.container.append(frag);}?
~~~
? 記住我們不再在for循環里調用appendTo()方法。取而代之的是只調用了它一次。唯一需要注意到的是在我們調用load()方法之后[0]寫法。我們用它的目的何在?
? 我們需要的是HTML元素,所以需要使用[0]或者get()方法來從jQuery方法獲得。
**隱藏容器**
? 我們第二個選擇是隱藏容器元素。當我們這么做時,不管你在這個元素里添加了多少次新的元素,都不會導致頁面重繪。這將會是你工具箱里常用的小技巧。
~~~
loadContent : function() { // Hide the container. Slides.container.hide(); for ( var i = 0; i < Slides.totalSlides; i++ ) { $(''<div id="#slide-' + i + '">'</div>') .load('slides/' + i + '.html') .appendTo(Slides.container); } // Now display the slides container again - causing exactly one reflow. Slides.container.show();}?
~~~
? 所以任意一個方法都可以改善這個問題。選擇任意一個你喜歡的。
? 如果你現在在瀏覽器查看我們的項目,假定你已經添加了一些虛擬的幻燈片到slides文件夾,你將會沿著線條看到一些內容:

? 如果我們使用Firebug或者Chrome的開發者工具查看,可以像預期一樣看到,幻燈片已經插入到slides div容器里。

**5-**讓它更美
? 我們下一步將替換樣式表。我們將同時關注美感和功能兩個方面。要讓每個幻燈片從左到右進行轉換,我們將要靈巧的處理樣式:
? 我們將開始創建畫布。
~~~
<!DOCTYPE HTML><html><head> <meta charset="utf-8"> <link href="style.css" rel="stylesheet" /> <title>My Great Presentation</title></head><body> <div class="wrap"> <div id="slides"> <!-- load in slides --> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script></body></html>?
~~~
? 我們的容器是一個類名為wrap的div。我們將要為它提供1180像素的寬度并放置在頁面中央。
~~~
.wrap { margin: auto; width: 1180px; overflow: hidden; /* because children will be floated */}?
~~~
? 然后,因為每一個幻燈片必須水平的切換,我們必須使得slides div盡可能的寬。
~~~
#slides { width: 999999px;}?
~~~
? 現在是有趣而小小可怕的部分。想象一個傳統的幻燈片,內容是不是通常水平和上下居中的?正是如此。因為我們有工程100%的控制權,所以不需要擔心瀏覽器的一致性。因為幻燈片是需要我們自己來展示的,所以我們可以自由使用自己所喜愛的瀏覽器。這種方式下,我們可以使用很多瀏覽器中并不支持的新特性,例如彈性盒子模型。
? 我們來開始指定每個幻燈片的尺寸,浮動每張幻燈片,一些逼真的空間(margins)。
~~~
#slides > div { height: 600px; width: 1180px; float: left; margin-right: 200px; text-align: center;}?
~~~

? 但是記住,文字必須垂直居中。[彈性盒子模型](http://bit.ly/eN24rj)是我們的救星。
~~~
#slides > div { height: 600px; width: 1180px; float: left; margin-right: 200px; text-align: center; /* Flexible Box Model */ display: -webkit-box; -webkit-box-align: center; -webkit-box-orient: horizontal; -webkit-box-pack: center; display: box; box-align: center; box-orient: horizontal; box-pack: center;}?
~~~

? ?然后,我們要為幻燈片添加一個漂亮的徑向漸變。說實話,CSS徑向漸變讓我非常困惑,我幾乎記不住它的格式。就這點而言,我通常為漸變創建筆記,或者使用網上一些不同的漸變生成器。
~~~
body { background-image: -webkit-gradient( radial, 50% 50%, 0, 50% 50%, 1000, from(rgba(245,245,245,1)), to(rgba(100,100,100,1)) );}?
~~~

? 同時我們在適當的位置有基本的結構。此時我鼓勵你為頭部添加樣式,也許是創建一個最小的格子,和其他你能想到的一切。
~~~
#slides h1,#slides h2,#slides h3,#slides h4,#slides h5 { color: #292929; font-family: 'League Gothic', sans-serif; letter-spacing: -5px; margin-top: 0; text-shadow: 5px 3px 0 white;}#slides > div h2 { font-size: 180px; line-height: 1em; margin: 0;}?
~~~
? 令人驚奇的是我們在調整字符間距和添加一些靈巧的字符陰影時能夠達到的效果。現在看起來好多了。


**6-**下一張幻燈片
? 下一個步驟是處理幻燈片間切換的過程。自然的,因為沒有空間來放置按鈕,我們可以監聽鍵盤上的左右鍵按下事件。我們將把這個功能存儲在slides對象一個名為keyPress的新方法。
~~~
var Slides = { ... init : function() { ... }, loadContent: function() { ... }, keyPress : function() { $(document.body).keydown(function(e) { // if left or right arrow key is pressed if ( e.keyCode === 39 || e.keyCode === 37 ) { e.preventDefault(); ( e.keyCode === 39 ) ? Slides.next() : Slides.prev(); } }); }}?
~~~
? jQuery提供了工具性的keydown方法,用于綁定需要的事件監聽。這代表傳入的回調方法將會在每個鍵按下時被執行。然而,我們只對向左和向右鍵感興趣,它們的鍵值分別是39和37。如果其中一個鍵被按下,我們首先阻止這個鍵的默認行為,然后調用next()或者prev()方法來切換幻燈片。
**下一張幻燈片**
? 現在讓我們開始編寫next()方法。當這個方法被調用時,它需要執行一些操作:
·????????更新URL里的hash值,采用這種方法,我們可以輕松的為指定的幻燈片傳送地址。
·????????將當前的幻燈片進行向左的動畫切換,并顯示下一張幻燈片。
? 但是繼續之前,我們如何知道幻燈片轉換時需要移動多少寬度?這應該是slides容器的寬度,但是我們不想把這個硬編碼到代碼里,而且也不需要。這是因為,如果稍后想要改變畫布的大小,我們還需要進入Javascript文件里并且更新尺寸大小。作為替代,讓我們動態的判斷容器的寬度和margin。
? 讓我們在slides對象里添加一個名為slideWidth的新屬性。然而,我們將不能決定幻燈片的寬度,直到它們已經通過loadContent方法插入到DOM樹中。
~~~
var Slides = { ... // New property stores the width of each slide slideWidth : '', ... init : function( totalSlides ) { ... }, loadContent : function() { ... }, // Determine the width of the slide... setSlideWidth : function() { var each = Slides.container.children( 'div' ); Slides.slideWidth = each.width() + ( parseInt( each.css('margin-right'), 10 ) ); }}?
~~~
? 哎呀,這一行看起來有一點可怕!
~~~
Slides.slideWidth = each.width() + ( parseInt( each.css('margin-right'), 10 ) );?
~~~
? 但是不要擔心,這相當的簡單。我們將要改變slides.slideWidth屬性并讓它等于幻燈片的寬度加上右邊的margin。因為獲取幻燈片的margin-right屬性會返回像素值,我們需要將它們切分開,并使用parseInt方法獲得數值。
? 為了讓計算的需求更清晰,假定右側的margin值等于200像素。
~~~
console.log ( typeof each.css('margin-right').split('px')[0] ); // value is 200. Typeof is still string, not integer.
~~~
? 同時通過這種方式,我們將要動態的決定幻燈片的寬度。回到next()方法,我們需要一直跟蹤幻燈片的位置。這樣當幻燈片從第四張換到第五張時,我們可以清楚的知道需要轉換多少寬度。我們將把這個值存儲在一個新的屬性translateAmount中。
~~~
translateAmount : '',next : function() { Slides.translateAmount -= Slides.slideWidth;}?
~~~
? 讓我們分開來解釋。當第一次按下向右鍵,我們設置translateAmount屬性等于slideWidth,在我們的例子中是1380像素。如果我們再次按下向右鍵,這個值將會更改為2760像素。
**更新Hash值**
? 使用這個next方法,我們還可以更改url里的hash值,例如先是形如example.com/index.html#slide-1,然后更新為example.com/index.html#slide-2。要這樣做的話,我們必須要跟蹤讀者正在閱讀的幻燈片。
~~~
currentSlide : 0,...next : function() { Slides.translateAmount -= Slides.slideWidth; Slides.updateHash( ++Slides.currentSlide );},updateHash : function() { location.hash = '#slide-' + Slides.currentSlide;}?
~~~
? 注意我們現在在將currentSlide在傳入updateHash方法前加1。這是合適的,當我們按下向右鍵,hash值將會更新為新幻燈片的值。
**幻燈片動畫**
? 最后,在已經設置了所有必須的值后,我們可以來設置幻燈片動畫了。
~~~
next : function() { Slides.translateAmount -= Slides.slideWidth; Slides.updateHash( ++Slides.currentSlide ); Slides.animate();},animate : function() { Slides.container .children() .css( '-webkit-transform', 'translateX(' + Slides.translateAmount + 'px)');}?
~~~
? 為了更好的性能,我們將使用CSS3的特性來進行幻燈片的切換。我們必須要更新CSS文件。
~~~
#slides div { ... -webkit-transition: all 1s linear; transition: all 1s linear;}?
~~~
**前一張幻燈片**
? Prev方法和next非常類似。
~~~
prev : function() { // No more left to go back. if ( Slides.translateAmount === 0 ) return; Slides.translateAmount += Slides.slideWidth; Slides.updateHash( --Slides.currentSlide ); Slides.animate();}?
~~~
? 現在,在我們轉換到幻燈片開始時,我們必須要反轉translateAmount變量和hash值。另外,我們必須要考慮用戶在第一張幻燈片時按下向左鍵時的情況。而當這種情況出現時,我們什么都不必做。
**最后的Javascript腳本**
~~~
var Slides = { container : $('#slides'), totalSlides : '', translateAmount : 0, currentSlide : 0, slideWidth : '', init : function(totalSlides) { var each; if ( !totalSlides ) throw new Error('Please pass the total number of slides.'); Slides.totalSlides = totalSlides; Slides.loadContent(); each = Slides.container.children('div'); // Determine the width of our canvas Slides.slideWidth = each.width() + ( parseInt( each.css('margin-right'), 10 ) ); Slides.keyPress(); }, loadContent : function() { Slides.container.hide(); for ( var i = 0; i < Slides.totalSlides; i++ ) { $('<div id="#slide-' + i + '"></div>') .load('slides/' + i + '.html') .appendTo(Slides.container); } Slides.container.show(); }, keyPress : function() { $(document.body).keydown(function(e) { // if left or right arrow key is pressed if ( e.keyCode === 39 || e.keyCode === 37 ) { e.preventDefault(); ( e.keyCode === 39 ) ? Slides.next() : Slides.prev(); } }); }, next : function( ) { Slides.translateAmount -= Slides.slideWidth; Slides.updateHash( ++Slides.currentSlide ); Slides.animate(); }, prev : function() { // No more left to go back. if ( Slides.translateAmount === 0 ) return; Slides.translateAmount += Slides.slideWidth; Slides.updateHash( --Slides.currentSlide ); Slides.animate(); }, animate : function() { Slides .container .children() .css( '-webkit-transform', 'translateX(' + Slides.translateAmount + 'px)' ); }, updateHash : function( direction ) { // Update current Slides and hash. location.hash = '#slide-' + Slides.currentSlide; }};// All right; let's do this.Slides.init(6);?
~~~
**完成**
? 所有的工作完成了。這并不困難。重要的地方在于,如果你在一個低或者高分辨率的情況下來觀看幻燈片,你可以通過Ctrl加+或者-鍵來進行頁面的縮放。如果你有任何的問題或者建議請讓我知道,謝謝。



- 前言
- AutoPager的簡單實現
- 利用CSS3特性巧妙實現漂亮的DIV箭頭
- IE9在Win7下任務欄新特性簡介
- 瀏覽器九宮格的簡單實現
- Raphael js庫簡介
- 使用CSS3構建Ajax加載動畫
- 用CSS3創建動畫價格表
- 用CSS3實現瀏覽器的縮放功能
- 用純CSS3實現QQ LOGO
- 用CSS3創建旋轉載入器
- 使用Javascript開發移動應用程序
- 用HTML5創建超酷圖像灰度漸變效果
- 使用CSS3創建文字顏色漸變(CSS3 Text Gradient)
- 僅用CSS創建立體旋轉幻燈片
- 如何創建跨瀏覽器的HTML5表單
- 用CSS3實現動畫進度條
- HTML5 Guitar Tab Player
- 奇妙的HTML5 Canvas動畫實例
- 談HTML5和CSS3的國際化支持
- 實現跨瀏覽器的HTML5占位符
- 前端開發必備工具:WhatFont Bookmarklet-方便的查詢網頁上的字體
- 使用HTML5和CSS3來創建幻燈片
- HTML5之美
- 如何使用HTML5創建在線精美簡歷
- 以小見大、由淺入深-談如何面試Javascript工程師
- 快速入門:HTML5強大的Details元素
- 用CSS3實現圖像風格
- HTML5視頻字幕與WebVTT
- 用純CSS3實現Path華麗動畫
- 用3個步驟實現響應式網頁設計
- 遇見CSS3濾鏡
- 關于CSS3濾鏡的碎念
- 用純CSS3繪制萌系漫畫人物動態頭像
- CSS3新的鼠標樣式介紹
- 用HTML5獻上愛的3D玫瑰
- 對HTML5 Device API相關規范的解惑
- 如何使用HTML5實現拍照上傳應用
- 2012第一季度國外HTML5移動開發趨勢
- HTML5新特性:范圍樣式
- 百度開發者大會-《用HTML5新特性開發移動App》PPT分享
- Chrome 19對于HTML5最新支持的動態:電池狀態API,全屏API,震動API,語音API
- 遇見Javascript類型數組(Typed Array)
- 用HTML5 Audio API開發游戲音樂
- 用HTML5實現人臉識別
- 用Javascript實現人臉美容
- Chrome 20對于HTML5最新支持的動態:顏色輸入,網絡信息API,CSS著色器
- 用HTML5實現手機搖一搖的功能
- 用HTML5實現iPad應用無限平滑滾動
- 用非響應式設計構建跨端Web App
- 了解SVG
- HTML5圖像適配介紹
- HTML5安全:內容安全策略(CSP)簡介
- HTML5安全:CORS(跨域資源共享)簡介
- 用CSS3 Region和3D變換實現書籍翻頁效果
- 談談移動App的思維誤區
- Chrome新特性:文件夾拖拽支持
- 《關注HTML5安全》
- HTML5安全風險詳析之一:CORS攻擊
- HTML5安全風險詳析之二:Web Storage攻擊
- HTML5圖像適配最新進展:響應式圖片規范草案
- HTML5移動Web App相關標準狀態及路線圖
- HTML5安全風險詳析之三:WebSQL攻擊
- Chrome引入WebRTC支持視頻聊天App
- HTML5安全風險詳析之四:Web Worker攻擊
- HTML5安全風險詳析之五:劫持攻擊
- HTML5安全風險詳析之六:API攻擊
- HTML5安全攻防詳析之七:新標簽攻擊
- 在iOS Safari中播放離線音頻
- 使用WebRTC實現遠程屏幕共享
- Firefox、Android、iOS遇見WebRTC
- HTML5光線傳感器簡介
- HTML5安全攻防詳析之八:Web Socket攻擊
- HTML5安全攻防詳析之完結篇:HTML5對安全的改進
- 激動人心!在網頁上通過語音輸入文字 - HTML5 Web Speech API介紹
- Web滾動性能優化實戰
- 用CSS3設計響應式導航菜單
- 用HTML5構建高性能視差網站
- 漫談@supports與CSS3條件規則
- HTML5下載屬性簡介
- 如何開發優秀的HTML5游戲?-迪斯尼《尋找奧茲之路》游戲技術詳解(一)
- 如何開發優秀的HTML5游戲?-迪斯尼《尋找奧茲之路》游戲技術詳解(二)
- 趨勢:Chrome為打包應用提供強大新特性
- 從HTML5移動應用現狀談發展趨勢
- 基于HTML5的Web跨設備超聲波通信方案