您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
阅读界面左侧功能栏增加“听书”按钮,点击“听书”开始朗读:Esc-结束朗读;空格-暂定/继续(360安全浏览器急速模式(已测试),Chrome浏览器);后台静默复制文章内容到剪贴板。
当前为
// ==UserScript== // @name 起点听书/www.qidian.com // @namespace yoursatan // @version 0.2 // @description 阅读界面左侧功能栏增加“听书”按钮,点击“听书”开始朗读:Esc-结束朗读;空格-暂定/继续(360安全浏览器急速模式(已测试),Chrome浏览器);后台静默复制文章内容到剪贴板。 // @author yorusatan // @include https://read.qidian.com/chapter/* // @grant none // @require https://code.jquery.com/jquery-2.1.4.min.js // @license MIT License // ==/UserScript== // v0.2 修复一些使用中发现的bug。 // v0.1 在阅读界面左侧功能栏添加“听书”按钮,点击“听书”开始朗读:Esc-结束朗读;空格-暂定/继续(360安全浏览器急速模式(已测试),Chrome浏览器);后台静默复制文章内容到剪贴板。 (function() { "use strict"; // 用于获取story内文本的父元素全体 var storyAll = ""; // 用于获取story文本全体 var story = ""; // 用于存储格式化后story文本全体 var newStory = ""; // 侧边栏添加 听书 按钮 $(".left-bar-list dl").append( '<dd style="background:#e60022;"><a href="javascript:"><i><em class="iconfont"></em><span id ="btnSmartRead">听书</span></i></a><div class="guide-box"><cite> </cite></div></dd>' ); // 获取文章内容 story = $(".read-content") .html() .replace(/<\/?p data-type="2">/gi, "\n") .replace(/<\/p>/gi, "\n") .replace(/<span class="content-wrap">/g, "\n") .replace(/<i><cite><\/cite><\/i>/g, "\n") .replace(/<span class="review-count.*data-segid=\"\d*\">\d*/g, "\n") .replace(/<\/span>/g, "\n"); $(".read-content").empty(); $(".read-content").append("<div id='storycontent'></div>"); // hover 事件 $("#btnSmartRead").hover( function() { $("#btnSmartRead").css({ color: "white" }); }, function() { $("#btnSmartRead").css({ color: "black" }); } ); // 将原文本进行格式化,分割存储; var storyArr = story .replace(/<div class="hc">[\s\S].*<\/div>/gi, "") .replace(/<\/?p>/gi, "\n") .replace(/<\/?div>/gi, "\n") .replace(/<br\s*\/?>/gi, "\n") .replace(/\n(\n)*( )*(\n)*\n/g, "\n") .replace(/\ /g, "") .split(/\n/); // 用于存储格式化后,并移除空行文本数组 var newStoryArr = []; // 移除数组空项(文本空行) const countPara = storyArr.length; for (var i = 0; i < countPara; i++) { storyArr[i] = storyArr[i].replace(/\s+/g, " ").trim(); if (storyArr[i] != "") { newStory += "<p>" + storyArr[i] + "</p>"; newStoryArr.push(storyArr[i]); } } // 重新加载文章内容,并更改默认样式 $("#storycontent").append(newStory); $("#storycontent").css({ "font-size": "1em", "line-height": "1.5em", "font-family": "sans-serif", "font-weight": 300 }); const newCountPara = newStoryArr.length; // 用于逐段朗读 var flag = 0; // 朗读 var speaker = new window.SpeechSynthesisUtterance(); speaker.rate = 1.24; speaker.lang = "en-US"; speaker.voiceURI = "Microsoft Zira Desktop - English (United States)"; speaker.lang = "zh-CN"; speaker.voiceURI = "Microsoft Huihui Desktop - Chinese (Simplified)"; $("#storycontent").css("font-family", "PingFangSC-Regular"); // 多次尝试再for循环中无法循环朗读,故添加flag步进;利用setInterval进行循环。 $("#btnSmartRead").click(function() { // 复制文章内容到剪贴板 if ( // https://read.qidian.com/chapter/ 网站支持 window.location.href.indexOf("https://read.qidian.com/chapter/") > -1 ) { // 功能参考插件Enable Copy:https://bitbucket.org/keakon/enable-copy/src/default/enable.js // 非常感谢!Sun Jing。Thanks very much. var doc = document; var body = doc.body; var html = doc.documentElement; function allowUserSelect(element) { element.setAttribute( "style", "-webkit-user-select: text !important" ); element.setAttribute("style", "user-select: text !important"); return element; } function allowUserSelectById(element_id) { return allowUserSelect(doc.getElementById(element_id)); } function allowUserSelectByClassName(element_class) { var elements = doc.getElementsByClassName(element_class); var len = elements.length; for (var i = 0; i < len; ++i) { allowUserSelect(elements[i]); } return elements; } function clearHandlers() { // html.onselectstart = html.oncopy = html.oncut = html.onpaste = html.onkeydown = html.oncontextmenu = html.onmousemove = body.oncopy = body.oncut = body.onpaste = body.onkeydown = body.oncontextmenu = body.onmousedown = body.onmousemove = body.onselectstart = body.ondragstart = doc.onselectstart = doc.oncopy = doc.oncut = doc.onpaste = doc.onkeydown = doc.oncontextmenu = doc.onmousedown = doc.onmouseup = window.onkeyup = window.onkeydown = null; // 起点网下列三个设置足以 html.oncopy = body.oncopy = doc.oncopy = null; allowUserSelect(html); allowUserSelect(body); } clearHandlers(); function defaultHandler(event) { event.returnValue = true; } for (var event_type in ["copy", "cut", "paste"]) { // 起点网,以上三个足以; // var event_type in ['selectstart', 'copy', 'cut', 'paste', 'keydown', 'contextmenu', 'dragstart'] html.addEventListener(event_type, defaultHandler); body.addEventListener(event_type, defaultHandler); doc.addEventListener(event_type, defaultHandler); } function removeEventAttributes(element) { /* element.removeAttribute('oncontextmenu'); element.removeAttribute('ondragstart'); element.removeAttribute('onselectstart'); element.removeAttribute('onselect'); element.removeAttribute('oncopy'); element.removeAttribute('onbeforecopy'); element.removeAttribute('oncut'); element.removeAttribute('onpaste'); element.removeAttribute('onclick'); element.removeAttribute('onmousedown'); element.removeAttribute('onmouseup'); */ // 起点网设置这一个足以 element.removeAttribute("oncopy"); } var jQuery = window.jQuery; var $Fn = window.$Fn; if ($Fn) { try { $Fn.freeElement(doc); $Fn.freeElement(body); } catch (e) {} } /* // 不需要 var jindo = window.jindo; if (jindo) { jindo.$A = null; } */ function replaceElementEventsWithClone(element) { var clone = element.cloneNode(); while (element.firstChild) { clone.appendChild(element.firstChild); } element.parentNode.replaceChild(clone, element); } function replaceElementsEventsWithClone(elements) { var length = elements.length; for (var i = 0; i < length; ++i) { replaceElementEventsWithClone(elements[i]); } } var url = doc.URL; var domain_pattern = /^https?:\/\/([^\/]+)/; var result = domain_pattern.exec(url); if (result) { var domain = result[1]; if ( domain.length > 11 && domain.substr(-11, 11) == ".lofter.com" ) { replaceElementsEventsWithClone(jQuery(".pic>a")); return; } switch (domain) { case "wenku.baidu.com": jQuery(".doc-reader") .off("copy") .removeAttr("oncopy"); jQuery("#reader-container-1").off("copy"); break; case "www.qidian.com": case "read.qidian.com": case "vipreader.qidian.com": case "big5.qidian.com": case "www.qdmm.com": var element = doc.getElementById("bigcontbox"); if (element) { element.onmousedown = null; } //jQuery(body).off('contextmenu copy cut'); // 可使用复制功能 jQuery(body).off("copy"); break; } /* // 百度文库不能覆盖这些事件 // 起点会造成无限递归 bug if (jQuery) { var $doc = jQuery(doc); var $body = jQuery(body); if ($doc.off) { $doc.off(); $body.off(); jQuery(window).off(); } else { $doc.unbind(); $body.unbind(); jQuery(window).unbind(); } } */ } } // 完成后台复制 var copyStory = document.createElement("textarea"); //创建textarea对象 copyStory.id = "copyArea"; $("#storycontent").prepend(copyStory); //添加元素 var storyTitle = $("head title").html(); copyStory.value = storyTitle + "\n" + newStoryArr.join("\n"); // 组合文章标题 copyStory.focus(); if (copyStory.setSelectionRange) { copyStory.setSelectionRange(0, copyStory.value.length); //获取光标起始位置到结束位置 } else { copyStory.select(); } document.execCommand("Copy", "false", null); //执行复制 if (document.execCommand("Copy", "false", null)) { console.log( "已复制文章到剪贴板!Success,The story has been copied to clipboard!--yoursatan" ); } $("#copyArea").remove(); //删除元素 // 朗读文字数组 var storyAllRead = newStoryArr; // 用于文字选中效果 var range = document.createRange(); var selection = window.getSelection(); // 朗读 var readStory = function() { var reading = setInterval(function() { if (!window.speechSynthesis.speaking && flag < newCountPara) { speaker.text = storyAllRead[flag]; window.speechSynthesis.speak(speaker); flag += 1; // 朗读段落文字选中效果 var referenceNode = document .getElementById("storycontent") .childNodes.item(flag - 1); // 起点网朗读效果,当前朗读段落文字变红 $("#storycontent p") .eq(flag - 1) .css("color", "red"); $("html,body").animate( { scrollTop: $("#storycontent p") .eq(flag - 1) .offset().top - document.documentElement.clientHeight * 0.382 }, 500 /*scroll实现定位滚动*/ ); //代码参考,感谢:https://blog.csdn.net/qq_30109365/article/details/86592336 if (flag - 1) { $("#storycontent p") .eq(flag - 2) .css("color", "black"); } } else if (flag >= newCountPara) { // 朗读结束 // window.speechSynthesis.cancel(); clearInterval(reading); selection.removeAllRanges(); $("#storycontent p") .eq(flag - 1) .css("color", "black"); flag = 0; alert("The story is finished"); } }, 500); // 监听键盘:Esc/F5 $(document).keyup(function(event) { if (event.keyCode == 27 || event.keyCode == 116) { window.speechSynthesis.cancel(); clearInterval(reading); selection.removeAllRanges(); if ( // https://read.qidian.com/chapter/ 网站支持 window.location.href.indexOf( "https://read.qidian.com/chapter/" ) > -1 ) { $("#storycontent p") .eq(flag - 1) .css("color", "black"); } flag = 0; } }); // 监听键盘:空格键 $(document).keypress(function(event) { if (event.keyCode == 32) { if (window.speechSynthesis.speaking) { window.speechSynthesis.pause(); } if (window.speechSynthesis.paused) { window.speechSynthesis.resume(); } } }); // 监听标签关闭事件 window.onbeforeunload = function(e) { clearInterval(reading); window.speechSynthesis.cancel(); } }; readStory(); }); })();