相对于分享代码更希望与你们分享编程思路,欢迎评论区讨论
最近在追几部小说,大家都知道手机浏览器大部分都会有小说模式,奈何手机没电想让他安静地充电,但是电脑上的各大小说网的阅读模式其实都不是很友好,或者充斥着大量的广告,但是本着懒得找的原则,手写了个插件来改善自己的阅读体验。
本代码只针对提供网站有效,其他网站可能需要凭借自己的知识修改部分正则表达式和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();
}