打造web版epub閱讀器(書架設(shè)計(jì))

寫在前面的話

實(shí)現(xiàn)本閱讀器需要進(jìn)行以下幾個(gè)步驟:

  1. 設(shè)計(jì)書架。(可添加圖書僧家,刪除圖書等)
  2. 打開并閱讀epub圖書雀摘。(可做高亮、筆記八拱、書簽阵赠,可顯示目錄并通過目錄跳轉(zhuǎn))

本篇文章先實(shí)現(xiàn)第一項(xiàng),設(shè)計(jì)書架乘粒,epub的閱讀部分將在稍后文章中進(jìn)行描述豌注。
作者在實(shí)現(xiàn)時(shí)采用了vue + vue-loader來進(jìn)行編碼伤塌,直接使用js實(shí)現(xiàn)時(shí)原理都是一樣的灯萍。

先附上效果圖:

實(shí)現(xiàn)書架主要有以下幾點(diǎn):

  1. 圖書的顯示
  2. 圖書的上傳。
  3. 圖書的存儲(chǔ)每聪。
  4. 圖書的管理旦棉。

顯示圖書

設(shè)計(jì)對(duì)象 files 存儲(chǔ)所有圖書信息

<div v-for="file in files" class="booklocal">
    <div class="readtime">
        {{file.readtimedis}}
    </div>
    <el-card :body-style="{ padding: '0px' }">
        ![](file.thumbnail)
    </el-card>
    <div class="filename">
        <span>{{file.name}}</span>
    </div>
</div>

上傳圖書

因?yàn)樵诤芏鄷r(shí)候,我們要通過其他方式來觸發(fā)文件選擇框药薯,所以在此將默認(rèn)的文件選擇器設(shè)置為不可見的绑洛,然后在其他(圖片按鈕)地方點(diǎn)擊事件中觸發(fā)文件選擇框。

//添加file input并將其設(shè)置為不可見
<input type="file" multiple="multiple" class="fileInput" @change="selectedFiles" 
 ref="inputer" />
