您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
修改自pppploi8的通用阅读器,为“真白萌”和“哔哩轻小说”提供阅读模式
当前为
// ==UserScript== // @name 轻小说阅读器 // @version 0.6.9 // @description 修改自pppploi8的通用阅读器,为“真白萌”和“哔哩轻小说”提供阅读模式 // @require https://update.gf.qytechs.cn/scripts/430421/1225835/%E4%B8%AD%E6%96%87%E7%B9%81%E4%BD%93%E7%AE%80%E4%BD%93%E8%BD%AC%E5%8C%96%E5%BA%93.js // @require https://update.gf.qytechs.cn/scripts/501723/1416523/font-ch-en.js // @author Y_C_Z // @match https://masiro.me/* // @match https://www.linovelib.com/* // @match https://www.bilinovel.com/* // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_registerMenuCommand // @grant unsafeWindow // @namespace https://gf.qytechs.cn/users/1335970 // ==/UserScript== (function() { var voices = []; var $ = function(selector){ return document.querySelector(selector); } var isSupportFontFamily = function (fontFamily) {//判断浏览器是否支持字体 if (typeof fontFamily != 'string') { return false; } var defaultFontFamily = 'Arial'; if (fontFamily.toLowerCase() == defaultFontFamily.toLowerCase()) { return true; } var defaultLetter = 'a'; var defaultFontSize = 100; // 使用该字体绘制的canvas var width = 100, height = 100; var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); canvas.width = width; canvas.height = height; // 全局一致的绘制设定 context.textAlign = 'center'; context.fillStyle = 'black'; context.textBaseline = 'middle'; var getFontData = function (fontFamily) { // 清除 context.clearRect(0, 0, width, height); // 设置字体 context.font = defaultFontSize + 'px ' + fontFamily + ', ' + defaultFontFamily; context.fillText(defaultLetter, width / 2, height / 2); var data = context.getImageData(0, 0, width, height).data; return [].slice.call(data).filter(function(value) { return value != 0; }); }; return getFontData(defaultFontFamily).join('') !== getFontData(fontFamily).join(''); }; GM_registerMenuCommand("设置", () => {//打开设置窗口 voices = getVoice();//第一次获取到的是空值 addDialog(); var arrFont = dataFont['windows'].concat(dataFont['OS X'], dataFont['office'], dataFont['open']);//获取浏览器可用字体 var fontFamilyoption = '<option value="">默认</option>'; arrFont.forEach(function (obj) { var fontFamily = obj.en; if (isSupportFontFamily(fontFamily)) { fontFamilyoption = fontFamilyoption + '<option value="'+ fontFamily +'">'+ obj.ch +'</option>'; } }); $("#fontSelect").innerHTML = fontFamilyoption; setTimeout(function() { var voiceSelect = document.getElementById('voiceSelect');//注入浏览器可用语音 voices = getVoice(); voices.forEach(function(voice) { var option = document.createElement('option'); option.value = voice.name; option.textContent = voice.name; voiceSelect.appendChild(option); }); if (GM_getValue('voice') != undefined){ $("#voiceSelect").value = GM_getValue('voice'); } },0); if (GM_getValue('ttsbutton') != undefined){ $("input[name='listen']").checked = GM_getValue('ttsbutton'); }else{ $("input[name='listen']").checked = true; } if (GM_getValue('totopbutton') != undefined){ $("input[name='scrollToTop']").checked = GM_getValue('totopbutton'); }else{ $("input[name='scrollToTop']").checked = true; } if (GM_getValue('fontFamily') != undefined){ $("#fontSelect").value = GM_getValue('fontFamily'); } const dialog = document.getElementById('myDialog'); dialog.showModal(); $('#closeDialog').onclick = function(){ if ($("input[name='listen']").checked == false) {//听书按钮 $("._er-tts") && ($("._er-tts").style.display = 'none'); GM_setValue('ttsbutton',false); }else{ $("._er-tts") && ($("._er-tts").style.display = 'block'); GM_setValue('ttsbutton',true); } if ($("input[name='scrollToTop']").checked == false) {//回到顶部按钮 $(".toTop") && ($(".toTop").style.display = 'none'); GM_setValue('totopbutton',false); }else{ $(".toTop") && ($(".toTop").style.display = 'block'); GM_setValue('totopbutton',true); } $("._er-title") && ($("._er-title").style.fontFamily = $("#fontSelect").value);//字体设置 $(".translator") && ($(".translator").style.fontFamily = $("#fontSelect").value); $("._er-content") && ($("._er-content").style.fontFamily = $("#fontSelect").value); GM_setValue('fontFamily',$("#fontSelect").value); GM_setValue('voice',$("#voiceSelect").value); dialog.remove(); } }); var blackList = {"masiro.me": true,"www.linovelib.com": true,"www.bilinovel.com": true}; if (location.host == "www.linovelib.com" || location.host == "www.bilinovel.com") {//尝试通过Cloudflare document.cookie = '__gpi_opt_out=1;'; document.cookie = 'cf_clearance=MHioFTJ3.DT_FjBcW1pGr7CzIvtm9Z29VMbB7d_TLgE-1721550888-1.0.1.1-7FSsg2Gpn9Y1x36Iq.eXyN60H2j.X2HXp_zPYRj17l0d4gzbOQw24ZSptWj.ktb8QTjubE5qO1Vz2YnTmPxAeQ;'; var start=1; var end=10; window.onload = function() { var t1 = setInterval(function(){ for (var n=0;n<10;++n){ $(".adsbygoogle") && $(".adsbygoogle").remove(); } $("#bottomads") && $("#bottomads").remove(); $("script[src*='adsbygoogle.js']") && $("script[src*='adsbygoogle.js']").remove(); $("script[src*='g.doubleclick.net']") && $("script[src*='g.doubleclick.net']").remove(); $("div[id*='google_ads']") && $("div[id*='google_ads']").remove(); $("div[data-google-query-id]") && $("div[data-google-query-id]").remove(); start++; if (start>=end ){ clearInterval(t1); } },1000); }; } // 通用解析模板 function parseContentAndTitle(){ var mainDom = null; function findMainDom(doms){ for(var i=0;i<doms.length;i++){ var dom = doms[i]; if (dom.classList.contains("nvl-content") || dom.classList.contains("read-content") || dom.classList.contains("bcontent")){//真白萌||哔哩轻小说PC||哔哩轻小说手机端 mainDom = dom; } findMainDom(dom.children||[]); } } findMainDom(document.body.children); var newTitle = ''; var title = document.title; var textToRemove1 = "真白萌 | "; var textToRemove2 = " _哔哩轻小说"; title = title.replace(textToRemove1, "").replace(textToRemove2, ""); switch (location.host){ case 'www.bilinovel.com': var atitle = document.querySelector('#atitle'); if (atitle) { newTitle = atitle.textContent; } else { newTitle = title; } break; default: // 选择“哔哩轻小说PC”中id为"mlfy_main_text"的元素 var mlfyMainTextElement = document.querySelector("#mlfy_main_text"); if (mlfyMainTextElement) { // 获取第一个<h1>元素 var firstH1Element = mlfyMainTextElement.querySelector("h1"); if (firstH1Element) { newTitle = firstH1Element.textContent; } else { newTitle = title; } } else { newTitle = title; } break; } if (mainDom){ return {content: mainDom.innerText, title: newTitle}; } } function parsePageUp(){ var reg, text; var href = ""; var i = 0; var as = document.querySelectorAll('a'); switch (location.host){ case 'www.bilinovel.com': return ReadParams.url_previous; break; default: reg = /上一章|上一篇|上一页|上一话|navigation-prev/; for(i=0;i<as.length;i++){ text = as[i].outerHTML; href = (as[i].attributes.href && as[i].attributes.href.value) || (as[i].dataset && as[i].dataset.url); if (text && reg.test(text.trim()) && href && href != "#" && href.indexOf("javascript:") !== 0){ return href; } } break; } } function parsePageDown(){ var reg, text; var href = ""; var i = 0; var as = document.querySelectorAll('a'); switch (location.host){ case 'www.bilinovel.com': return ReadParams.url_next; break; default: reg = /下一章|下一篇|下一页|下一话|navigation-next/; for(i=0;i<as.length;i++){ text = as[i].outerHTML; href = (as[i].attributes.href && as[i].attributes.href.value) || (as[i].dataset && as[i].dataset.url); if (text && reg.test(text.trim()) && href && href != "#" && href.indexOf("javascript:") !== 0){ return href; } } break; } } function parsePageIndex(){ var as = document.querySelectorAll('a'); var reg = /目录/; switch (location.host){ case 'www.bilinovel.com': return ReadParams.url_index; break; default: for(var i=0;i<as.length;i++){ var text = as[i].innerText; var href = as[i].attributes.href && as[i].attributes.href.value; if (text && text.length <= 10 && reg.test(text.trim()) && href && href != "#" && href.indexOf("javascript:") !== 0){ return href; } } break; } } var fontsize = parseInt(localStorage["_er_fontsize"] || 0); var padding = parseInt(localStorage["_er_padding"] || 10); var autoplay = false; if (localStorage['_er-autoplay'] === 'true'){ autoplay = true; } delete localStorage['_er-autoplay']; if (top.window !== window) return; // iframe内的网页不展示按钮,也不支持进入阅读模式 if (localStorage['_er-enable'] === 'true'){ localStorage['_er-enable'] = 'false'; checkAndCreateReader(true); } else if (blackList[location.host] == true){ // 创建阅读模式悬浮按钮 $('body').children[0].insertAdjacentHTML('beforeBegin', '<button id="_er-entryReadMode" style="' + ' position: fixed;' + ' right: 50px;' + ' bottom: 50px;' + ' background-color: rgba(255,255,255,0.5);' + ' backdrop-filter: blur(1px);' + ' border: 0px solid black;' + ' border-radius: 10px;' + ' box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);' + ' padding: 0 5px;' + ' height: 50px;' + ' overflow: auto;' + ' font-size: 14px;' + ' color: black;' + ' z-index: 201901272210;">进入阅读模式</button>'); $('#_er-entryReadMode').onclick = checkAndCreateReader; $('#_er-NotShowReadMode').onclick = function(){ localStorage['_er-disabled'] = 'true'; $('#_er-entryReadMode').remove(); $('#_er-NotShowReadMode').remove(); } } function checkAndCreateReader(notAlert){ // 通过调用通用模板尝试是否能够成功匹配到阅读内容 var content = parseContentAndTitle(); if (content && content.content){ content.pageup = parsePageUp(); content.pagedown = parsePageDown(); content.pageindex = parsePageIndex(); createReader(content); }else{ if (notAlert !== true){ alert('当前页面解析失败,无法进入阅读模式!'); } } } function setTheme(theme) { switch(theme) { case 'black': $('._er').style.backgroundColor = 'black'; $('._er-title').style.color = 'lightgrey'; $('._er-content').style.color = 'lightgrey'; $('.translator').style.color = 'lightgrey'; document.querySelectorAll('.buttonBottom').forEach(function(element) { element.style.color = 'lightgrey'; element.style.border = '0.5px solid lightgrey'; }); document.querySelectorAll('.buttonTop').forEach(function(element) { element.style.color = 'lightgrey'; }); document.querySelectorAll('.exit').forEach(function(element) { element.style.setProperty('box-shadow', '0px 4px 8px rgba(255, 255, 255, 0.2)'); element.style.setProperty('background-color', 'rgb(59,59,59)'); element.style.setProperty('color', 'white'); }); document.querySelectorAll('.toTop').forEach(function(element) { element.style.setProperty('box-shadow', '0px 4px 8px rgba(255, 255, 255, 0.2)'); element.style.setProperty('background-color', 'rgb(59,59,59)'); element.style.setProperty('color', 'white'); }); document.querySelectorAll('._er-tts').forEach(function(element) { element.style.setProperty('box-shadow', '0px 4px 8px rgba(255, 255, 255, 0.2)'); element.style.setProperty('background-color', 'rgb(59,59,59)'); element.style.setProperty('color', 'white'); }); break; case 'OliveDrab': $('._er').style.backgroundColor = '#D3E1D0'; $('._er-title').style.color = 'black'; $('._er-content').style.color = 'black'; break; case 'Khaki': $('._er').style.backgroundColor = '#F6F2E7'; $('._er-title').style.color = 'black'; $('._er-content').style.color = 'black'; break; case 'blue': $('._er').style.backgroundColor = '#D3E5F9'; $('._er-title').style.color = 'black'; $('._er-content').style.color = 'black'; break; case 'white': $('._er').style.backgroundColor = 'white'; $('._er-title').style.color = 'black'; $('._er-content').style.color = 'black'; $('.translator').style.color = 'black'; document.querySelectorAll('.buttonBottom').forEach(function(element) { element.style.border = '0.5px solid black'; element.style.color = 'black'; }); document.querySelectorAll('.buttonTop').forEach(function(element) { element.style.border = '1px solid black'; element.style.color = 'black'; }); document.querySelectorAll('.exit').forEach(function(element) { element.style.setProperty('box-shadow', '0px 4px 8px rgba(0, 0, 0, 0.2)'); element.style.setProperty('background-color', 'rgb(239,239,239)'); element.style.setProperty('color', 'black'); }); document.querySelectorAll('.toTop').forEach(function(element) { element.style.setProperty('box-shadow', '0px 4px 8px rgba(0, 0, 0, 0.2)'); element.style.setProperty('background-color', 'rgb(239,239,239)'); element.style.setProperty('color', 'black'); }); document.querySelectorAll('._er-tts').forEach(function(element) { element.style.setProperty('box-shadow', '0px 4px 8px rgba(0, 0, 0, 0.2)'); element.style.setProperty('background-color', 'rgb(239,239,239)'); element.style.setProperty('color', 'black'); }); break; } localStorage['_er-theme'] = theme; $('._er').dataset['theme'] = theme; } function setSimplemode(simplemode, contentHtml) {//简繁切换 switch(simplemode) { case 'simple': contentHtml = traditionalized(contentHtml); break; case 'traditional': contentHtml = simplized(contentHtml); break; } localStorage['_er-simplemode'] = simplemode; $('._er').dataset['simplemode'] = simplemode; return contentHtml; } // 创建阅读器 function createReader(content){ document.documentElement.style.overflow = 'hidden'; $('#_er-entryReadMode') && $('#_er-entryReadMode').remove(); $('#_er-NotShowReadMode') && $('#_er-NotShowReadMode').remove(); addClassAndDom(); if (window.SpeechSynthesisUtterance){ $('#_er-tts').style.display = 'block'; } if (GM_getValue('ttsbutton')==0){//本地缓存的设置 document.querySelector('._er-tts').style.display = 'none'; } if (GM_getValue('totopbutton')==0){ document.querySelector('.toTop').style.display = 'none'; } $("._er-title").style.fontFamily = GM_getValue('fontFamily',); $(".translator").style.fontFamily = GM_getValue('fontFamily',); $("._er-content").style.fontFamily = GM_getValue('fontFamily',); if (hasCSSRule('#TextContent p:last-of-type')||hasCSSRule('.bcontent p:last-of-type')) {//针对哔哩轻小说最后一段转码的情况 addCSSRule('._er-content p:last-of-type', 'font-family: "read" !important;'); } if (localStorage['_er-theme']) { setTheme(localStorage['_er-theme']); } $('._er-title').innerText = content.title; var contentArr = content.content.split('\n'); var contentHtml = ''; for(var i=0;i<contentArr.length;i++){ var line = contentArr[i]; if (line){ contentHtml += '<p style="text-indent: 2em; margin-bottom: 1em;">' + line + '</p>'; } } $('._er-content').innerHTML = contentHtml; if (location.host == "masiro.me") { var translatorInfoElm = document.getElementById('translator-info-elm'); var translator = translatorInfoElm.textContent.trim(); $('.translator').innerHTML = translator; $('.translator').style.display = 'block'; } if (localStorage['_er-simplemode']) { $('._er-content').innerHTML=setSimplemode(localStorage['_er-simplemode'],$('._er-content').innerHTML); $('._er-title').innerHTML=setSimplemode(localStorage['_er-simplemode'],$('._er-title').innerHTML); $('.translator').innerHTML=setSimplemode(localStorage['_er-simplemode'],$('.translator').innerHTML); } var spanNodes = document.querySelectorAll('._er-content p'); for(i=0;i<spanNodes.length;i++){ spanNodes[i].onclick = function(){ if ($('#_er-tts').innerText == '听书'){ for(var j=0;j<spanNodes.length;j++){ spanNodes[j].classList.remove('_er-none'); spanNodes[j].classList.remove('_er-current'); } this.classList.add('_er-none'); } } } // 挂接键盘事件,实现键盘上下左右切换阅读功能 $('body').onkeydown = function(e){ e.stopPropagation(); switch(e.keyCode || e.which || e.charCode){ case 38: // up if (e.ctrlKey) { $('._er').scrollTop = $('._er').scrollTop - (document.documentElement.clientHeight - 24) } else { toPrevReadPos(); updateReadPos(); } break; case 40: // down if (e.ctrlKey) { $('._er').scrollTop = $('._er').scrollTop + (document.documentElement.clientHeight - 24); } else { toNextReadPos(); updateReadPos(); } break; case 37: // left if (e.ctrlKey) { toPrevPage(); } else { $('._er').scrollTop = $('._er').scrollTop - (document.documentElement.clientHeight - 24) } break; case 39: // right if (e.ctrlKey) { toNextPage() } else { $('._er').scrollTop = $('._er').scrollTop + (document.documentElement.clientHeight - 24); } break; default: return true; } return false; function toPrevPage(){ if (content.pageup){ localStorage['_er-enable'] = 'true'; location.href = content.pageup; }else{ alert('很抱歉,没有匹配到上一页!'); } } function toNextPage(){ if (content.pagedown){ localStorage['_er-enable'] = 'true'; location.href = content.pagedown; }else{ alert('很抱歉,没有匹配到下一页!'); } } }; $('._er-content').onclick = function(e){ // 适用于墨水屏的左右点击无动画翻页 var x = e.pageX; var width = document.documentElement.clientWidth; if (x <= width*0.1){ // 前翻一页 $('._er').scrollTop = $('._er').scrollTop - (document.documentElement.clientHeight - 24) }else if(x >= width*0.9){ // 后翻一页 $('._er').scrollTop = $('._er').scrollTop + (document.documentElement.clientHeight - 24); } } var erpageindex = document.querySelectorAll('#_er-pageindex'); for (i = 0; i < erpageindex.length; i++) { erpageindex[i].onclick = function() { if (content.pageindex) { location.href = content.pageindex; } else { alert('很抱歉,没有匹配到目录!'); } }; } $('#_er-switch-theme').onclick = function(){ var current = $('._er').dataset['theme'] || 'white'; var themeList = ['white', 'Khaki', 'blue', 'OliveDrab', 'black']; var index = themeList.indexOf(current); if (index === -1) index = 0; index++; if (index >= themeList.length) { index = 0; } setTheme(themeList[index]); } var pressTimer;//定时器 var touchpressTimer;//触摸定时器 var isLongPress = false; // 长按标记 $('#_er-simplemode').addEventListener('touchstart', function() {//触摸屏 touchpressTimer = setTimeout(function() { isLongPress = true; localStorage['_er-simplemode'] = ''; $('._er-content').innerHTML = contentHtml; $('._er-title').innerText = content.title; if (location.host == "masiro.me") { $('.translator').innerHTML = translator; } }, 500); }); $('#_er-simplemode').addEventListener('touchend', function() { clearTimeout(touchpressTimer); }); $('#_er-simplemode').addEventListener('mousedown', function() {//PC pressTimer = setTimeout(function() { isLongPress = true; localStorage['_er-simplemode'] = ''; $('._er-content').innerHTML = contentHtml; $('._er-title').innerText = content.title; if (location.host == "masiro.me") { $('.translator').innerHTML = translator; } }, 500); }); $('#_er-simplemode').addEventListener('mouseup', function() { clearTimeout(pressTimer); if (!isLongPress) { var current = $('._er').dataset['simplemode'] || 'traditional'; var simplemodeList = ['simple', 'traditional']; var index = simplemodeList.indexOf(current); if (index === -1) index = 0; index++; if (index >= simplemodeList.length) { index = 0; } $('._er-content').innerHTML=setSimplemode(simplemodeList[index],$('._er-content').innerHTML); $('.translator').innerHTML=setSimplemode(simplemodeList[index],$('.translator').innerHTML); $('._er-title').innerHTML=setSimplemode(simplemodeList[index],$('._er-title').innerHTML); } else { $('._er').dataset['simplemode'] = ''; current = $('._er').dataset['simplemode'] || 'traditional'; simplemodeList = ['simple', 'traditional']; index = simplemodeList.indexOf(current);; } isLongPress = false; }); var erpageup = document.querySelectorAll('#_er-pageup'); for (i = 0; i < erpageup.length; i++) { erpageup[i].onclick = function() { if (content.pageup) { localStorage['_er-enable'] = 'true'; location.href = content.pageup; } else { alert('很抱歉,没有匹配到上一页!'); } }; } var erpagedown = document.querySelectorAll('#_er-pagedown'); for (i = 0; i < erpagedown.length; i++) { erpagedown[i].onclick = function() { if (content.pagedown) { localStorage['_er-enable'] = 'true'; location.href = content.pagedown; } else { alert('很抱歉,没有匹配到下一页!'); } }; } $('#_er-pagedown').dataset['nexturl'] = content.pagedown; setFontSize(); setPadding(); // 按钮事件处理 $('#_er-close').onclick = removeDom; $('#_er-font-plus').onclick = function(){ fontsize += 2; setFontSize(); }; $('#_er-font-minus').onclick = function(){ fontsize -= 2; setFontSize(); }; $('#_er-border').onclick= function() { padding = padding == 10 ? 5 : 10; setPadding(); } $('#_er-toTop').onclick= function() { document.querySelector('._er').scrollTop = 0; } $('#_er-tts').onclick = function(){ if (this.dataset['pause'] === 'true'){ // 开始播放 this.innerText = '停止'; this.dataset['pause'] = 'false'; playNextText(); }else{ this.innerText = '听书'; this.dataset['pause'] = 'true'; } }; if (autoplay){ $('#_er-tts').innerText = '停止'; $('#_er-tts').dataset['pause'] = 'false'; playNextText(); }else{ $('#_er-tts').dataset['pause'] = 'true'; } } // 听书功能 function playNextText(){ updateReadPos(); var current = $('._er-current'); var ernone = $('._er-none'); var playText = ''; if (current){ playText = current.innerText; }else if(ernone) { playText = ernone.innerText; ernone.classList.add('_er-current'); ernone.classList.remove('_er-none'); }else{ playText = $('._er-title').innerText; } if (playText){ var utterThis = new SpeechSynthesisUtterance(); utterThis.text = playText; if (GM_getValue('voice') != undefined) { var selectedVoiceName = GM_getValue('voice'); voices = getVoice(); var selectedVoice = voices.find(function(voice) { return voice.name === selectedVoiceName; }); if (selectedVoice) { utterThis.voice = selectedVoice; } } utterThis.onerror = function(){ $('#_er-tts').dataset['pause'] = 'true'; alert("TTS语音转换文字出现异常,听书已停止运行!"); }; utterThis.onend = function(){ toNextReadPos(); if (!$('._er-current')){ var nextUrl = $('#_er-pagedown').dataset['nexturl']; console.log(nextUrl); if (nextUrl){ localStorage['_er-autoplay'] = 'true'; localStorage['_er-enable'] = 'true'; location.href = nextUrl; } return; } if ($('#_er-tts').dataset['pause'] === 'false'){ playNextText(); } }; speechSynthesis.speak(utterThis); }else{ toNextReadPos(); playNextText(); } } function toNextReadPos(){ var current = $('._er-current'); var nextSpan = null; if (current){ nextSpan = current.nextElementSibling; while(nextSpan && nextSpan.nodeName !== 'P'){ nextSpan = nextSpan.nextElementSibling; } }else{ nextSpan = $('._er-content p'); } if (current) current.classList.remove('_er-current'); if (nextSpan) nextSpan.classList.add('_er-current'); } function toPrevReadPos(){ var current = $('._er-current'); var prevSpan = null; if (current){ prevSpan = current.previousElementSibling; while(prevSpan && prevSpan.nodeName !== 'P'){ prevSpan = prevSpan.previousElementSibling; } } if (current) current.classList.remove('_er-current'); if (prevSpan) prevSpan.classList.add('_er-current'); } function updateReadPos(){ if ($('._er-current')) $('._er').scrollTop = $('._er-current').offsetTop - (document.documentElement.clientHeight / 2); } function getVoice() {//获取可用语音 voices = speechSynthesis.getVoices(); var chineseVoices = voices.filter(function(voice) { return voice.lang.startsWith('zh'); }); return chineseVoices; } function setFontSize(){ localStorage["_er_fontsize"] = fontsize; $('._er-title').style.fontSize = (20+fontsize) + 'px'; $('._er-title').style.lineHeight = ((20+fontsize)*1.5) + 'px'; $('._er-content').style.fontSize = (14+fontsize) + 'px'; $('._er-content').style.lineHeight = ((14+fontsize)*1.5) + 'px'; $('.translator').style.fontSize = (10+fontsize) + 'px'; $('.translator').style.lineHeight = ((10+fontsize)*1.5) + 'px'; } function setPadding() { localStorage["_er_padding"] = padding; $('._er-content').style.padding = '10px ' + padding + '%'; } function hasCSSRule(selector) { // 获取所有的样式表 const styleSheets = document.styleSheets; for (let i = 0; i < styleSheets.length; i++) { const rules = styleSheets[i].cssRules || styleSheets[i].rules; // 兼容不同浏览器 if (rules) { for (let j = 0; j < rules.length; j++) { if (rules[j].selectorText === selector) { return true; } } } } return false; } function addCSSRule(selector, styles) { const styleSheet = document.styleSheets[0]; const rule = `${selector} { ${styles} }`; styleSheet.insertRule(rule, styleSheet.cssRules.length); } var oldOverflow = ''; var oldOnKeyDown = $('body').onkeydown; function removeDom(){ var erScrollTop = document.querySelector('._er').scrollTop; var erScrollHeight = document.querySelector('._er').scrollHeight; var erClientHeight = document.documentElement.clientHeight; var scrollPercentage = (erScrollTop / (erScrollHeight - erClientHeight)) * 100; $('._er').remove(); document.documentElement.style.overflow = 'auto'; $('body').style.overflow = oldOverflow; $('body').onkeydown = oldOnKeyDown; $('body').children[0].insertAdjacentHTML('beforeBegin', '<button id="_er-entryReadMode" style="' + ' position: fixed;' + ' right: 50px;' + ' bottom: 50px;' + ' background-color: rgba(255,255,255,0.5);' + ' backdrop-filter: blur(1px);' + ' border: 0px solid black;' + ' border-radius: 10px;' + ' box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);' + ' padding: 0 5px;' + ' height: 50px;' + ' overflow: auto;' + ' font-size: 14px;' + ' color: black;' + ' z-index: 201901272210;">进入阅读模式</button>'); $('#_er-entryReadMode').onclick = checkAndCreateReader; setTimeout(function() { var restoredScrollTop = ((erScrollHeight - erClientHeight) * (scrollPercentage / 100)); window.scrollTo(0, restoredScrollTop); }, 0); } function addClassAndDom(){ var originalScrollTop = window.pageYOffset; var originalScrollHeight = document.documentElement.scrollHeight; var originalClientHeight = document.documentElement.clientHeight; var scrollPercentage = (originalScrollTop / (originalScrollHeight - originalClientHeight)) * 100; oldOverflow = $('body').style.overflow; $('body').style.overflow = 'hidden'; $('body').children[0].insertAdjacentHTML('beforeBegin', '<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"><div class="_er">' + ' <button type="button" id="_er-tts" class="_er-tts">听书</button>' + ' <div class="_er-tools" style="margin-top:0;">' + ' <button type="button" id="_er-pageup" class="buttonBottom" style="width:50%; margin: 0;">上一页</button>' + ' <button type="button" id="_er-pageindex" class="buttonBottom" style="padding: 5px 40px; margin: 0;">目录</button>' + ' <button type="button" id="_er-pagedown" class="buttonBottom" style="width:50%; margin: 0;">下一页</button>' + ' </div>' + ' <div class="_er-tools">' + ' <button type="button" id="_er-switch-theme" class="buttonTop">切换主题</button>' + ' <button type="button" id="_er-font-plus" class="buttonTop">字号+</button>' + ' <button type="button" id="_er-font-minus" class="buttonTop">字号-</button>' + ' <button type="button" id="_er-border" class="buttonTop">边距</button>' + ' <button type="button" id="_er-simplemode" class="buttonTop">简 / 繁</button>' + ' <button type="button" id="_er-toTop" class="toTop">' + ' <span class="first-line">回到</span>' + ' <span class="second-line">顶部</span>' + ' </button>' + ' <button type="button" id="_er-close" class="exit">退出</button>' + ' </div>' + ' <div class="_er-title"></div>' + ' <div class="translator"></div>' + ' <div class="_er-content">' + ' </div>' + ' <div class="_er-tools">' + ' <button type="button" id="_er-pageup" class="buttonBottom" style="width: 50%;">上一页</button>' + ' <button type="button" id="_er-pageindex" class="buttonBottom" style="padding: 5px 40px;">目录</button>' + ' <button type="button" id="_er-pagedown" class="buttonBottom" style="width: 50%;">下一页</button>' + ' </div>' + '</div>'); if (!document.querySelector('#_er-styles')) { $('body').children[0].insertAdjacentHTML('beforeBegin', '<style id="_er-styles">' + '* {' + '-webkit-user-select: none; /* Safari */' + '-moz-user-select: none; /* Firefox */' + '-ms-user-select: none; /* IE 10+ */' + 'user-select: none; /* 标准语法 */' + '}' + '._er{' + ' position: fixed;' + ' left: 0;' + ' right: 0;' + ' top: 0;' + ' bottom: 0;' + ' overflow: auto;' + ' background-color: white;' + ' z-index: 201901272211;' + '}' + '._er-title{' + ' text-align: center;' + ' font-size: 20px;' + ' line-height: 30px;' + ' font-weight: 900;' + ' padding: 10px 10%;' + ' color: black;' + '}' + '.translator{' + ' text-align: center;' + ' font-size: 10px;' + ' line-height: 15px;' + ' padding: 0 10% 10px;' + ' color: black;' + ' display: none;' + '}' + '._er-content{' + ' padding: 10px 10%;' + ' font-size: 14px;' + ' line-height: 21px;' + ' color: black;' + '}' + '._er-tools{' + ' margin-top: 10px;' + ' margin-bottom: 10px;' + ' text-align: center;' + ' display: flex;' + ' justify-content: center;' + '}' + '.buttonTop{' + ' cursor: pointer;' + ' color: black;' + ' background-color: rgba(255,255,255,0.5);' + ' border: 1px solid black;' + ' padding: 5px 8px;' + ' margin: 8px 5px 0;' + ' border-radius: 10px;' + ' white-space: nowrap;' + '}' + '.buttonTop:hover{' + ' background-color: rgba(255,255,255,0.9);' + '}' + '.buttonTop:active{' + ' background-color: rgba(255,255,255,0.7);' + '}' + '.buttonBottom{' + ' cursor: pointer;' + ' color: black;' + ' background-color: rgba(255,255,255,0);' + ' border: 0.5px solid black;' + ' padding: 5px 50px;' + ' margin: 20px 0 80px;' + ' font-size: 20px;' + ' white-space: nowrap;' + '}' + '.buttonBottom:hover{' + ' background-color: rgba(255,255,255,0.8);' + '}' + '.buttonBottom:active{' + ' background-color: rgba(255,255,255,0.5);' + '}' + '.toTop{' + ' width: 50px;' + ' height: 50px;' + ' position: fixed;' + ' right: 15px;' + ' bottom: 80px;' + ' z-index: 201901272212;' + ' color: black;' + ' border: 0px solid black;' + ' box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);' + ' opacity: 0.8;' + ' cursor: pointer;' + ' border-radius: 25px;' + ' font-size: 14px;' + ' padding: 0;' + ' display: flex;' + ' flex-direction: column;' + ' align-items: center;' + ' justify-content: center;' + '}' + '.first-line,' + '.second-line {' + ' display: inline-block;' + ' white-space: nowrap;' + '}' + '.exit{' + ' width: 50px;' + ' height: 50px;' + ' position: fixed;' + ' right: 15px;' + ' bottom: 15px;' + ' z-index: 201901272212;' + ' color: black;' + ' border: 0px solid black;' + ' box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);' + ' opacity: 0.8;' + ' cursor: pointer;' + ' border-radius: 25px;' + ' font-size: 14px;' + ' padding: 0;' + ' white-space: nowrap;' + '}' + '._er-tts {' + ' width: 50px;' + ' height: 50px;' + ' position: fixed;' + ' left: 15px;' + ' bottom: 15px;' + ' z-index: 201901272212;' + ' color: black;' + ' border: 0px solid black;' + ' box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);' + ' opacity: 0.8;' + ' cursor: pointer;' + ' border-radius: 25px;' + ' font-size: 14px;' + ' padding: 0;' + ' white-space: nowrap;' + ' display: none;' + '}' + '._er-current{' + ' background-color: yellow;' + ' color: black;' + '}' + '._er-none{' + '}' + '</style>'); } setTimeout(function() { var restoredScrollTop = ((originalScrollHeight - originalClientHeight) * (scrollPercentage / 100)); document.querySelector('._er').scrollTop = restoredScrollTop; }, 0); } function addDialog(){ if (!document.querySelector('#myDialog')) { $('body').children[0].insertAdjacentHTML('beforeBegin', '<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"><dialog id="myDialog">' + ' <h2>设置</h2>' + ' <div class="checkbox-container">' + ' <div class="checkbox">' + ' <label>' + ' <input type="checkbox" name="scrollToTop" value="1"> 回到顶部按钮' + ' </label>' + ' </div>' + ' <div class="checkbox">' + ' <label>' + ' <input type="checkbox" name="listen" value="1"> 听书按钮' + ' </label>' + ' </div>' + ' <div class="font-selector">' + ' <label for="fontSelect">选择字体样式:</label>' + ' <select id="fontSelect">' + ' </select>' + ' </div>' + ' <div class="voice-selector">' + ' <label for="voiceSelect">选择听书语音:</label>' + ' <select id="voiceSelect">' + ' </select>' + ' </div>' + ' </div>' + ' <button id="closeDialog">确定</button>' + '</dialog>'); } if (!document.querySelector('#dialog-styles')) { $('body').children[0].insertAdjacentHTML('beforeBegin', '<style id="dialog-styles">' + '#myDialog {' + ' width: 300px;' + ' padding: 20px;' + ' margin: 0;' + ' background-color: #f2f2f2;' + ' border: 1px solid #ccc;' + ' border-radius: 10px;' + ' box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);' + ' font-family: Arial, sans-serif;' + ' display: flex;' + ' flex-direction: column;' + ' align-items: center;' + ' position: fixed;' + ' top: 50%;' + ' left: 50%;' + ' transform: translate(-50%, -50%);' + '}' + '#myDialog::backdrop {' + ' background: rgba(30,30,30,0.2);' + ' backdrop-filter: blur(3px);' + '}' + '#myDialog h2 {' + ' margin-top: 0;' + ' font-size: 24px;' + ' font-weight: bold;' + ' margin-bottom: 10px;' + '}' + '.checkbox-container {' + ' display: flex;' + ' flex-direction: column;' + ' align-items: flex-start;' + '}' + '.checkbox {' + ' margin-bottom: 10px;' + '}' + '.font-selector,.voice-selector {' + ' margin-bottom: 20px;' + ' display: block;' + '}' + '.font-selector label,.voice-selector label {' + ' font-size: 16px;' + ' font-weight: bold;' + ' margin-right: 10px;' + ' color: #333;' + '}' + '.font-selector select,.voice-selector select {' + ' font-size: 16px;' + ' padding: 5px;' + ' border: 1px solid #ccc;' + ' border-radius: 4px;' + ' background-color: #fff;' + ' cursor: pointer;' + ' transition: border-color 0.3s ease;' + ' color: black;' + ' max-width: 150px;' + '}' + '.font-selector select,.voice-selector select:hover {' + ' border-color: #007BFF;' + '}' + '.font-selector select,.voice-selector select:focus {' + ' outline: none;' + ' border-color: #007BFF;' + ' box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);' + '}' + '.checkbox label {' + ' display: block;' + ' margin: 0 0 10px;' + ' font-size: 16px;' + '}' + '.checkbox input[type="checkbox"] {' + ' border: 1px solid #B4B4B4;' + ' padding: 1px;' + ' margin: 3px;' + ' width: 16px;' + ' height: 16px;' + ' background: none;' + ' cursor: pointer;' + ' visibility: visible;' + ' position: static;' + ' vertical-align: middle;' + '}' + '#myDialog button {' + ' padding: 8px 16px;' + ' background-color: #4CAF50;' + ' color: #fff;' + ' border: none;' + ' border-radius: 4px;' + ' cursor: pointer;' + ' font-size: 14px;' + '}' + '#myDialog button:hover {' + ' background-color: #45a049;' + '}' + '</style>'); } } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址