圖片來源 - http://webkit.org/
電子書用 iBooks 看,沒有什麼稀奇,但 iBooks 的閱讀器是用修修改改的 WebKit 做,那可就好玩了!因為 ePub 裡的格式幾乎就像 XHTML 一般,如果呈現它的閱讀軟體可以支援網頁上豐富的互動,那電子書就不再枯燥乏味了!況且 WebKit 有支援 HTML5 與 Javascript 耶,那是不是電子書的內容就可變動了呢?
上週老闆說,iPad 裡頭的 iBooks 是用 WebKit 實作的,當下就聽到他弄出 HTML5 的特效出來,這週開始來測測上頭的 WebKit 到底有甚麼可以玩的,首先擺於上傳自己的電子書,方法很簡單,就是建立出 epub 格式,再把他拖進 iTunes ,那就會出現"書櫃"的項目,接著再切換到 device 上頭,跑去該項目按一下同步!資料就傳送到 iPad 上,並且可以用 iBooks 去瀏覽。細節可以參考這篇:[iPhone/iPad] 匯入自製的 ePub 電子書 至 iBooks
目前測試 Javascript 的結果,可以用 alert 對 document 跟 window 物件測試一下,代表有此物件可以用,所以接下來測試 document.getElementById 也是 OK 的,當然,去改某個物件的 innerHTML 也是可以成功啦!接著,野心更大就是丟個 jQuery 進去吃吃,發現也 ok 啦!
之前是先寫一個簡單的 HTML 檔案,然後用 Calibre 把他轉成 ePub 來用,後來測試幾次後,發現 script 會被它轉爛,當時還一直以為是 WebKit 的功能被縮減掉(但真的有其他的功能被拿掉了,如 js 的 document.write),浪費不少時間測試,最後,就變成自己手動去建 ePub 啦!建議可以先用 Calibre 建立一個範例檔,然後把它解開來,除了確認內文是否正常,也可以當作一個範本,以後修改完內文就可以快速打包囉!
指令:
$ cd epub
$ ls
META-INF cover_image.jpg jquery.html stylesheet.css toc.ncx
content.opf jquery-1.4.2.min.js mimetype titlepage.xhtml
打包指令:
$ zip -0Xq ../test.epub mimetype
$ zip -Xr9Dq ../test.epub *
把所在目錄的東西, 打包成 test.epub 並擺到上一層目錄裡
以下是 jquery.html 程式碼:
<?xml version='1.0' encoding='utf-8'?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>jQuery on local</title>
<script language="JavaScript" TYPE="text/javascript" src="jquery-1.4.2.min.js"></script>
<script language="JavaScript" TYPE="text/javascript">
function updateByjQuery()
{
var curr = new Date();
var y = curr.getFullYear();
var m = curr.getMonth() + 1;
var d = curr.getDate();
var h = curr.getHours();
var min = curr.getMinutes();
var sec = curr.getSeconds();
$( '#1' ).html( 'By jQuery: '+y+'/'+m+'/'+d+' '+h+':'+min+':'+sec );
}
function updateBygetElementById()
{
var curr = new Date();
var y = curr.getFullYear();
var m = curr.getMonth() + 1;
var d = curr.getDate();
var h = curr.getHours();
var min = curr.getMinutes();
var sec = curr.getSeconds();
document.getElementById( '1' ).innerHTML = 'By getElementById: ' +y+'/'+m+'/'+d+' '+h+':'+min+':'+sec;
}
function ajaxByjQuery()
{
$.ajax({
async: false,
type: "GET",
dataType: "html",
url: "http://tw.yahoo.com",
success: function(data) {
alert( data ) ;
}
});
}
function dumpObj(obj, name, indent, depth) { // modified from http://geekswithblogs.net/svanvliet/archive/2006/03/23/simple-javascript-object-dump-function.aspx
if (depth > 1)
return ( indent + name + ": 'Maximum Depth Reached'\n" );
if(typeof obj == "function") {
return "func: " + name + "\n";
} else if (typeof obj == "object") {
var child = null;
var output = indent + name + "\n";
indent += "\t";
for (var item in obj) {
try {
child = obj[item];
} catch (e) {
child = "'UnableToEvaluate'";
}
if(typeof child == "function") {
output += indent + " func: " + item + "\n";
} else if (typeof child == "object") {
//output += dumpObj(child, item, indent, depth + 1);
} else {
//output += indent + item + ": " + child + "\n";
}
}
return output;
} else {
//return obj;
}
}
</script>
<meta content="http://www.w3.org/1999/xhtml; charset=utf-8" http-equiv="Content-Type"/>
</head>
<body>
<div id="main">
<p id="1">Hello World</p>
</div>
<hr/>
<p>
<span onclick="alert(window);">alert(window)</span><br />
<span onclick="alert(document);">alert(document)</span><br />
<span onclick="alert(document.write);">alert(document.write)</span><br />
<span onclick="alert(jQuery);">alert(jQuery)</span><br />
<span onclick="alert($);">alert($)</span><br />
<span onclick="var curr = new Date();var y = curr.getFullYear();var m = curr.getMonth() + 1;var d = curr.getDate();var h = curr.getHours();var min = curr.getMinutes();var sec = curr.getSeconds();$( '#1' ).html( 'By inline:'+y+'/'+m+'/'+d+' '+h+':'+min+':'+sec );">update by inline (use jQuery)</span><br />
<span onclick="updateByjQuery();">update by func (use jQuery)</span><br />
<span onclick="updateBygetElementById();">update by func (use document.getElementById)</span><br />
<span onclick="$.ajax({async: false,type: 'GET',dataType: 'html',url: 'http://tw.yahoo.com', success: function(data) {alert( data ) ;}});">inline ajax call (use jQuery)</span><br />
<span onclick="ajaxByjQuery();">ajax call by func</span><br />
<span onclick="alert( dumpObj(document, 'document', '\t', 0) );">dump document</span><br />
</p>
</body>
</html>
心得:
- 若用 <script language="JavaScript" TYPE="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script> 這種方式, 則打開書的時候, 整個會空白, 但改用以下方式就沒問題:
- <script language="JavaScript" TYPE="text/javascript" src="jquery-1.4.2.min.js"></script>
- 新增 content.opf 的 manifest
- <item href="jquery-1.4.2.min.js" id="jquery" media-type="text/javascript"/>
- 最後,記得把 jquery-1.4.2.min.js 也擺進去打包
- 有些地方, 如在寫 inline 時, 若碰到 '<' 符號會被判斷成語法錯誤, 所以得要設法避開
- 在 head 定義 js func 時, 不要用 <!-- 與 // --> 去處理, 這樣定義出來不能使用, 即:
<script language="JavaScript" TYPE="text/javascript"><!--
func hehe() {}
// -->
</script>
一些成果: