本文是JavaScript輕量級框架系列的第二篇文章。
reveal.js是一款開源的、功能強(qiáng)大的JavaScript幻燈片框架,通過簡單的HTML就能夠創(chuàng)建非常漂亮的幻燈片。其在github上有18000+個star,可見這個JavaScript框架的活躍程度和質(zhì)量。
Reveal.js的基本結(jié)構(gòu)其實很簡單,它實質(zhì)上就是一個html頁面,不過這個html的核心內(nèi)容部分需要按照reveal.js規(guī)定好的套路來,不然它就解析不出來了。其實大部分的JavaScript幻燈片框架都是一個原理,只不過各個框架的實現(xiàn)細(xì)節(jié)和復(fù)雜程度不一樣,包括本系列上一篇文章闡述的Impress.js。
下面讓我們一起來看看Reveal.js指定的游戲規(guī)則具體是什么樣子的,
<html>
<head>
<!-- 添加meta及css引入 -->
</head>
<body>
<div class="reveal">
<div class="slides">
<section>
<!-- 第一張幻燈片內(nèi)容 -->
</section>
<section>
<!-- 第二張幻燈片內(nèi)容 -->
</section>
<!-- 更多的幻燈片 -->
</div>
</div>
<!-- 引入reveal.js文件 -->
<script>
// reveal.js的初始化配置,包括一些插件的加載
</script>
</body>
</html>
從上面的代碼片段可以看出,html的文件結(jié)構(gòu)其實很簡單。核心就是下面html片段包裹的區(qū)域,
<div class="reveal">
<div class="slides">...</div>
</div>
其中,每一個<section>
都是一張幻燈片。live demo中效果絢麗的幻燈片其實就是對這些<section>
標(biāo)簽耍了些手段,讓他們具備了絢麗效果的展示。
需要特別說明的一點(diǎn)就是,上面的所有<section>
標(biāo)簽都是依次出現(xiàn)的,并沒有出現(xiàn)嵌套的情況(即<section>
標(biāo)簽中嵌套了<section>
標(biāo)簽),它的展現(xiàn)效果是,所有的幻燈片都依次從左到右的展示。
Reveal.js真的是一款功能強(qiáng)大的幻燈片框架,基本上涵蓋了其他幻燈片框架的所有功能。而且采用插件式設(shè)計,將不同的功能封裝到不同的插件,按需加載,保證了其靈活性。同時擁有生動的幻燈片過渡效果,絢麗的內(nèi)置主題,以及一些完善的功能設(shè)計,能夠讓你的幻燈片更加完美的展示。
下面我們來談?wù)勂渲饕膸讉€特性。
html代碼中如果出現(xiàn)<section>
標(biāo)簽嵌套的情況,reveal.js將會如何表現(xiàn)呢?假設(shè)我們有如下的html結(jié)構(gòu),
<div class="reveal">
<div class="slides">
<section>Single Horizontal Slide</section>
<section>
<section>Vertical Slide 1</section>
<section>Vertical Slide 2</section>
</section>
</div>
</div>
可見第二個<section>
標(biāo)簽中又嵌套了兩個<section>
標(biāo)簽,這樣一來第二張幻燈片其實就是由兩張子幻燈片組成的,在方向上是垂直的。具體效果可以體驗Live Demo或者template demo。
這其實是一個很有意思的特性,當(dāng)我們一張幻燈片中不能滿足一個主題的描述時,可以采用子幻燈片的形式來補(bǔ)充,此時幻燈片的嵌套將會非常有用。
我本人比較喜歡markdown這種簡潔的標(biāo)記式語法。在接觸到reveal.js之前,我曾特意去搜索了一些能夠直接解析markdown文件并生成幻燈片的JavaScript框架,的確得到了一些結(jié)果,比如cleaver,就使用上來說,的確非常簡單,能夠非??焖俚纳苫脽羝撁?。但是這個輕量的框架不能滿足這樣一個需求:不太容易生成圖文并茂的幻燈片,一般只能生成一些簡單的純文字幻燈片,而且展示效果不是那么的優(yōu)美。
reveal.js是支持markdown語法的,而且有兩種不同形式的支持。
我們可以在某一個<section>
標(biāo)簽中(即某一張幻燈片中)插入一段markdown代碼片段,如下所示,
<section data-markdown>
<h2>內(nèi)聯(lián)片段支持</h2>
<script type="text/template">
## Page title
A paragraph with some text and a [link](http://hakim.se).
</script>
</section>
這里,我們有兩點(diǎn)需要注意,
<section>
標(biāo)簽中需要添加額外的屬性標(biāo)簽data-markdown
來標(biāo)識此幻燈片中有markdown代碼片段<script type="text/template">
標(biāo)簽包裹,可見markdown在其中被當(dāng)作成一種模版除了支持內(nèi)聯(lián)的markdown代碼片段之外,reveal.js還可以解析一個外部引入的markdown文件,如下所示,
<section data-markdown="example.md"
data-separator="^---"
data-vertical="^--"
data-notes="^Note:"
data-charset="utf-8">
</section>
從上面的html代碼中,我們添加幾個data-*
屬性,他們的作用分別如下,
data-markdown="example.md"
需要解析的外部markdown文件路徑data-separator="^---"
表明markdown文件中使用---
符號來區(qū)分不同的幻燈片data-vertical="^--"
表明markdown文件中使用--
符號來區(qū)分垂直子幻燈片data-notes="^Note:"
演講者備注的標(biāo)識data-charset="utf-8"
markdown文件的編碼格式對應(yīng)的markdown文件內(nèi)容范例如下,
## 我是標(biāo)題一
我是內(nèi)容一
--
### 我是副標(biāo)題一
我是內(nèi)容
--
### 我是副標(biāo)題二
我下面是代碼
var p = {
name: 'gejiawen',
age: 18
};
console.log('hello world', p.name);
--
### 我是副標(biāo)題三
- Item 1 <!-- .element: class="fragment" data-fragment-index="1" -->
- Item 2 <!-- .element: class="fragment" data-fragment-index="2" -->
- Item 3 <!-- .element: class="fragment" data-fragment-index="3" -->
- Item 4 <!-- .element: class="fragment" data-fragment-index="4" -->
- grow <!-- .element: class="fragment grow" data-fragment-index="5" -->
- roll-in <!-- .element: class="fragment roll-in" data-fragment-index="6" -->
- highlight-current-blue <!-- .element: class="fragment highlight-current-blue" data-fragment-index="7" -->
--
### 我是副標(biāo)題四
<!-- .slide: data-background="#007777" -->
我是內(nèi)容
---
## 我是第二頁幻燈片
<!-- .slide: data-transition="linear" data-background="#4d7e65" data-background-transition="slide" -->
我是內(nèi)容
---
## 我是第三頁幻燈片
<!-- .slide: data-transition="linear" data-background="#8c4738" data-background-transition="zoom" -->
我是內(nèi)容
從上面的markdown內(nèi)容,我們可以看出,
看到了嗎,就是這么簡單。
在上面小節(jié)中的markdown代碼中,如果你觀察仔細(xì)的話,可能會看到一些奇怪的代碼,比如,
### 我是副標(biāo)題三
- Item 1 <!-- .element: class="fragment" data-fragment-index="1" -->
- Item 2 <!-- .element: class="fragment" data-fragment-index="2" -->
- Item 3 <!-- .element: class="fragment" data-fragment-index="3" -->
- Item 4 <!-- .element: class="fragment" data-fragment-index="4" -->
- grow <!-- .element: class="fragment grow" data-fragment-index="5" -->
- roll-in <!-- .element: class="fragment roll-in" data-fragment-index="6" -->
- highlight-current-blue <!-- .element: class="fragment highlight-current-blue" data-fragment-index="7" -->
--
### 我是副標(biāo)題四
<!-- .slide: data-background="#007777" -->
我是內(nèi)容
發(fā)現(xiàn)了嗎?
這些<!-- .element: class="fragment" data-fragment-index="1" -->
代碼,類似html的注釋語法是干啥的啊?
其實這些額外的屬性是為了增強(qiáng)markdown的表現(xiàn)性。主要分為兩類,
<!-- .element: xxx -->
給某個元素添加額外的表現(xiàn)特性,比如fragment等<!-- .slide: xxx -->
給某個slide(幻燈片)添加額外的表現(xiàn)特性,比如背景色,內(nèi)容變換效果等。我個人覺得這是個非常有用的設(shè)計,很大程度上彌補(bǔ)了markdown生成的幻燈片表現(xiàn)性不強(qiáng)的缺陷。
還有一點(diǎn)需要特別指出的是,reveal.js對外部markdown文件的解析,需要web server的支持,因為是通過服務(wù)器去拿到相應(yīng)的markdown文件的。
在之前的基礎(chǔ)結(jié)構(gòu)中可以看到,reveal.js的初始化及相關(guān)配置是位于整個html文件的最后部分的。下面給出其常用的一些配置項,
// 下面的值都是reveal.js的默認(rèn)值
Reveal.initialize({
// 是否展示導(dǎo)航控制器
controls: true,
// 是否展示幻燈片進(jìn)度條
progress: true,
// 是否展示當(dāng)前幻燈片的頁面
slideNumber: false,
// 是否啟用瀏覽器的歷史功能
history: false,
// 是否啟用鍵盤快捷鍵
keyboard: true,
// 是否啟用幻燈片鳥瞰模式
overview: true,
// 是否讓幻燈片垂直居中
center: true,
// 是否啟用移動的觸控響應(yīng)
touch: true,
// 是否開啟幻燈片循環(huán)(最后一張結(jié)束后繼續(xù)下一張?zhí)D(zhuǎn)回第一張)
loop: false,
// 是否啟用fragments功能
fragments: true,
// 是否自動輪播。0為不自動輪播,不為0的值即為自動輪播的間隔。
autoSlide: 0,
// 當(dāng)用戶輸入則禁用自動輪播
autoSlideStoppable: true,
// 是否使用鼠標(biāo)滾輪進(jìn)行幻燈片播放
mouseWheel: false,
// 幻燈片變換動畫類型,可選值 default/cube/page/concave/zoom/linear/fade/none
transition: 'default',
// 變換動畫速度,可選值 default/fast/slow
transitionSpeed: 'default',
// 幻燈片背景變換風(fēng)格,可選值 default/none/slide/concave/convex/zoom
backgroundTransition: 'default',
});
一般來說,大部分的配置屬性都是直接使用默認(rèn)值即可,想了解更多信息,請閱讀其文檔
前面說過reveal.js將各種不同的功能都封裝成了獨(dú)立的插件,在實際使用的過程中按需加載即可。如下,
Reveal.initialize({
dependencies: [
// 一個跨瀏覽器的獲取classList的解決方案插件
{
src: 'lib/js/classList.js',
condition: function() {
return !document.body.classList;
}
},
// markdown解析支持插件
{
src: 'plugin/markdown/marked.js',
condition: function() {
return !!document.querySelector('[data-markdown]');
}
},
{
src: 'plugin/markdown/markdown.js',
condition: function() {
return !!document.querySelector('[data-markdown]');
}
},
// 代碼高亮插件
{
src: 'plugin/highlight/highlight.js',
async: true,
callback: function() {
hljs.initHighlightingOnLoad();
}
},
// 幻燈片局部區(qū)域的縮放插件
{
src: 'plugin/zoom-js/zoom.js',
async: true,
condition: function() {
return !!document.body.classList;
}
},
// 演講者備注插件
{
src: 'plugin/notes/notes.js',
async: true,
condition: function() {
return !!document.body.classList;
}
},
// 遠(yuǎn)程控制插件
{
src: 'plugin/remotes/remotes.js',
async: true,
condition: function() {
return !!document.body.classList;
}
},
// 常用數(shù)學(xué)公式表達(dá)式插件
{
src: 'plugin/math/math.js',
async: true
}
]
});
一般來說,classList
和highlight
是必用的插件,如果你用到了markdown,就需要加載markdown插件。當(dāng)然這些都是根據(jù)不同需求而定的。想了解更多信息,請閱讀其文檔。
還記得嗎,我們前面提到了對markdown的額外支持,其實它更一般的使用場景是直接在<section>
標(biāo)簽上添加各種屬性,如下,
<section data-background="#ff0000">
<h2>All CSS color formats are supported, like rgba() or hsl().</h2>
</section>
<section data-background="http://example.com/image.png">
<h2>This slide will have a full-size background image.</h2>
</section>
<section data-background="http://example.com/image.png" data-background-size="100px" data-background-repeat="repeat">
<h2>This background image will be sized to 100px and repeated.</h2>
</section>
這里唯一值得一提就是,在<section>
標(biāo)簽上添加的額外屬性會覆蓋Reveal.initialize()
時的配置。
Fragments是用來突出顯示幻燈片上的某一個元素的。體驗一下。
其實實現(xiàn)起來很簡單,只需要給你想要fragment的元素添加一個css class name即可。如下,
<section>
<p class="fragment">normal</p>
<p class="fragment grow">grow</p>
<p class="fragment shrink">shrink</p>
<p class="fragment roll-in">roll-in</p>
<p class="fragment fade-out">fade-out</p>
<p class="fragment current-visible">visible only once</p>
<p class="fragment highlight-current-blue">blue only once</p>
<p class="fragment highlight-red">highlight-red</p>
<p class="fragment highlight-green">highlight-green</p>
<p class="fragment highlight-blue">highlight-blue</p>
</section>
更加高級一點(diǎn)的用法,
<section>
<span class="fragment fade-in">
<span class="fragment fade-out">I'll fade in, then out</span>
</span>
</section>
這里有兩個地方需要注意,
fragment
類,將會使元素變?yōu)椴豢梢姟?/li>
fragment
可以很多效果能夠聯(lián)合使用,如grow
等。此時一般來說元素的可見的。fragment
和fade-in
等某些具有讓元素隱藏的css class name聯(lián)合使用時。如上面的高級用法。data-fragment-index
屬性來指定各元素的執(zhí)行次序我們知道reveal.js將每一個<section>
標(biāo)簽解析成一個幻燈片。reveal.js內(nèi)部會依次給每個<section>
標(biāo)簽添加一個數(shù)字id,在瀏覽幻燈片時,瀏覽器的url如下,
http://localhost:4000/livedemo/#/3
如果當(dāng)前的幻燈片正處在一個子幻燈片上,那么瀏覽器的url如下,
http://localhost:4000/livedemo/#/3/1
如果你給<section>
標(biāo)簽添加了id
屬性,比如
<section id="test"></section>
那么,瀏覽器的url就會如下,
http://localhost:4000/livedemo/#/test
根據(jù)上面的分析,我們可以在某一張幻燈片中添加一個內(nèi)部跳轉(zhuǎn)鏈接,比如
<a href="#/2/2">Link</a>
<a href="#/some-slide">Link</a>
這樣我們就可以直接進(jìn)行內(nèi)部跳轉(zhuǎn)了。
除了上面介紹的各種功能和特點(diǎn)之外,reveal.js仍然還有不少可以挖掘的地方,比如事件機(jī)制、PDF導(dǎo)出支持、演講備注、同步演示等。這里就不多作描述了,想了解更多信息,請閱讀其文檔。
Reveal.js的確是一款功能強(qiáng)大的幻燈片框架,深受web開發(fā)者的喜愛?;旧峡梢苑浅]p松的制作出一個幻燈片。特別針對那些Geekers來說,如果只是一些純文字的描述,那么一份markdown文件將會幫你搞定所有的事情。即使是需要制作圖文并茂的幻燈片,也不是難事,無非就是多花費(fèi)些時間,對<section>
標(biāo)簽添加一些額外的屬性而已。
你還在執(zhí)著office的ppt么?來試試reveal.js吧。
更多建議: