自动无缝翻页

自动无缝翻页,目前支持:423Down、Apphot(原烈火汉化)

当前为 2021-01-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name 自动无缝翻页
  3. // @version 1.1.0
  4. // @author X.I.U
  5. // @description 自动无缝翻页,目前支持:423Down、Apphot(原烈火汉化)
  6. // @match *://www.423down.com/*
  7. // @exclude *://www.423down.com/*.html
  8. // @match *://apphot.cc/*
  9. // @exclude *://apphot.cc/*.html
  10. // @icon https://github.githubassets.com/favicon.ico
  11. // @grant GM_xmlhttpRequest
  12. // @grant GM_registerMenuCommand
  13. // @grant GM_openInTab
  14. // @license GPL-3.0 License
  15. // @run-at document-end
  16. // @namespace https://github.com/XIU2/UserScript
  17. // ==/UserScript==
  18.  
  19. (function() {
  20. // 注册(不可用)脚本菜单
  21. GM_registerMenuCommand('反馈 & 申请添加支持', function () {window.GM_openInTab('https://github.com/XIU2/UserScript#xiu2userscript', {active: true,insert: true,setParent: true});});
  22.  
  23. // 默认 ID 为 0
  24. var curSite = {SiteTypeID: 0};
  25.  
  26. // 自动翻页规则
  27. let DBSite = {
  28. postslist_423down: {
  29. SiteTypeID: 1,
  30. pager: {
  31. nextLink: '//div[@class="paging"]//a[contains(text(),"下一页")][@href]',
  32. pageElement: 'css;div.content-wrap ul.excerpt > li',
  33. HT_insert: ['css;div.content-wrap ul.excerpt', 2],
  34. replaceE: 'css;div.paging',
  35. scrollDelta: 1300
  36. }
  37. },
  38. postslist_apphot: {
  39. SiteTypeID: 2,
  40. pager: {
  41. nextLink: '//div[@class="pagination"]//a[contains(text(),"下一页")][@href]',
  42. pageElement: 'css;div.content > article.excerpt',
  43. HT_insert: ['css;div.pagination', 1],
  44. replaceE: 'css;div.pagination',
  45. scrollDelta: 1500
  46. }
  47. }
  48. };
  49.  
  50. // 用于脚本内部判断当前 URL 类型
  51. let SiteType = {
  52. POSTSLIST_423DOWN: DBSite.postslist_423down.SiteTypeID,
  53. POSTSLIST_APPHOT: DBSite.postslist_apphot.SiteTypeID
  54. };
  55.  
  56. switch (location.host) {
  57. case "www.423down.com":
  58. curSite = DBSite.postslist_423down;
  59. break;
  60. case "apphot.cc":
  61. curSite = DBSite.postslist_apphot;
  62. break;
  63. }
  64. curSite.pageUrl = ""; // 下一页URL
  65. pageLoading(); // 自动无缝翻页
  66.  
  67.  
  68. // 自动无缝翻页
  69. function pageLoading() {
  70. if (curSite.SiteTypeID > 0){
  71. windowScroll(function (direction, e) {
  72. if (direction === "down") { // 下滑才准备翻页
  73. var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
  74. let scrollDelta = curSite.pager.scrollDelta;
  75. if (document.documentElement.scrollHeight <= document.documentElement.clientHeight + scrollTop + scrollDelta) {
  76. ShowPager.loadMorePage();
  77. }
  78. }
  79. });
  80. }
  81. }
  82.  
  83.  
  84. // 滚动条事件
  85. function windowScroll(fn1) {
  86. var beforeScrollTop = document.documentElement.scrollTop,
  87. fn = fn1 || function () {};
  88. setTimeout(function () { // 延时执行,避免刚载入到页面就触发翻页事件
  89. window.addEventListener("scroll", function (e) {
  90. var afterScrollTop = document.documentElement.scrollTop,
  91. delta = afterScrollTop - beforeScrollTop;
  92. if (delta == 0) return false;
  93. fn(delta > 0 ? "down" : "up", e);
  94. beforeScrollTop = afterScrollTop;
  95. }, false);
  96. }, 1000)
  97. }
  98.  
  99.  
  100. var ShowPager = { // 修改自 https://gf.qytechs.cn/scripts/14178
  101. getFullHref: function (e) {
  102. if(e == null) return '';
  103. "string" != typeof e && (e = e.getAttribute("href"));
  104. var t = this.getFullHref.a;
  105. return t || (this.getFullHref.a = t = document.createElement("a")), t.href = e, t.href;
  106. },
  107. createDocumentByString: function (e) {
  108. if (e) {
  109. if ("HTML" !== document.documentElement.nodeName) return (new DOMParser).parseFromString(e, "application/xhtml+xml");
  110. var t;
  111. try {
  112. t = (new DOMParser).parseFromString(e, "text/html");
  113. } catch (e) {
  114. }
  115. if (t) return t;
  116. if (document.implementation.createHTMLDocument) t = document.implementation.createHTMLDocument("ADocument"); else try {
  117. (t = document.cloneNode(!1)).appendChild(t.importNode(document.documentElement, !1)),
  118. t.documentElement.appendChild(t.createElement("head")), t.documentElement.appendChild(t.createElement("body"));
  119. } catch (e) {
  120. }
  121. if (t) {
  122. var r = document.createRange();
  123. r.selectNodeContents(document.body);
  124. var n = r.createContextualFragment(e);
  125. t.body.appendChild(n);
  126. for (var a, o = {
  127. TITLE: !0,
  128. META: !0,
  129. LINK: !0,
  130. STYLE: !0,
  131. BASE: !0
  132. }, i = t.body, s = i.childNodes, c = s.length - 1; c >= 0; c--) o[(a = s[c]).nodeName] && i.removeChild(a);
  133. return t;
  134. }
  135. } else console.error("没有找到要转成DOM的字符串");
  136. },
  137. loadMorePage: function () {
  138. if (curSite.pager) {
  139. let curPageEle = getElementByXpath(curSite.pager.nextLink);
  140. var url = this.getFullHref(curPageEle);
  141. //console.log(`${url} ${curPageEle} ${curSite.pageUrl}`);
  142. if(url === '') return;
  143. if(curSite.pageUrl === url) return;// 不会重复加载相同的页面
  144. curSite.pageUrl = url;
  145. // 读取下一页的数据
  146. curSite.pager.startFilter && curSite.pager.startFilter();
  147. GM_xmlhttpRequest({
  148. url: url,
  149. method: "GET",
  150. timeout: 5000,
  151. onload: function (response) {
  152. try {
  153. var newBody = ShowPager.createDocumentByString(response.responseText);
  154. let pageElems = getAllElements(curSite.pager.pageElement, newBody, newBody);
  155. let toElement = getAllElements(curSite.pager.HT_insert[0])[0];
  156. if (pageElems.length >= 0) {
  157. let addTo = "beforeend";
  158. if (curSite.pager.HT_insert[1] == 1) addTo = "beforebegin";
  159. // 插入新页面元素
  160. pageElems.forEach(function (one) {
  161. toElement.insertAdjacentElement(addTo, one);
  162. });
  163. // 替换待替换元素
  164. try {
  165. let oriE = getAllElements(curSite.pager.replaceE);
  166. let repE = getAllElements(curSite.pager.replaceE, newBody, newBody);
  167. if (oriE.length === repE.length) {
  168. for (var i = 0; i < oriE.length; i++) {
  169. oriE[i].outerHTML = repE[i].outerHTML;
  170. }
  171. }
  172. } catch (e) {
  173. console.log(e);
  174. }
  175. }
  176. } catch (e) {
  177. console.log(e);
  178. }
  179. }
  180. });
  181. }
  182. },
  183. };
  184.  
  185.  
  186. function getElementByXpath(e, t, r) {
  187. r = r || document, t = t || r;
  188. try {
  189. return r.evaluate(e, t, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  190. } catch (t) {
  191. return void console.error("无效的xpath");
  192. }
  193. }
  194.  
  195.  
  196. function getAllElements(e, t, r, n, o) {
  197. let getAllElementsByXpath = function(e, t, r) {
  198. return r = r || document, t = t || r, r.evaluate(e, t, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  199. }
  200.  
  201. var i, s = [];
  202. if (!e) return s;
  203. if (r = r || document, n = n || window, o = o || void 0, t = t || r, "string" == typeof e) i = 0 === e.search(/^css;/i) ? function getAllElementsByCSS(e, t) {
  204. return (t || document).querySelectorAll(e);
  205. }(e.slice(4), t) : getAllElementsByXpath(e, t, r); else {
  206. if (!(i = e(r, n, o))) return s;
  207. if (i.nodeType) return s[0] = i, s;
  208. }
  209. return function makeArray(e) {
  210. var t, r, n, o = [];
  211. if (e.pop) {
  212. for (t = 0, r = e.length; t < r; t++) (n = e[t]) && (n.nodeType ? o.push(n) : o = o.concat(makeArray(n)));
  213. return a()(o);
  214. }
  215. if (e.item) {
  216. for (t = e.length; t;) o[--t] = e[t];
  217. return o;
  218. }
  219. if (e.iterateNext) {
  220. for (t = e.snapshotLength; t;) o[--t] = e.snapshotItem(t);
  221. return o;
  222. }
  223. }(i);
  224. }
  225. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址