小说合并插件第六篇 这一篇我们即将完成我们插件的第一个版本, 用这个插件可以把小说下载到本地。
上次我们编写了几个重要的事件处理函数, 接下来我们继续编写剩下的CHAPTER_DONE, CONTENT_DONE和NOVEL_DONE三个事件。
继续添加几个属性。
function Novel ( ){ const EVT_CHAPTER_MORE = "chapterMore" ; const EVT_CHAPTER_DONE = "chapterDone" ; const EVT_CONTENT_MORE = "contentMore" ; const EVT_CONTENT_DONE = "contentDone" ; const EVT_NOVEL_DONE = "novelDone" this .chapters = new Map (); this .escapeChapters = new Array (); this .chapterCount = -1 ; this .currentChapterCount = 0 ; ........
所有章节获取成功 需要说明的是我们在currentChapterCount里保存已经下载完成的章节总数, 在chapterCount里保存全部章节的总数。
所以chapterDone事件处理函数特别简单, 就一行, 不过前提是修改chapter_more函数, 需要把章节循环里的break去掉, 我在代码里特意注释过, 此外我们需要添加触发chapter_done事件的代码。。
this .main .addEventListener (EVT_CHAPTER_MORE , (e ) => { ......... if (url) { this .main .dispatchEvent (new CustomEvent (EVT_CHAPTER_MORE , {detail : url})); } else { this .main .dispatchEvent (new CustomEvent (EVT_CHAPTER_DONE , {detail : chapterNum})); } }) ............. });
在看chapter_done事件处理函数。
this .main .addEventListener (EVT_CHAPTER_DONE , (e ) => { this .chapterCount = e.detail ; });
把最后获取的章节序号付给chapterCount就可以了, 反正一本小说有300章那么这本小说的章节总数就是300, 当然在某些情况下这样做肯定出现问题, 不过先不管他。
下载缺失的章节 上次没写完的content_done函数, 注意最前面新增了一行内容, 此外这里判断是否开始下载缺失章节, 是否全部下载完成。
this .main .addEventListener (EVT_CONTENT_DONE , (e ) => { this .currentChapterCount += 1 ; ........ this .updateTable ({title, pageCount, summary}) if (this .escapeChapters .length !== 0 && this .currentChapterCount === this .chapters .size ) { this .downloadEscape (); } if (this .currentChapterCount === this .chapterCount ) { this .main .dispatchEvent (new Event (EVT_NOVEL_DONE )); } });
接下来是下载缺失章节的函数定义
this .downloadEscape = () => { while (this .escapeChapters .length > 0 ) { let esc = this .escapeChapters .shift (); let url = this .chapters .get (esc.chapterNum - 1 )?.nextChapterURL ; this .main .dispatchEvent (new CustomEvent (EVT_CONTENT_MORE , {detail : {url : url, chapterNum : esc.chapterNum }})); } }
只要在escapeChapters里有元素就拿出来触发CONTENT_MORE事件就可以了, 因为我们前面已经在上一张里存放了他们的URL。
生成全本小说生成下载接口 最后所有章节都下载完毕后触发如下事件
this .main .addEventListener (EVT_NOVEL_DONE , () => { let downloadLink = this .makeFull (); this .downloadButton .innerHTML = "下载全本" ; this .downloadButton .addEventListener ("click" , () => downloadLink.click ()); });
在看看怎么生成全本小说, 怎么生成下载地址的。
this .makeFull = () => { let chapterNums = Array .from (this .chapters .keys ()).sort ((x, y ) => x - y); let novelContent = new Array (); for (let num of chapterNums) { let chapter = this .chapters .get (num); let text = `\n${chapter.title} \n${chapter.pages.join("\n\n" )} \n\n` ; novelContent.push (text); } let blob = new Blob (novelContent); let url = URL .createObjectURL (blob); let a = document .createElement ("a" ); a.href = url; a.download = `${document .title.split("_" )[0 ]} .txt` ; return a; }
到此为止我们可算是舒一口气了, 不过这是测试版, 还有很多问题, 比如下载一些小说比较好使, 换成其他小说可能就歇菜了, 所以最后一篇我们要完善这个插件, 让他相对良好稳定的运行。
我发现的一些问题列举如下: