打造web版epub阅读器(书架设计)

写在前面的话

实现本阅读器需要进行以下几个步骤:

  1. 设计书架。(可添加图书,删除图书等)
  2. 打开并阅读epub图书。(可做高亮、笔记、书签,可显示目录并通过目录跳转)

本篇文章先实现第一项,设计书架,epub的阅读部分将在稍后文章中进行描述。
作者在实现时采用了vue + vue-loader来进行编码,直接使用js实现时原理都是一样的。

先附上效果图:

打造web版epub阅读器(书架设计)_第1张图片

实现书架主要有以下几点:

  1. 图书的显示
  2. 图书的上传。
  3. 图书的存储。
  4. 图书的管理。

显示图书

设计对象 files 存储所有图书信息

{{file.readtimedis}}
![](file.thumbnail)
{{file.name}}

上传图书

因为在很多时候,我们要通过其他方式来触发文件选择框,所以在此将默认的文件选择器设置为不可见的,然后在其他(图片按钮)地方点击事件中触发文件选择框。

//添加file input并将其设置为不可见

.fileInput {
    display: none;
}
//设置自定义按钮并在其点击事件中触发文件选择器。
+
.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; //设置文字不能选中 -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; cursor: pointer; } addbook: function(event) { $('.fileInput').click(); }, //用户选择文件后的触发事件, selectedFiles: function(event) { var self = this; //获取文件 var files = this.$refs.inputer.files; $.each(files, function(index, file) {//可在此处理上传的文件。 } }

存储图书

HTML5提供了对象存储技术,可以再IndexedDB数据库中保存Bolb对象,而文件正是一种特殊的Blob对象。
在进行对象存储时,其存储形式为Key---Object(文件),需要对每个文件进行区分,也就是说每个文件需要唯一的Key,在此我们使用MD5来对文件进行区分。

1. 提取文件MD5码

我们使用github上的开源库spark-md5来实现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. 存储图书

使用github上的开源库localForage来对文件进行存储。localForage将对IndexedDB数据库的操作进行了封装,代码如下:

//在vue中引入localForage
import localForage from "localforage";
//初始化localForage
this.store = localForage.createInstance({
    name: this.dbName
});
//使用开源库对文件进行存储。(MD5为以上代码获取的MD5值,file为循环中的file)
self.store.setItem(md5, file, function(err) {
});
3. 管理图书

我们先讨论管理图书都需要什么操作,使用什么方式的操作更容易让用户接受,然后再讨论每种操作的实现方式。

  1. 管理图书所需操作。
  • 添加图书
  • 导出图书
  • 删除图书
  • 重命名图书
  1. 操作方式
    使用右键来对其进行操作。如图:
打造web版epub阅读器(书架设计)_第2张图片

右键菜单使用context.js来实现,具体使用方式请参考使用指南或如下代码:

addRightClick: function() {
        var self = this;
        context.init({
            preventDoubleContext: false
        });
        context.attach('.booklocal', [{
            text: '打开',
            action: function(e, selector) {
              //添加打开操作
            }
        }, {
            text: '导出',
            action: function(e, selector) {
              //添加导出操作
            }
        }, {
            text: '重命名',
            action: function(e, selector) {
              //添加重命名操作
            }
        }, {
            text: '删除',
            action: function(e, selector) {
              //添加删除操作
            }
        }]);
    },
  1. 操作的实现方式。
    设计文件管理是包含如下属性:
    var fileInfo=new Object();
    fileInfo.name = file.name; //文件显示的名字
    fileInfo.dname = md5; //文件的MD5值
    fileInfo.addtime = Date.parse(new Date()); //文件添加日期(如有需要可以添加)
    fileInfo.readtime = null; //文件上次阅读时间
    fileInfo.readtimedis = "未读过"; //显示给用户的文件上次阅读时间
    fileInfo.lastreadurl = null; //文件上次关闭时后的阅读位置,方便下次阅读直接跳转
    fileInfo.thumbnail = ""; //文件缩略图
    fileInfo.tags=[]; //阅读图书时所添加的标签
    fileInfo.notes=[]; //阅读图书时的笔记
    导出
    //导出
    export: function() {
    var self = this;
    //this.editFile为当前正在操作的文件,可在用户点击右键时获取
    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的数据绑定机制,会自动删除相应图书。
    重命名
    重命名跟删除机制一样,只需要修改图书信息中的name即可。

总结:

书架的设计,主要包括图书的显示,图书的上传,图书的存储和图书的管理。

  • 使用VUE可以很方便的使界面显示和数据进行同步。
  • 图书上传时使用MD5来标记图书,可以方便索引图书。
  • 使用localForage可以很方便的对图书进行存储。
  • 使用context.js来实现右键菜单,对图书进行管理。

你可能感兴趣的:(打造web版epub阅读器(书架设计))