.fileInput {
    display: none;
}
//設(shè)置自定義按鈕并在其點(diǎn)擊事件中觸發(fā)文件選擇器童本。
<div class="book-add" v-on:click="addbook">+</div>
.book-add {
    width: 60px;
    height: 60px;
    border-radius: 30px;
    background-color: #FB771E;
    box-shadow: 5px 5px 10px #272727;
    text-align: center;
    line-height: 60px;
    font-size: 40px;
    //設(shè)置文字不能選中
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    cursor: pointer;
}
addbook: function(event) {
    $('.fileInput').click();
},
//用戶選擇文件后的觸發(fā)事件真屯,
selectedFiles: function(event) {
    var self = this;
    //獲取文件
    var files = this.$refs.inputer.files;
    $.each(files, function(index, file) {//可在此處理上傳的文件。
    }
}

存儲(chǔ)圖書

HTML5提供了對(duì)象存儲(chǔ)技術(shù)穷娱,可以再IndexedDB數(shù)據(jù)庫中保存Bolb對(duì)象绑蔫,而文件正是一種特殊的Blob對(duì)象。
在進(jìn)行對(duì)象存儲(chǔ)時(shí)泵额,其存儲(chǔ)形式為Key---Object(文件)配深,需要對(duì)每個(gè)文件進(jìn)行區(qū)分,也就是說每個(gè)文件需要唯一的Key嫁盲,在此我們使用MD5來對(duì)文件進(jìn)行區(qū)分篓叶。

1. 提取文件MD5碼

我們使用github上的開源庫spark-md5來實(shí)現(xiàn)MD5碼的提取。代碼如下:

selectedFiles: function(event) {
    var self = this;
    //獲取文件
    var files = this.$refs.inputer.files;
    $.each(files, function(index, file) {
        var fileName = file.name;
        if (fileName.substr(fileName.indexOf(".")) == '.epub') {
            if (file.size / 1024 / 1024 > 200) {
                //如果大于20M
                self.$notify({
                    title: '失敗',
                    message: fileName + '大于200M,目前只支持小于200M文件',
                    type: 'error'
                });
            } else {
                var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
                    chunkSize = 2097152, // Read in chunks of 2MB
                    chunks = Math.ceil(file.size / chunkSize),
                    currentChunk = 0,
                    spark = new SparkMD5.ArrayBuffer(),
                    fileReader = new FileReader();
                var md5;
                fileReader.onload = function(e) {
                    spark.append(e.target.result); // Append array buffer
                    currentChunk++;
                    if (currentChunk < chunks) {
                        loadNext();
                    } else {
                        md5 = spark.end();//在此處獲取MD5碼缸托。
                    }
                };
                fileReader.onerror = function() {
                    console.warn('oops, something went wrong.');
                };
                function loadNext() {
                    var start = currentChunk * chunkSize,
                        end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
                    fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
                }
                loadNext();
            }
        } else {
            self.$notify({
                title: '失敗',
                message: fileName + '為非epub文件左敌!',
                type: 'error'
            });
        }
    });
},
2. 存儲(chǔ)圖書

使用github上的開源庫localForage來對(duì)文件進(jìn)行存儲(chǔ)。localForage將對(duì)IndexedDB數(shù)據(jù)庫的操作進(jìn)行了封裝俐镐,代碼如下:

//在vue中引入localForage
import localForage from "localforage";
//初始化localForage
this.store = localForage.createInstance({
    name: this.dbName
});
//使用開源庫對(duì)文件進(jìn)行存儲(chǔ)母谎。(MD5為以上代碼獲取的MD5值,file為循環(huán)中的file)
self.store.setItem(md5, file, function(err) {
});
3. 管理圖書

我們先討論管理圖書都需要什么操作京革,使用什么方式的操作更容易讓用戶接受奇唤,然后再討論每種操作的實(shí)現(xiàn)方式。

  1. 管理圖書所需操作匹摇。
  • 添加圖書
  • 導(dǎo)出圖書
  • 刪除圖書
  • 重命名圖書
  1. 操作方式
    使用右鍵來對(duì)其進(jìn)行操作咬扇。如圖:

右鍵菜單使用context.js來實(shí)現(xiàn),具體使用方式請(qǐng)參考使用指南或如下代碼:

addRightClick: function() {
        var self = this;
        context.init({
            preventDoubleContext: false
        });
        context.attach('.booklocal', [{
            text: '打開',
            action: function(e, selector) {
              //添加打開操作
            }
        }, {
            text: '導(dǎo)出',
            action: function(e, selector) {
              //添加導(dǎo)出操作
            }
        }, {
            text: '重命名',
            action: function(e, selector) {
              //添加重命名操作
            }
        }, {
            text: '刪除',
            action: function(e, selector) {
              //添加刪除操作
            }
        }]);
    },
  1. 操作的實(shí)現(xiàn)方式廊勃。
    設(shè)計(jì)文件管理是包含如下屬性:
    var fileInfo=new Object();
    fileInfo.name = file.name; //文件顯示的名字
    fileInfo.dname = md5; //文件的MD5值
    fileInfo.addtime = Date.parse(new Date()); //文件添加日期(如有需要可以添加)
    fileInfo.readtime = null; //文件上次閱讀時(shí)間
    fileInfo.readtimedis = "未讀過"; //顯示給用戶的文件上次閱讀時(shí)間
    fileInfo.lastreadurl = null; //文件上次關(guān)閉時(shí)后的閱讀位置懈贺,方便下次閱讀直接跳轉(zhuǎn)
    fileInfo.thumbnail = ""; //文件縮略圖
    fileInfo.tags=[]; //閱讀圖書時(shí)所添加的標(biāo)簽
    fileInfo.notes=[]; //閱讀圖書時(shí)的筆記
    導(dǎo)出
    //導(dǎo)出
    export: function() {
    var self = this;
    //this.editFile為當(dāng)前正在操作的文件,可在用戶點(diǎn)擊右鍵時(shí)獲取
    this.store.getItem(this.editFile.dname, function(err, file) {
    if (file) {
    var fileName = self.editFile.name;
    if (fileName.substr(fileName.indexOf(".")) == '.epub') {
    self.downFile(file, self.editFile.name);
    } else {
    self.downFile(file, self.editFile.name + ".epub");
    }
    } else {
    }
    });
    },
    //下載
    downFile: function(blob, fileName) {
    if (window.navigator.msSaveOrOpenBlob) {
    navigator.msSaveBlob(blob, fileName);
    } else {
    var link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = fileName;
    link.click();
    window.URL.revokeObjectURL(link.href);
    }
    },
    刪除
    刪除就是把圖書信息中的本圖書刪掉即可坡垫。
    vue的數(shù)據(jù)綁定機(jī)制梭灿,會(huì)自動(dòng)刪除相應(yīng)圖書。
    重命名
    重命名跟刪除機(jī)制一樣冰悠,只需要修改圖書信息中的name即可堡妒。

總結(jié):

書架的設(shè)計(jì),主要包括圖書的顯示溉卓,圖書的上傳皮迟,圖書的存儲(chǔ)和圖書的管理。

  • 使用VUE可以很方便的使界面顯示和數(shù)據(jù)進(jìn)行同步桑寨。
  • 圖書上傳時(shí)使用MD5來標(biāo)記圖書伏尼,可以方便索引圖書。
  • 使用localForage可以很方便的對(duì)圖書進(jìn)行存儲(chǔ)尉尾。
  • 使用context.js來實(shí)現(xiàn)右鍵菜單爆阶,對(duì)圖書進(jìn)行管理。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沙咏,一起剝皮案震驚了整個(gè)濱河市辨图,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌芭碍,老刑警劉巖徒役,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異窖壕,居然都是意外死亡忧勿,警方通過查閱死者的電腦和手機(jī)杉女,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸳吸,“玉大人熏挎,你說我怎么就攤上這事∩卫” “怎么了坎拐?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)养匈。 經(jīng)常有香客問我哼勇,道長(zhǎng),這世上最難降的妖魔是什么呕乎? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任积担,我火速辦了婚禮,結(jié)果婚禮上猬仁,老公的妹妹穿的比我還像新娘帝璧。我一直安慰自己,他們只是感情好湿刽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布的烁。 她就那樣靜靜地躺著,像睡著了一般诈闺。 火紅的嫁衣襯著肌膚如雪渴庆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天买雾,我揣著相機(jī)與錄音把曼,去河邊找鬼。 笑死漓穿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的注盈。 我是一名探鬼主播晃危,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼老客!你這毒婦竟也來了僚饭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤胧砰,失蹤者是張志新(化名)和其女友劉穎鳍鸵,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尉间,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡偿乖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年击罪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贪薪。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡媳禁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出画切,到底是詐尸還是另有隱情竣稽,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布霍弹,位于F島的核電站毫别,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏典格。R本人自食惡果不足惜拧烦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望钝计。 院中可真熱鬧恋博,春花似錦、人聲如沸私恬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽本鸣。三九已至疫衩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間荣德,已是汗流浹背闷煤。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涮瞻,地道東北人鲤拿。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像署咽,于是被迫代替她去往敵國和親近顷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • iOS開發(fā)系列--網(wǎng)絡(luò)開發(fā) 概覽 大部分應(yīng)用程序都或多或少會(huì)牽扯到網(wǎng)絡(luò)開發(fā)宁否,例如說新浪微博窒升、微信等,這些應(yīng)用本身可...
    lichengjin閱讀 3,661評(píng)論 2 7
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理慕匠,服務(wù)發(fā)現(xiàn)饱须,斷路器,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 10,967評(píng)論 6 13
  • 今天的主題台谊,運(yùn)動(dòng)蓉媳。 2016年最有成就感的事譬挚,是自己開始形成運(yùn)動(dòng)的習(xí)慣。 最直接的表現(xiàn)是督怜,某次去上海殴瘦,住在酒店就開...
    石艷華閱讀 154評(píng)論 1 1
  • 我喜歡仰望沒有一絲云彩的藍(lán)天,清澈澄明号杠,有讓我浮躁的心平靜下來的魔力蚪腋。
    333455adff2d閱讀 191評(píng)論 0 0