JavaScript实现小说阅读插件

    技术2022-07-10  130

    相对于分享代码更希望与你们分享编程思路,欢迎评论区讨论

    最近在追几部小说,大家都知道手机浏览器大部分都会有小说模式,奈何手机没电想让他安静地充电,但是电脑上的各大小说网的阅读模式其实都不是很友好,或者充斥着大量的广告,但是本着懒得找的原则,手写了个插件来改善自己的阅读体验。

    本代码只针对提供网站有效,其他网站可能需要凭借自己的知识修改部分正则表达式和DOM名称才可使用

    流程构思

    获取当前页面的标题、下一页链接和内容存入变量重构页面样式写入刚才保存的数据监听页面滚动事件获取下一页dom正则匹配标题、下一页链接和内容追加补充到第一次渲染出来的正文下方循环起来RUA~

    实现

    一、 随意打开其中的一篇小说,使用开发者工具确认章节标题、内容和下一页链接 标题 内容 下一章 变量赋值

    //下一页链接 var nextHref = $(".bottem a").eq(3).attr("href"); //标题 var bookname = $(".bookname h1").text(); //正文 var content = $("#content").html();

    页面元素清空同时创建自定义样式

    $("body").html("<div id=\"content\"></div>"); $("#content").css({ "width":"80%", "margin":"20px auto" });

    定义渲染文章方法

    function getHtml(){ //获取当前已有内容 var html = $("#content").html(); //追加标题 html+=`<br/><h1>${bookname}</h1>`; //追加正文 html+=`<div style="font-size: 30px;">${content}</div><br/><br/><br/>`; //渲染至html上 $("#content").html(html); //设置标题样式 $("h1").css({ 'font-size': '50px', 'text-align': 'center' }); }

    监听滚动事件

    //获取下一页状态(防止重复拉取) var type = true; $(window).scroll(function() { //页面高度 var pageHeight = document.body.scrollHeight //滚动条高度(多浏览器兼容) var scrollHeight = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; //如果当前没有获取过当前章的下一页, //且高度达到页面的4/5的位置,就是快看完了。 //获取下一章的html, //因为是html所以采用get的方式获取,且返回的是html的字符串 if(scrollHeight/pageHeight>0.8&&type){ type = false;//改变获取状态为不可获取 $.get(nextHref,function(res){ initContent(text)//从字符串中获取自己需要的数据,下文中解释 type = true;//改变获取状态为可获取 }); } })

    字符串处理函数

    分析了一下他的页面发现标题、下一页链接参数其实都在页面中存在的,于是根据下图匹配相应的正则 而正文部分依然可以从页面中一个名为content的ID中使用正则匹配 function initContent(text){ var nextregOne = /(?<=(var index_page = "))[a-z:/._0-9]+/i var nextregTwo = /(?<=(var next_page = "))[0-9]*.html/i; var contentreg = /(<div id="content"[>]*>)([\s\S]*?)(<\/div[>]*>?)/i var titlereg = /(?<=(var readtitle = "))[\u4e00-\u9fa5 0-9]*/i; //章节名 bookname = titlereg.exec(text)[0]; //下一章链接 两个变量拼接而成 nextHref = nextregOne.exec(text)[0]; nextHref += nextregTwo.exec(text)[0]; //正文 content = contentreg.exec(text)[2]; //调用追加html方法追加内容 getHtml(); }

    自动滚动起来是不是会更加方便一些呢 创建自动滚动方法

    var scrollGo = setInterval(function(){ //页面高度 var pageHeight = document.body.scrollHeight //滚动条高度 var scrollHeight = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; if(pageHeight-scrollHeight>0){ window.scrollTo(0,scrollHeight+1); } },10);//速度可调

    至此基本功能已完结,直接扔到控制台即可快乐食用 全部代码见文末

    高级功能

    完成基本控制

    点击美化,进入自定义小说模式点击滚动,自动向下滚动点击停止滚动,停止滚动点击加速滚动速度加快点击减速滚动速度减慢显示当前章节名称和当前页面网址(便于储存进度)

    界面管理样式

    创建tools工具栏

    $("body").append(`<ul id="tools"> <li id="title">标题</li> <li id="into">美化</li> <li id="begin">滚动</li> <li id="up">加速</li> <li id="down">减速</li> </ul>`);

    设置样式

    function creatCss (argument) { $("body").css.backgroundColor="#E9FAFF"; $("#content").css({ "width":"80%", "margin":"20px auto" }); $("#tools").css({ "position": "fixed", "right": "0px", "top": "0px", "width": "10%" }); $("#tools>li").css({ "list-style": "none", "font-size": "20px", "margin": "5px 0px", "border": "3px solid #eeeee5", "border-radius": "10px", "text-align": "center", "cursor": "pointer" }); }

    封装四个事件

    //开启滚动 function startScroll(){ clearInterval(scrollGo); scrollGo = setInterval(function(){ //页面高度 var pageHeight = document.body.scrollHeight //滚动条高度 var scrollHeight = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; if(pageHeight-scrollHeight>0){ window.scrollTo(0,scrollHeight+1); } },speed); } function initTools () { //美化 $("#into").click(function() { if( $("#into").text()="美化"){ var str = `<div id="content"></div> <ul id="tools"> <li id="title">标题</li> <li id="into">取消美化</li> <li id="begin">滚动</li> <li id="up">加速</li> <li id="down">减速</li> </ul>`; $("body").html(str); function scrolling(){}; creatCss(); getHtml(); initTools (); }else{ window.location.href = url; } }); //滚动 $("#begin").click(function() { if($("#begin").text()=="滚动"){ $("#begin").text("停止滚动") startScroll(); }else{ $("#begin").text("滚动") clearInterval(scrollGo); } }); //加速 $("#up").click(function() { if(scrollGo!=0){ speed = speed>20?(speed-20):(speed>2?(speed-2):speed); startScroll(); }else{ alert("当前未开启滚动"); } }); //减速 $("#down").click(function() { if(scrollGo!=0){ speed = speed+20; startScroll(); }else{ alert("当前未开启滚动"); } }); }

    修改追加文本时的逻辑

    //判断是不是最新的标题和内容 var nnew = false; //获取下一页状态 var type = true; //监听滚动条滚动 $(window).scroll(function() { //页面高度 var pageHeight = document.body.scrollHeight //滚动条高度 var scrollHeight = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; if(pageHeight-scrollHeight<2000&&type&&!nnew&&pageHeight-scrollHeight>=650){ type = false; $.get(nextHref,function(res){ initContent(res); type = true; nnew = true; }); } //上面先获取存入变量看完后再追加 if(pageHeight-scrollHeight<650&&nnew){ nnew=false; getHtml(); } })

    总结

    里面遇到了几个难点,追加文本加载的时机、如何防止多次拉取下一页,说是难点不是因为它写的难,而是有多种实现方法,需要找到让人看起来最舒服的方法比较难。 在这里其实偷了个小懒,用了网站自带的JQuery,以后面的这种高级优化之后其实更实用于油猴插件TamperMonkey,这样可以在网站加载时自动注入JS,省了很多操作,同时可以在里面直接引入JQuery,让我们可以在即使没有JQuery的网站也可以方便食用。

    油猴插件配置(不知道的自行百度)

    有更好的优化可以在评论区回复,么么哒~

    高级功能版本,点击自取

    简单版全部js代码

    // http://www.biquge.info/54_54083/7205717.html //标题 var bookname = $(".bookname h1").text(); //正文 var content = $("#content").html(); //下一页链接 var nextHref = $(".bottem a").eq(3).attr("href"); $("body").html("<div id=\"content\"></div>"); $("#content").css({ "width":"80%", "margin":"20px auto" }); //获取下一页状态 var type = true; getHtml(); var scrollGo = setInterval(function(){ //页面高度 var pageHeight = document.body.scrollHeight //滚动条高度 var scrollHeight = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; if(pageHeight-scrollHeight>0){ window.scrollTo(0,scrollHeight+1); } },10); //监听滚动条滚动 $(window).scroll(function() { //页面高度 var pageHeight = document.body.scrollHeight //滚动条高度 var scrollHeight = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; if(scrollHeight/pageHeight>0.8&&type){ type = false; $.get(nextHref,function(res){ initContent(res); type = true; }); } }) function getHtml(){ var html = $("#content").html(); html+=`<br/><h1>${bookname}</h1>`; html+=`<div style="font-size: 30px;">${content}</div><br/><br/><br/>`; $("#content").html(html); $("h1").css({ 'font-size': '50px', 'text-align': 'center' }); } function initContent(text){ var nextregOne = /(?<=(var index_page = "))[a-z:/._0-9]+/i var nextregTwo = /(?<=(var next_page = "))[0-9]*.html/i; var contentreg = /(<div id="content"[>]*>)([\s\S]*?)(<\/div[>]*>?)/i var titlereg = /(?<=(var readtitle = "))[\u4e00-\u9fa5 0-9]*/i; bookname = titlereg.exec(text)[0]; nextHref = nextregOne.exec(text)[0]; nextHref += nextregTwo.exec(text)[0]; content = contentreg.exec(text)[2]; getHtml(); }
    Processed: 0.016, SQL: 9