Skip to content

Commit 2234854

Browse files
committed
新增 全球主机交流论坛自动翻页脚本
1 parent 0dea2e0 commit 2234854

2 files changed

Lines changed: 253 additions & 0 deletions

File tree

Hostloc-Enhanced.user.js

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
// ==UserScript==
2+
// @name 全球主机交流论坛增强
3+
// @version 1.0.0
4+
// @author X.I.U
5+
// @description 自动无缝翻页
6+
// @match *://www.hostloc.com/*
7+
// @icon https://www.hostloc.com/favicon.ico
8+
// @grant GM_xmlhttpRequest
9+
// @license GPL-3.0 License
10+
// @run-at document-end
11+
// @namespace https://greasyfork.org/scripts/414005
12+
// ==/UserScript==
13+
14+
(function() {
15+
// 是否开启帖子内自动翻页功能,true 为开启,false 为关闭。
16+
var thread_pageLoading = true;
17+
18+
// 默认 ID 为 0
19+
var curSite = {SiteTypeID: 0};
20+
21+
// 自动翻页规则
22+
let DBSite = {
23+
forum: {
24+
SiteTypeID: 1
25+
},
26+
thread: {
27+
SiteTypeID: 2,
28+
pager: {
29+
nextLink: '//div[@id="pgt"]//a[contains(text(),"下一页")][@href]',
30+
pageElement: 'css;div#postlist > div[id^="post_"]',
31+
HT_insert: ['css;div#postlist', 2],
32+
replaceE: '//div[@class="pg"] | //div[@class="pgbtn"]',
33+
}
34+
},
35+
guide: {
36+
SiteTypeID: 3,
37+
pager: {
38+
nextLink: '//div[@id="pgt"]//a[contains(text(),"下一页")][@href]',
39+
pageElement: 'css;div#threadlist div.bm_c table > tbody[id^="normalthread_"]',
40+
HT_insert: ['css;div#threadlist div.bm_c table', 2],
41+
replaceE: 'css;div.pg',
42+
}
43+
}
44+
};
45+
46+
// 用于脚本内部判断当前 URL 类型
47+
let SiteType = {
48+
FORUM: DBSite.forum.SiteTypeID, // 各板块帖子列表
49+
THREAD: DBSite.thread.SiteTypeID, // 帖子内
50+
GUIDE: DBSite.guide.SiteTypeID // 导读帖子列表
51+
};
52+
53+
// URL 匹配正则表达式
54+
var patt_thread = /\/thread-\d+-\d+\-\d+.html/,
55+
patt_thread_2 = /mod\=viewthread/,
56+
patt_forum = /\/forum-\d+-\d+\.html/,
57+
patt_forum_2 = /mod\=forumdisplay/,
58+
patt_guide = /mod\=guide\&view\=(hot|digest)/
59+
60+
// URL 判断
61+
if (patt_thread.test(location.pathname) || patt_thread_2.test(location.search)){
62+
// 帖子内
63+
if(thread_pageLoading)curSite = DBSite.thread;
64+
// 自动显示帖子内被隐藏的回复
65+
showPosts();
66+
}else if (patt_forum.test(location.pathname) || patt_forum_2.test(location.search)){
67+
// 各板块帖子列表
68+
curSite = DBSite.forum;
69+
}else if (patt_guide.test(location.search)){
70+
// 导读帖子列表
71+
curSite = DBSite.guide;
72+
}
73+
curSite.pageUrl = ""; // 下一页URL
74+
75+
76+
pageLoading(); // 自动翻页
77+
78+
79+
// 自动翻页
80+
function pageLoading() {
81+
if (curSite.SiteTypeID > 0){
82+
windowScroll(function (direction, e) {
83+
if (direction === "down") { // 下滑才准备翻页
84+
var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
85+
let scrollDelta = 666;
86+
if (document.documentElement.scrollHeight <= document.documentElement.clientHeight + scrollTop + scrollDelta) {
87+
if (curSite.SiteTypeID === SiteType.FORUM) { // 如果是各版块帖子列表则直接点下一页就行了
88+
var autopbn = document.querySelector('#autopbn');
89+
if (autopbn && autopbn.innerText == "下一页 »"){ // 如果已经在加载中了,就忽略
90+
autopbn.click();
91+
}
92+
}else{
93+
ShowPager.loadMorePage();
94+
}
95+
}
96+
}
97+
});
98+
}
99+
}
100+
101+
102+
// 自动显示帖子内被隐藏的回复
103+
function showPosts() {
104+
var showposts = document.querySelector('#hiddenpoststip a');
105+
if (showposts){ // 如果存在
106+
showposts.click();
107+
}
108+
}
109+
110+
111+
// 滚动条事件
112+
function windowScroll(fn1) {
113+
var beforeScrollTop = document.documentElement.scrollTop,
114+
fn = fn1 || function () {};
115+
setTimeout(function () { // 延时执行,避免刚载入到页面就触发翻页事件
116+
window.addEventListener("scroll", function (e) {
117+
var afterScrollTop = document.documentElement.scrollTop,
118+
delta = afterScrollTop - beforeScrollTop;
119+
if (delta == 0) return false;
120+
fn(delta > 0 ? "down" : "up", e);
121+
beforeScrollTop = afterScrollTop;
122+
}, false);
123+
}, 1000)
124+
}
125+
126+
127+
var ShowPager = { // 修改自 https://greasyfork.org/scripts/14178
128+
getFullHref: function (e) {
129+
if(e == null) return '';
130+
"string" != typeof e && (e = e.getAttribute("href"));
131+
var t = this.getFullHref.a;
132+
return t || (this.getFullHref.a = t = document.createElement("a")), t.href = e, t.href;
133+
},
134+
createDocumentByString: function (e) {
135+
if (e) {
136+
if ("HTML" !== document.documentElement.nodeName) return (new DOMParser).parseFromString(e, "application/xhtml+xml");
137+
var t;
138+
try {
139+
t = (new DOMParser).parseFromString(e, "text/html");
140+
} catch (e) {
141+
}
142+
if (t) return t;
143+
if (document.implementation.createHTMLDocument) t = document.implementation.createHTMLDocument("ADocument"); else try {
144+
(t = document.cloneNode(!1)).appendChild(t.importNode(document.documentElement, !1)),
145+
t.documentElement.appendChild(t.createElement("head")), t.documentElement.appendChild(t.createElement("body"));
146+
} catch (e) {
147+
}
148+
if (t) {
149+
var r = document.createRange();
150+
r.selectNodeContents(document.body);
151+
var n = r.createContextualFragment(e);
152+
t.body.appendChild(n);
153+
for (var a, o = {
154+
TITLE: !0,
155+
META: !0,
156+
LINK: !0,
157+
STYLE: !0,
158+
BASE: !0
159+
}, i = t.body, s = i.childNodes, c = s.length - 1; c >= 0; c--) o[(a = s[c]).nodeName] && i.removeChild(a);
160+
return t;
161+
}
162+
} else console.error("没有找到要转成DOM的字符串");
163+
},
164+
loadMorePage: function () {
165+
if (curSite.pager) {
166+
let curPageEle = getElementByXpath(curSite.pager.nextLink);
167+
var url = this.getFullHref(curPageEle);
168+
//console.log(`${url} ${curPageEle} ${curSite.pageUrl}`);
169+
if(url === '') return;
170+
if(curSite.pageUrl === url) return;// 不会重复加载相同的页面
171+
curSite.pageUrl = url;
172+
// 读取下一页的数据
173+
curSite.pager.startFilter && curSite.pager.startFilter();
174+
GM_xmlhttpRequest({
175+
url: url,
176+
method: "GET",
177+
timeout: 5000,
178+
onload: function (response) {
179+
try {
180+
var newBody = ShowPager.createDocumentByString(response.responseText);
181+
let pageElems = getAllElements(curSite.pager.pageElement, newBody, newBody);
182+
let toElement = getAllElements(curSite.pager.HT_insert[0])[0];
183+
if (pageElems.length >= 0) {
184+
let addTo = "beforeend";
185+
if (curSite.pager.HT_insert[1] == 1) addTo = "beforebegin";
186+
// 插入新页面元素
187+
pageElems.forEach(function (one) {
188+
toElement.insertAdjacentElement(addTo, one);
189+
});
190+
// 替换待替换元素
191+
try {
192+
let oriE = getAllElements(curSite.pager.replaceE);
193+
let repE = getAllElements(curSite.pager.replaceE, newBody, newBody);
194+
if (oriE.length === repE.length) {
195+
for (var i = 0; i < oriE.length; i++) {
196+
oriE[i].outerHTML = repE[i].outerHTML;
197+
}
198+
}
199+
} catch (e) {
200+
console.log(e);
201+
}
202+
}
203+
} catch (e) {
204+
console.log(e);
205+
}
206+
}
207+
});
208+
}
209+
},
210+
};
211+
212+
213+
function getElementByXpath(e, t, r) {
214+
r = r || document, t = t || r;
215+
try {
216+
return r.evaluate(e, t, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
217+
} catch (t) {
218+
return void console.error("无效的xpath");
219+
}
220+
}
221+
222+
223+
function getAllElements(e, t, r, n, o) {
224+
let getAllElementsByXpath = function(e, t, r) {
225+
return r = r || document, t = t || r, r.evaluate(e, t, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
226+
}
227+
228+
var i, s = [];
229+
if (!e) return s;
230+
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) {
231+
return (t || document).querySelectorAll(e);
232+
}(e.slice(4), t) : getAllElementsByXpath(e, t, r); else {
233+
if (!(i = e(r, n, o))) return s;
234+
if (i.nodeType) return s[0] = i, s;
235+
}
236+
return function makeArray(e) {
237+
var t, r, n, o = [];
238+
if (e.pop) {
239+
for (t = 0, r = e.length; t < r; t++) (n = e[t]) && (n.nodeType ? o.push(n) : o = o.concat(makeArray(n)));
240+
return a()(o);
241+
}
242+
if (e.item) {
243+
for (t = e.length; t;) o[--t] = e[t];
244+
return o;
245+
}
246+
if (e.iterateNext) {
247+
for (t = e.snapshotLength; t;) o[--t] = e.snapshotItem(t);
248+
return o;
249+
}
250+
}(i);
251+
}
252+
})();

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
| **Google 翻译美化** | 精简多余内容、修复翻译结果溢出屏幕问题 | **[「安装」](https://greasyfork.org/scripts/413721)** | **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/GoogleTranslate-Beautification.user.js)** |
2727
| **吾爱破解论坛美化** | 精简多余内容 | **[「安装」](https://greasyfork.org/scripts/412681)** | **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/52pojie-Beautification.user.js)** |
2828
| **吾爱破解论坛增强** | 自动签到、自动无缝翻页 | **[「安装」](https://greasyfork.org/scripts/412680)** | **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/52pojie-Enhanced.user.js)** |
29+
| **全球主机交流论坛增强** | 自动无缝翻页 | **[「安装」](https://greasyfork.org/scripts/414005)** | **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/Hostloc-Enhanced.user.js)** |
2930
| **Steam 创意工坊大图修复** | 修复 Steam 创意工坊预览大图无法显示的问题 | **[「安装」](https://greasyfork.org/scripts/397666)** | **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/SteamWorkshopImageRepair.user.js)** |
3031

3132
****

0 commit comments

Comments
 (0)