Skip to content

Commit 624c3ae

Browse files
committed
新增 3DM论坛增强 - 自动无缝翻页
1 parent d171aea commit 624c3ae

2 files changed

Lines changed: 240 additions & 3 deletions

File tree

3dm-Enhanced.user.js

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

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
## 使用说明
1010

11-
> 点击 **「安装」** 是备用的 Github 链接,点击 **脚本名称** 查看详细介绍。
11+
> 点击 **「安装」** 是备用的 Github 链接,点击 **脚本名称** 前往 _GreasyFork_ 查看详细介绍。
1212
1313
* **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/SteamWorkshopImageRepair.user.js)** [Steam 创意工坊大图修复](https://greasyfork.org/scripts/397666)
1414
****
@@ -17,12 +17,14 @@
1717
* **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/ZhihuEnhanced-HD-Pictures.user.js)** [知乎增强 - 默认显示高清原图](https://greasyfork.org/scripts/412217)
1818
* **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/ZhihuEnhanced-Time.user.js)** [知乎增强 - 置顶显示发布/编辑时间](https://greasyfork.org/scripts/412216)
1919
****
20-
* **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/Zhiyoo-Beautification.user.js)** [智友邦论坛美化 - 精简多余内容、宽屏显示](https://greasyfork.org/scripts/412361)
21-
* **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/Zhiyoo-Enhanced.user.js)** [智友邦论坛增强 - 自动签到、自动回复、自动无缝翻页、清理置顶帖子](https://greasyfork.org/scripts/412362)
20+
* **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/3dm-Enhanced.user.js)** [3DM论坛增强 - 自动无缝翻页](https://greasyfork.org/scripts/412890)
2221
****
2322
* **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/52pojie-Beautification.user.js)** [吾爱破解论坛美化 - 精简多余内容](https://greasyfork.org/scripts/412681)
2423
* **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/52pojie-Enhanced.user.js)** [吾爱破解论坛增强 - 自动签到、自动无缝翻页](https://greasyfork.org/scripts/412680)
2524
****
25+
* **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/Zhiyoo-Beautification.user.js)** [智友邦论坛美化 - 精简多余内容、宽屏显示](https://greasyfork.org/scripts/412361)
26+
* **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/Zhiyoo-Enhanced.user.js)** [智友邦论坛增强 - 自动签到、自动回复、自动无缝翻页、清理置顶帖子](https://greasyfork.org/scripts/412362)
27+
****
2628
* **[「安装」](https://cdn.jsdelivr.net/gh/XIU2/UserScript@master/GithubEnhanced-High-Speed-Download.user.js)** [Github 增强 - 高速下载 \[Clone、Release、Raw、Code(ZIP)\]](https://greasyfork.org/scripts/412245)
2729

2830
****

0 commit comments

Comments
 (0)