微信读书 VIP会员版

可视化面板,轻松修改宽度、字体、字体颜色、背景颜色、背景图片,另有自动滚动(加速/减速/暂停/继续),自动翻页,隐藏头部标题。字体、背景颜色非常方便拓展增加

  1. // ==UserScript==
  2. // @name 微信读书 VIP会员版
  3. // @version 2.2.3
  4. // @license MIT
  5. // @namespace https://greasyfork.org/zh-CN/users/1272865
  6. // @description 可视化面板,轻松修改宽度、字体、字体颜色、背景颜色、背景图片,另有自动滚动(加速/减速/暂停/继续),自动翻页,隐藏头部标题。字体、背景颜色非常方便拓展增加
  7. // @author brewin
  8. // @match https://weread.qq.com/web/reader/*
  9. // @require https://cdn.staticfile.org/jquery/3.3.1/jquery.min.js
  10. // @icon https://weread.qq.com/favicon.ico
  11. // @grant GM_log
  12. // @grant GM_addStyle
  13. // @grant unsafeWindow
  14. // @grant GM_setValue
  15. // @grant GM_getValue
  16. // @grant GM_openInTab
  17. // @grant GM_download
  18. // @grant GM_setClipboard
  19. // @grant GM_notification
  20. // @grant GM_xmlhttpRequest
  21. // @grant GM_registerMenuCommand
  22. // @connect pixabay.com
  23. // @connect w3school.com.cn
  24. // ==/UserScript==
  25.  
  26. //GM_addStyle("*{font-family: TsangerJinKai05 !important;}");
  27. //GM_addStyle(".renderTargetContainer .wr_canvasContainer{position:inherit}");
  28. GM_addStyle(
  29. ".readerControls{margin-left: calc(50% - 200px) !important;margin-bottom: -28px !important;}"
  30. );
  31. GM_addStyle(
  32. ".dialog { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 400px; height: 600px; background-color: #f9f9f9; padding: 2px; border: 1px solid #ffffff; border-radius: 10px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); z-index: 1000; }.dialog-header { cursor: move; user-select: none; padding: 5px; height: 60px; background-color: #007bff; color: #fff; position: relative; border-top-left-radius: 10px; border-top-right-radius: 10px; font-size: 45px; font-weight: bold; }.dialog-content { padding: 10px; height: 500px; color: #000; background-color: #f0f0f0; border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; }.close { font-size: 20px; font-weight: bold; cursor: pointer; color: #fff; position: absolute; top: 5px; right: 5px; }"
  33. );
  34. GM_addStyle(
  35. ".next-page-tip { display: none; position: fixed; bottom: 0%; right: 10%; width: 120px; height: 40px; font-size: 25px;color:#000; background-color: #fff; padding: 2px; border: 1px solid grey; border-radius: 10px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); z-index: 1000; }"
  36. );
  37. GM_addStyle(
  38. ".next-page-tip-progress { width: 80px; background-color: #d8e2c8; }"
  39. );
  40. GM_addStyle("#dialog_content { overflow-y: auto; }");
  41. GM_addStyle(
  42. ".font-show-area-btn {font-size: 25px;color:#A52A2A; border:2px #c4c4c4 solid ;margin:5px}"
  43. );
  44. GM_addStyle(".font-show-area-font-absence {color:grey;}");
  45. GM_addStyle(
  46. ".font-color-show-area-btn{font-size: 20px; border:2px #c4c4c4 solid ;margin:5px}"
  47. );
  48. GM_addStyle(".font-color-show-area-label{font-size: 30px;margin:5px}");
  49.  
  50. GM_addStyle(
  51. ".background-color-show-area-btn{font-size: 20px; border:2px #c4c4c4 solid ;margin:5px}"
  52. );
  53. GM_addStyle(
  54. ".custom-background-color-show-area-btn{font-size: 12px; border:1px #c4c4c4 solid ;padding:5px}"
  55. );
  56. GM_addStyle(
  57. ".width-show-area-btn{font-size: 12px; border:1px #c4c4c4 solid ;margin:5px}"
  58. );
  59. GM_addStyle(".background-color-show-area-label{font-size: 30px;margin:5px}");
  60. GM_addStyle(
  61. ".auto-scroll-show-area-btn{ border:1px #c4c4c4 solid ;margin:5px}"
  62. );
  63.  
  64. $(window).on("load", async function () {
  65. "use strict";
  66. ///////////////////////////////////////////////////// 全局变量和菜单指令 /////////////////////////////////////////////////////
  67. //可选字体
  68. var myfonts = [
  69. {
  70. name: "默认",
  71. font: "PingFang SC,-apple-system,SF UI Text,Lucida Grande,STheiti,Microsoft YaHei,sans-serif"
  72. },
  73. { name: "楷体", font: "楷体" },
  74. { name: "宋体", font: "宋体" },
  75. { name: "黑体", font: "黑体" },
  76. { name: "苍耳今楷", font: "TsangerJinKai05" },
  77. { name: "字魂白鸽天行体", font: "字魂白鸽天行体" },
  78. { name: "霞鹜文楷", font: "霞鹜文楷" },
  79. { name: "汉仪空山楷", font: "汉仪空山楷" },
  80. { name: "寒蝉正楷体", font: "ChillKai" },
  81. { name: "三极行楷简体", font: "三极行楷简体-粗" },
  82. { name: "演示悠然小楷", font: "演示悠然小楷" }
  83. ];
  84. //可选背景图片
  85. var background_image_urls = [
  86. "https://www.w3school.com.cn/i/eg_bg_02.gif",
  87. "https://www.w3school.com.cn/i/eg_bg_03.gif",
  88. "https://www.w3school.com.cn/i/eg_bg_04.gif",
  89. "https://cdn.pixabay.com/photo/2016/12/18/02/35/paper-1914901_1280.jpg",
  90. "https://cdn.pixabay.com/photo/2017/09/06/11/41/vintage-2721099_1280.jpg",
  91. "https://cdn.pixabay.com/photo/2016/04/15/21/39/paper-1332019_1280.jpg",
  92. "https://cdn.pixabay.com/photo/2016/12/18/02/41/background-1914910_1280.jpg",
  93. "https://cdn.pixabay.com/photo/2015/06/02/15/31/watercolor-795162_1280.jpg",
  94. "https://cdn.pixabay.com/photo/2017/09/06/11/41/vintage-2721100_1280.jpg",
  95. "https://cdn.pixabay.com/photo/2016/04/15/21/34/paper-1332008_1280.jpg",
  96. "https://cdn.pixabay.com/photo/2016/04/15/21/37/paper-1332013_1280.jpg",
  97. "https://cdn.pixabay.com/photo/2017/11/07/10/22/paper-2926300_1280.jpg",
  98. "https://cdn.pixabay.com/photo/2018/02/16/20/46/pattern-3158572_1280.jpg",
  99. "https://cdn.pixabay.com/photo/2014/11/20/20/30/paper-539779_1280.jpg",
  100. "https://cdn.pixabay.com/photo/2019/11/02/15/21/map-4596619_1280.jpg",
  101. "https://cdn.pixabay.com/photo/2017/02/04/11/33/background-2037176_1280.jpg",
  102. "https://cdn.pixabay.com/photo/2015/09/13/11/00/vintage-937977_1280.jpg",
  103. "https://www.w3school.com.cn/i/eg_bg_01.gif"
  104. ];
  105. //自定义常驻背景颜色
  106. var mybackground_colors = [
  107. { name: "浅绿", color: "#d8e2c8" },
  108. { name: "茶色", color: "#d2b48c" },
  109. { name: "淡绿", color: "#eefaee" },
  110. { name: "明黄", color: "#ffffed" },
  111. { name: "灰绿", color: "#d8e7eb" },
  112. { name: "浅蓝", color: "#e9faff" },
  113. { name: "草绿", color: "#cce8cf" },
  114. { name: "红粉", color: "#fcefff" },
  115. { name: "米黄", color: "#f5f5dc" },
  116. { name: "暗银", color: "#c0c0c0" },
  117. { name: "黑绿", color: "#00b800" },
  118. { name: "浅黄", color: "#f5f1e8" },
  119. { name: "浅灰", color: "#d9e0e8" },
  120. { name: "深灰", color: "#555555" },
  121. { name: "漆黑", color: "#111111" },
  122. { name: "淡青", color: "#839496" },
  123. { name: "深青", color: "#002b36" }
  124. ];
  125.  
  126. ///////////////////////////////////////////////////// 对话框 /////////////////////////////////////////////////////
  127. $("body").append(`
  128. <div id="dialog" class="dialog">
  129. <div class="dialog-header">
  130. <span>功能</span>
  131. <span class="close" id="close_dialog">&times;</span>
  132. </div>
  133. <div id="dialog_content" class="dialog-content">
  134. <div class="font-style">
  135. <h3>宽度:</h3>
  136. <div id="width_show_area">
  137. </div>
  138.  
  139. <h3>字体:</h3>
  140. <div id="font_show_area">
  141. </div>
  142.  
  143. <h3>字体颜色:</h3>
  144. <div id="font_color_show_area">
  145. </div>
  146.  
  147. <h3>背景颜色:</h3>
  148. <div id="background_color_show_area">
  149. </div>
  150.  
  151. <h3>背景图片:</h3>
  152. <div id="background_image_show_area">
  153. </div>
  154.  
  155. <h3>自动滚动:</h3>
  156. <div id="auto_scroll_show_area">
  157. </div>
  158. </div>
  159. </div>
  160. </div>
  161. `);
  162. $("body").append(`
  163. <div id="next_page_tip" class="next-page-tip">
  164.  
  165. <div class="next-page-tip-progress">
  166. 即将翻页
  167. </div>
  168. </div>
  169. `);
  170.  
  171. var control_function_btn_div =
  172. "<button id='open_dialog' class='readerControls_item' style='color:#6a6c6c;cursor:pointer;'>功能</button>";
  173. $(".readerControls").append(control_function_btn_div);
  174.  
  175. $("#open_dialog").click(function () {
  176. $("#dialog").fadeIn();
  177. });
  178.  
  179. $("#close_dialog").click(function () {
  180. $("#dialog").fadeOut();
  181. });
  182.  
  183. let is_dragging = false;
  184. let offset_x, offset_y;
  185.  
  186. $(".dialog-header").mousedown(function (e) {
  187. is_dragging = true;
  188. offset_x = e.clientX - $("#dialog").offset().left;
  189. offset_y = e.clientY - $("#dialog").offset().top;
  190. });
  191.  
  192. $(document).mousemove(function (e) {
  193. if (is_dragging) {
  194. $("#dialog").offset({
  195. top: e.clientY - offset_y,
  196. left: e.clientX - offset_x
  197. });
  198. }
  199. });
  200.  
  201. $(document).mouseup(function () {
  202. is_dragging = false;
  203. });
  204.  
  205. ///////////////////////////////////////////////////// 字体 背景 /////////////////////////////////////////////////////
  206.  
  207. ///////////////////////////////////////////////////// 字体
  208. //初始化对话框全部字体缩图
  209. function initDialogFontShowArea() {
  210. for (let i = 0; i < myfonts.length; i++) {
  211. var font_btn = document.createElement("button");
  212. font_btn.textContent = myfonts[i].name;
  213. font_btn.style.fontFamily = myfonts[i].font;
  214. font_btn.classList.add("font-show-area-btn");
  215. if (!isSupportFontFamily(myfonts[i].font)) {
  216. font_btn.classList.add("font-show-area-font-absence");
  217. }
  218.  
  219. font_btn.addEventListener("click", function () {
  220. changeFont(i);
  221. });
  222. $("#font_show_area").append(font_btn);
  223. }
  224. var bak = GM_getValue("font_index", -1);
  225. changeFontSelectedBorder(bak);
  226. }
  227.  
  228. /* 改变字体
  229. index:使用字体序号
  230. */
  231. function changeFont(index) {
  232. var font = myfonts[index].font;
  233. var font_style_str = `*{font-family: ${font} ;}`;
  234. console.log("切换字体-> " + index + " font:" + font);
  235. GM_addStyle(font_style_str);
  236. GM_setValue("font_index", index);
  237. changeFontSelectedBorder(index);
  238. afterFontSelected();
  239. // location.reload();
  240. }
  241. //改变选中字体边框
  242. function changeFontSelectedBorder(index) {
  243. var buttons = $("#font_show_area button");
  244. for (var i = 0; i < buttons.length; i++) {
  245. if (i == index) {
  246. buttons[i].style.border = "2px solid silver";
  247. } else {
  248. buttons[i].style.border = "none";
  249. }
  250. }
  251. }
  252. //改变选中字体后对话框字体保持原字体
  253. function afterFontSelected() {
  254. var buttons = $("#font_show_area button");
  255. for (var i = 0; i < buttons.length; i++) {
  256. buttons[i].style.fontFamily = `${myfonts[i].font} !important`;
  257. }
  258. }
  259.  
  260. /* 判断用户操作系统是否安装某字体
  261. https://www.zhangxinxu.com/wordpress/2018/02/js-detect-suppot-font-family/
  262. */
  263. var isSupportFontFamily = function (f) {
  264. if (typeof f != "string") {
  265. return false;
  266. }
  267. var h = "Arial";
  268. if (f.toLowerCase() == h.toLowerCase()) {
  269. return true;
  270. }
  271. var e = "a";
  272. var d = 100;
  273. var a = 100,
  274. i = 100;
  275. var c = document.createElement("canvas");
  276. var b = c.getContext("2d");
  277. c.width = a;
  278. c.height = i;
  279. b.textAlign = "center";
  280. b.fillStyle = "black";
  281. b.textBaseline = "middle";
  282. var g = function (j) {
  283. b.clearRect(0, 0, a, i);
  284. b.font = d + "px " + j + ", " + h;
  285. b.fillText(e, a / 2, i / 2);
  286. var k = b.getImageData(0, 0, a, i).data;
  287. return [].slice.call(k).filter(function (l) {
  288. return l != 0;
  289. });
  290. };
  291. return g(h).join("") !== g(f).join("");
  292. };
  293.  
  294. ///////////////////////////////////////////////////// 字体颜色
  295. $("#font_color_show_area").append(`
  296. <input type="color" id="font_color" name="font_color" value="#ffffff" />
  297. <label for="font_color" class="font-color-show-area-label"></label>
  298. <button class="font-color-show-area-btn" id="font_color_open_btn">开启</button><button class="font-color-show-area-btn" id="font_color_close_btn">关闭</button>
  299. `);
  300. $("#font_color").on("input", function () {
  301. console.log("触发了input");
  302. var color = $(this).val();
  303. changeFontColor(true, color);
  304. });
  305.  
  306. $("#font_color").change(function () {
  307. console.log("触发了change");
  308. var color = $(this).val();
  309. GM_setValue("font_color", color);
  310. changeFontColor();
  311. });
  312.  
  313. //初始化对话框字体颜色展示区域
  314. function initDialogFontColorShowArea() {
  315. var font_color = GM_getValue("font_color", "#000000");
  316. var font_color_open = GM_getValue("font_color_open", false);
  317. if (font_color_open) {
  318. $("#font_color_open_btn").css("border", "2px solid fuchsia");
  319. $("#font_color_close_btn").css("border", "none");
  320. } else {
  321. $("#font_color_close_btn").css("border", "2px solid fuchsia");
  322. $("#font_color_open_btn").css("border", "none");
  323. }
  324. }
  325. /*改变字体颜色
  326. temp: 动态变换字体,方便看效果
  327. */
  328. function changeFontColor(temp = false, color = "#000000") {
  329. var color_str = `.readerChapterContent {color: ${color} !important;}`;
  330. //动态查看效果使用
  331. if (temp) {
  332. GM_addStyle(color_str);
  333. $('label[for="font_color"]').text(color);
  334. return;
  335. }
  336. var font_color = GM_getValue("font_color", "#000000");
  337. var font_color_open = GM_getValue("font_color_open", false);
  338. if (font_color_open) {
  339. color_str = `.readerChapterContent {color: ${font_color} !important;}`;
  340. GM_addStyle(color_str);
  341. $('label[for="font_color"]').text(font_color);
  342. } else {
  343. color_str = `.readerChapterContent {color: #000000 !important;}`;
  344. GM_addStyle(color_str);
  345. $('label[for="font_color"]').text("");
  346. }
  347. }
  348.  
  349. $("#font_color_open_btn").click(function () {
  350. GM_setValue("font_color_open", true);
  351. $("#font_color_open_btn").css("border", "2px solid aqua");
  352. $("#font_color_close_btn").css("border", "none");
  353. changeFontColor();
  354. });
  355. $("#font_color_close_btn").click(function () {
  356. GM_setValue("font_color_open", false);
  357. $("#font_color_close_btn").css("border", "2px solid aqua");
  358. $("#font_color_open_btn").css("border", "none");
  359. changeFontColor();
  360. });
  361.  
  362. ///////////////////////////////////////////////////// 背景图片
  363.  
  364. //初始化对话框全部背景图片缩图
  365. function initDialogBackgroundImageShowArea() {
  366. for (let i = 0; i < background_image_urls.length; i++) {
  367. //GM_xmlhttpRequest存在异步问题导致图片和序号不对应,暂时使用setTimeout解决
  368. setTimeout(() => {
  369. addDialogBackgroundImageShow(i);
  370. }, i * 100);
  371. }
  372. setTimeout(() => {
  373. var bak = GM_getValue("background_image_index", -1);
  374. changeBackgroundImageSelectedBorder(bak);
  375. }, (background_image_urls.length + 2) * 100);
  376. }
  377. //对话框追加背景图片缩图
  378. function addDialogBackgroundImageShow(index) {
  379. var url2 = background_image_urls[index];
  380. GM_xmlhttpRequest({
  381. method: "GET",
  382. url: url2,
  383. responseType: "blob",
  384. synchronous: true,
  385. onload: function (response) {
  386. var blobUrl = URL.createObjectURL(response.response);
  387. var img = document.createElement("img");
  388. img.src = blobUrl;
  389. img.style.width = "50px";
  390. img.style.height = "50px";
  391. img.style.margin = "3px";
  392. img.style.padding = "3px";
  393. img.addEventListener("click", function () {
  394. changeBackgroundImage(index);
  395. });
  396. $("#background_image_show_area").append(img);
  397. }
  398. });
  399. }
  400.  
  401. /* 改变背景图片
  402. index:使用背景图片序号
  403. dbClickCancel:是否双击取消背景图片
  404. 当$background_image_index和index相同时取消背景图片,也就是点击同一个背景图片两次时取消背景图片
  405. */
  406. function changeBackgroundImage(index, dbClickCancel = true) {
  407. var bak = GM_getValue("background_image_index", -1);
  408. // 又被点击了一次,取消背景图片
  409. if (bak == index && dbClickCancel) {
  410. index = -1;
  411. }
  412. var background_image_style_str =
  413. ".readerContent .app_content {background-image: none;}";
  414. if (index > -1) {
  415. background_image_style_str =
  416. ".readerContent .app_content {background-image: url('" +
  417. background_image_urls[index] +
  418. "');}";
  419. }
  420. console.log(
  421. "切换背景图片-> " + index + " url:" + background_image_urls[index]
  422. );
  423. GM_addStyle(background_image_style_str);
  424. GM_setValue("background_image_index", index);
  425. changeBackgroundImageSelectedBorder(index);
  426. }
  427. function changeBackgroundImageSelectedBorder(index) {
  428. var images = $("#background_image_show_area img");
  429. for (var i = 0; i < images.length; i++) {
  430. if (i == index) {
  431. images[i].style.border = "2px solid green";
  432. } else {
  433. images[i].style.border = "none";
  434. }
  435. }
  436. }
  437.  
  438. ///////////////////////////////////////////////////// 背景颜色
  439. $("#background_color_show_area").append(`
  440. <input type="color" id="background_color" name="background_color" value="#ffffff" />
  441. <label for="background_color" class="background-color-show-area-label"></label>
  442. <button class="background-color-show-area-btn" id="background_color_open_btn">开启</button><button class="background-color-show-area-btn" id="background_color_close_btn">关闭</button>
  443. `);
  444. $("#background_color").on("input", function () {
  445. var color = $(this).val();
  446. changeBackgroundColor(true, color);
  447. });
  448.  
  449. $("#background_color").change(function () {
  450. var color = $(this).val();
  451. GM_setValue("background_color", color);
  452. changeBackgroundColor();
  453. });
  454.  
  455. //初始化对话框背景颜色展示区域
  456. function initDialogBackgroundColorShowArea() {
  457. var background_color = GM_getValue("background_color", "#d8e2c8");
  458. var background_color_open = GM_getValue("background_color_open", false);
  459. if (background_color_open) {
  460. $("#background_color_open_btn").css("border", "2px solid maroon");
  461. $("#background_color_close_btn").css("border", "none");
  462. } else {
  463. $("#background_color_close_btn").css("border", "2px solid maroon");
  464. $("#background_color_open_btn").css("border", "none");
  465. }
  466. //自定义背景颜色按钮
  467. $("#background_color_show_area").append("<br>");
  468. for (let i = 0; i < mybackground_colors.length; i++) {
  469. var item = mybackground_colors[i];
  470. var background_color_btn = document.createElement("button");
  471. background_color_btn.textContent = item.name;
  472. background_color_btn.style.backgroundColor = item.color;
  473. background_color_btn.classList.add(
  474. "custom-background-color-show-area-btn"
  475. );
  476. $("#background_color_show_area").append(background_color_btn);
  477. }
  478. }
  479.  
  480. function changeBackgroundColor(temp = false, color = "none") {
  481. var color_str = `.readerContent .app_content{background-color: ${color} !important;}`;
  482. //动态查看效果使用
  483. if (temp) {
  484. GM_addStyle(color_str);
  485. $('label[for="background_color"]').text(color);
  486. return;
  487. }
  488. var background_color = GM_getValue("background_color", "#d8e2c8");
  489. var background_color_open = GM_getValue("background_color_open", false);
  490. if (background_color_open) {
  491. color_str = `.readerContent .app_content{background-color: ${background_color} !important;}`;
  492. GM_addStyle(color_str);
  493. $('label[for="background_color"]').text(background_color);
  494. } else {
  495. color_str = `.readerContent .app_content{background-color: transparent !important;}`;
  496. GM_addStyle(color_str);
  497. $('label[for="background_color"]').text("");
  498. }
  499. }
  500.  
  501. $("#background_color_open_btn").click(function () {
  502. GM_setValue("background_color_open", true);
  503. $("#background_color_open_btn").css("border", "2px solid maroon");
  504. $("#background_color_close_btn").css("border", "none");
  505. changeBackgroundColor();
  506. });
  507. $("#background_color_close_btn").click(function () {
  508. GM_setValue("background_color_open", false);
  509. $("#background_color_close_btn").css("border", "2px solid maroon");
  510. $("#background_color_open_btn").css("border", "none");
  511. changeBackgroundColor();
  512. });
  513. $("#background_color_show_area").on(
  514. "click",
  515. ".custom-background-color-show-area-btn",
  516. function () {
  517. var selectedColorName = $(this).text();
  518. var selectedColor = getColorByName(selectedColorName);
  519. GM_setValue("background_color", selectedColor);
  520. $("#background_color").val(selectedColor);
  521. changeBackgroundColor();
  522. }
  523. );
  524.  
  525. function getColorByName(colorName) {
  526. for (let i = 0; i < mybackground_colors.length; i++) {
  527. if (mybackground_colors[i].name === colorName) {
  528. return mybackground_colors[i].color;
  529. }
  530. }
  531. return "transparent"; // 如果未找到对应颜色,可以返回null或者其他自定义值
  532. }
  533.  
  534. ///////////////////////////////////////////////////// 宽度 /////////////////////////////////////////////////////
  535.  
  536. $("#width_show_area").append(`
  537. <input type="range" min="30" max="100" value="60" style="width:300px" id="width_control">
  538. <span id="width_control_text"></span>%<button class="width-show-area-btn" id="default_width_btn">默认</button>
  539. `);
  540. $("#width_control").on("input", function () {
  541. var width_radio = $(this).val();
  542. $("#width_control_text").text(width_radio);
  543. var new_width = Math.floor((window.innerWidth * width_radio) / 100);
  544. GM_setValue("width_radio", width_radio);
  545. changeWidth(new_width);
  546. });
  547.  
  548. //改变文章宽度
  549. function changeWidth(new_width) {
  550. const item1 = document.querySelector(".readerContent .app_content");
  551. const item2 = document.querySelector(".readerTopBar");
  552. item1.style["max-width"] = new_width + "px";
  553. item2.style["max-width"] = new_width + "px";
  554. const myEvent = new Event("resize");
  555. window.dispatchEvent(myEvent);
  556. }
  557. //初始化宽度
  558. function initWidth() {
  559. const item1 = document.querySelector(".readerContent .app_content");
  560. const defaultOriginWidth = getElementMaxWidth(item1);
  561. GM_setValue("default_origin_width", defaultOriginWidth);
  562. var width_radio = GM_getValue("width_radio", 60);
  563. $("#width_control").val(width_radio);
  564. $("#width_control_text").text(width_radio);
  565. var new_width = Math.floor((window.innerWidth * width_radio) / 100);
  566. changeWidth(new_width);
  567. }
  568.  
  569. //获取元素最大宽度
  570. function getElementMaxWidth(element) {
  571. let currentValue = window.getComputedStyle(element).maxWidth;
  572. currentValue = currentValue.substring(0, currentValue.indexOf("px"));
  573. currentValue = parseInt(currentValue);
  574. return currentValue;
  575. }
  576. $("#default_width_btn").click(function () {
  577. var default_origin_width = GM_getValue("default_origin_width", 600);
  578. changeWidth(default_origin_width);
  579. var width_radio = Math.floor(
  580. (default_origin_width * 100) / window.innerWidth
  581. );
  582. GM_setValue("width_radio", width_radio);
  583. $("#width_control").val(width_radio);
  584. $("#width_control_text").text(width_radio);
  585. });
  586. ///////////////////////////////////////////////////// 自动滚动 /////////////////////////////////////////////////////
  587. $("#auto_scroll_show_area").append(`
  588. <label for="scroll_interval">滚动间隔:</label>
  589. <input type="number" id="scroll_interval" name="scroll_interval">ms
  590. <br>
  591. <label for="scroll_speed">滚动距离:</label>
  592. <input type="number" id="scroll_speed" name="scroll_speed" >px
  593. <br>
  594. <label for="scroll_speed">翻页等待:</label>
  595. <input type="number" id="next_page_wait_threshold" name="next_page_wait_threshold" >ms
  596. `);
  597.  
  598. $(".readerControls").append(
  599. "<button id='auto_scroll_speed_acc' class='readerControls_item' style='color:#6a6c6c;cursor:pointer;'>滚动加速</button><button id='auto_scroll_speed_dec' class='readerControls_item' style='color:#6a6c6c;cursor:pointer;'>滚动减速</button><button id='auto_scroll_pause' class='readerControls_item' style='color:#6a6c6c;cursor:pointer;'>开始滚动</button>"
  600. );
  601.  
  602. // 初始滚动状态
  603. let is_scrolling = false;
  604. //滚动间隔
  605. let scroll_interval = GM_getValue("scroll_interval", 20);
  606. // 初始滚动速度
  607. let scroll_speed = GM_getValue("scroll_speed", 1);
  608. // 等待翻页阈值
  609. let next_page_wait_threshold = GM_getValue("next_page_wait_threshold", 1000);
  610. //滚动事件标识
  611. let interval_event_id;
  612. //上次滚动位置
  613. let last_scroll_pos = -1;
  614. //已等待时间
  615. let next_page_wait = 0;
  616. //最小滚动间隔
  617. let min_scroll_interval = 20;
  618. // 最小初始滚动速度
  619. let min_scroll_speed = 1;
  620. // 最小等待翻页阈值
  621. let min_next_page_wait_threshold = 500;
  622. $("#auto_scroll_speed_acc").click(function () {
  623. scroll_speed++;
  624. GM_setValue("scroll_speed", scroll_speed);
  625. var text = $("#auto_scroll_pause").text().substring(0, 2);
  626. $("#auto_scroll_pause").html(text + scroll_speed);
  627. $("#scroll_speed").val(scroll_speed);
  628. });
  629.  
  630. $("#auto_scroll_speed_dec").click(function () {
  631. scroll_speed--;
  632. if (scroll_speed < min_scroll_speed) {
  633. scroll_speed = 1;
  634. }
  635. GM_setValue("scroll_speed", scroll_speed);
  636. var text = $("#auto_scroll_pause").text().substring(0, 2);
  637. $("#auto_scroll_pause").html(text + scroll_speed);
  638. $("#scroll_speed").val(scroll_speed);
  639. });
  640.  
  641. $("#auto_scroll_pause").click(function () {
  642. is_scrolling = !is_scrolling;
  643. if (is_scrolling) {
  644. interval_event_id = setInterval(autoScroll, scroll_interval);
  645. $("#auto_scroll_pause").html("暂停" + scroll_speed);
  646. } else {
  647. clearInterval(interval_event_id);
  648. $("#auto_scroll_pause").html("继续" + scroll_speed);
  649. }
  650. });
  651.  
  652. $("#scroll_interval").on("change", function () {
  653. var new_scroll_interval = $(this).val();
  654. scroll_interval = new_scroll_interval;
  655. if (scroll_interval < min_scroll_interval) {
  656. scroll_interval = min_scroll_interval;
  657. $("#scroll_interval").val(scroll_interval);
  658. }
  659. GM_setValue("scroll_interval", scroll_interval);
  660. });
  661. $("#scroll_speed").on("change", function () {
  662. var new_scroll_speed = $(this).val();
  663. scroll_speed = new_scroll_speed;
  664. if (scroll_speed < min_scroll_speed) {
  665. scroll_speed = min_scroll_speed;
  666. $("#scroll_speed").val(scroll_speed);
  667. }
  668. GM_setValue("scroll_speed", scroll_speed);
  669. var text = $("#auto_scroll_pause").text().substring(0, 2);
  670. $("#auto_scroll_pause").html(text + scroll_speed);
  671. });
  672. $("#next_page_wait_threshold").on("change", function () {
  673. var new_next_page_wait_threshold = $(this).val();
  674. next_page_wait_threshold = new_next_page_wait_threshold;
  675. if (next_page_wait_threshold < min_next_page_wait_threshold) {
  676. next_page_wait_threshold = min_next_page_wait_threshold;
  677. $("#next_page_wait_threshold").val(next_page_wait_threshold);
  678. }
  679. GM_setValue("next_page_wait_threshold", next_page_wait_threshold);
  680. });
  681. function autoScroll() {
  682. var distance = scroll_speed;
  683. window.scrollBy(0, distance);
  684. let scroll_pos = $(this).scrollTop();
  685.  
  686. // 到底后会一直一样,累加等待时间
  687. if (last_scroll_pos == scroll_pos) {
  688. next_page_wait = parseInt(next_page_wait) + parseInt(scroll_interval);
  689. let progress = Math.floor(
  690. (next_page_wait * 100) / next_page_wait_threshold
  691. );
  692. GM_addStyle(
  693. `.next-page-tip-progress { width: ${progress}px; background-color: #d8e2c8; }`
  694. );
  695. } else {
  696. next_page_wait = 0;
  697. }
  698. last_scroll_pos = scroll_pos;
  699. // 开始显示翻页条
  700. if (next_page_wait > 200) {
  701. console.log(
  702. "next_page_wait:" +
  703. next_page_wait +
  704. ",next_page_wait_threshold:" +
  705. next_page_wait_threshold
  706. );
  707. $("#next_page_tip").fadeIn();
  708. } else {
  709. $("#next_page_tip").fadeOut();
  710. }
  711. // 到达阈值,翻页
  712. if (next_page_wait > next_page_wait_threshold) {
  713. document.dispatchEvent(
  714. new KeyboardEvent("keydown", {
  715. bubbles: true,
  716. cancelable: true,
  717. keyCode: 39
  718. })
  719. );
  720. }
  721. }
  722. //初始化对话框自动滚动配置区域
  723. function initDialogAutoScrollShowArea() {
  724. $("#scroll_interval").val(scroll_interval);
  725. $("#scroll_speed").val(scroll_speed);
  726. $("#next_page_wait_threshold").val(next_page_wait_threshold);
  727. }
  728. ///////////////////////////////////////////////////// 隐藏显示工具栏 /////////////////////////////////////////////////////
  729. let reader_controls = $(".readerControls");
  730. $(document).mousemove(function (event) {
  731. // 获取鼠标指针相对于文档的位置
  732. let mouse_x = event.pageX;
  733. // 获取屏幕宽度
  734. let screen_width = $(window).width();
  735. // 如果鼠标指针距离屏幕最右侧200px内,则显示reader_controls,否则隐藏
  736. if (screen_width - mouse_x <= 200) {
  737. reader_controls.css("opacity", "1");
  738. } else {
  739. reader_controls.css("opacity", "0");
  740. }
  741. });
  742.  
  743. ///////////////////////////////////////////////////// 下滑不显示标题栏 /////////////////////////////////////////////////////
  744. var window_top = 0;
  745. $(window).scroll(function () {
  746. let scroll_dis = $(this).scrollTop();
  747. let reader_top_bar = $(".readerTopBar");
  748. if (scroll_dis > window_top) {
  749. // 下滑隐藏
  750. reader_top_bar.css("opacity", "0");
  751. } else {
  752. // 上滑到最顶端显示
  753. reader_top_bar.css("opacity", "1");
  754. }
  755. });
  756. ///////////////////////////////////////////////////// 启动初始化 /////////////////////////////////////////////////////
  757. //页面加载时初始化
  758. function pageLoad() {
  759. console.log("pageLoad");
  760. //打开对话框时渲染已选中的字体、背景图片缩图
  761. initDialog();
  762. //初始化字体
  763. initFont();
  764. //初始化字体颜色
  765. initFontColor();
  766. //初始化背景图片
  767. initBackgroundImage();
  768. //初始化背景颜色
  769. initBackgroundColor();
  770. //初始化宽度
  771. initWidth();
  772. }
  773. //初始化背景图片
  774. function initBackgroundImage() {
  775. var bak = GM_getValue("background_image_index", -1);
  776. changeBackgroundImage(bak, false);
  777. }
  778. //初始化背景颜色
  779. function initBackgroundColor() {
  780. var background_color = GM_getValue("background_color", "#d8e2c8");
  781. $("#background_color").val(background_color);
  782. changeBackgroundColor();
  783. }
  784. //初始化字体颜色
  785. function initFontColor() {
  786. var font_color = GM_getValue("font_color", "#000000");
  787. $("#font_color").val(font_color);
  788. changeFontColor();
  789. }
  790. //初始化字体
  791. function initFont() {
  792. var bak = GM_getValue("font_index", 0);
  793. changeFont(bak);
  794. }
  795. //打开对话框时渲染已选中的字体、背景图片缩图
  796. function initDialog() {
  797. //初始化对话框字体颜色展示区域
  798. initDialogFontColorShowArea();
  799. //初始化对话框背景颜色展示区域
  800. initDialogBackgroundColorShowArea();
  801. //初始化对话框全部背景图片缩图
  802. initDialogBackgroundImageShowArea();
  803. //初始化对话框全部字体缩图
  804. initDialogFontShowArea();
  805. //初始化对话框自动滚动配置区域
  806. initDialogAutoScrollShowArea();
  807. }
  808. pageLoad();
  809. })();