【油猴脚本】把“勛章信息 - 即時動態”插入勋章商城页
动机有一个官方的勋章交易帖,就在勋章公会板块下的“【勛章信息 - 即時動態】”这里。哪怕是对勋章已经有了一定的了解,也可能不常看,甚至根本不知道有这个帖子。
由于论坛是基于Discuz!架构,没法达到即时通讯软件那样的时效性,所以在这里回复内容已经算是最高效的方法了。
功能
这个脚本在“勋章商城”主页面增加了一个小窗口,会直接出现在 https://www.gamemale.com/wodexunzhang-showxunzhang.html 页面的 #div.myfenleilist.clearfix.myfenleilist_1 元素前。这张图片会展示地更加一目了然:
代码
@Name@Match@Icon
// ==UserScript==
// @name 勋章:把[勛章信息 - 即時動態]插入勋章商城页
// @namespace https://www.gamemale.com/
// @version 1.0.0
// @description在访问“我的勋章”页面时,将论坛页的 #livethread(即时动态)插入到 #div.myfenleilist.clearfix.myfenleilist_1 前,并尽量保留全部功能(刷新、回复等)。
// @match https://www.gamemale.com/wodexunzhang-showxunzhang.html
// @run-at document-end
// @grant none
// ==/UserScript==
(function () {
'use strict';
const SOURCE_URL = 'https://www.gamemale.com/forum-128-1.html';
const TARGET_SELECTOR ='div.myfenleilist.clearfix.myfenleilist_1';
const INSERT_BEFORE = true;
function log(...args) {
console.log('', ...args);
}
function waitForElement(selector, timeoutMs = 15000) {
return new Promise((resolve, reject) => {
const el = document.querySelector(selector);
if (el) return resolve(el);
const obs = new MutationObserver(() => {
const el2 = document.querySelector(selector);
if (el2) {
obs.disconnect();
resolve(el2);
}
});
obs.observe(document.documentElement, { childList: true, subtree: true });
setTimeout(() => {
obs.disconnect();
reject(new Error('Timeout waiting for ' + selector));
}, timeoutMs);
});
}
function createHostBox() {
const host = document.createElement('div');
host.id = 'gm_livethread_host';
host.style.margin = '12px 0';
host.style.border = '1px solid #e5e5e5';
host.style.borderRadius = '8px';
host.style.overflow = 'hidden';
host.style.background = '#fff';
const iframe = document.createElement('iframe');
iframe.id = 'gm_livethread_iframe';
iframe.src = SOURCE_URL;
iframe.style.width = '100%';
iframe.style.border = '0';
iframe.style.display = 'block';
iframe.style.height = '0px'; // 初始高度,加载后会自动调
iframe.referrerPolicy = 'no-referrer-when-downgrade';
host.appendChild(iframe);
return { host, iframe };
}
function cropIframeToLiveThread(iframe) {
iframe.addEventListener('load', () => {
try {
const doc = iframe.contentDocument;
const win = iframe.contentWindow;
if (!doc) return;
const live = doc.querySelector('#livethread');
if (!live) {
log('iframe内未找到 #livethread,可能页面结构变了。');
return;
}
// 注入样式:隐藏其他所有内容,只展示 #livethread
const style = doc.createElement('style');
style.textContent = `
html, body { margin: 0 !important; padding: 0 !important; background: transparent !important; }
body > * { display: none !important; }
#livethread { display: block !important; margin: 0 !important; }
/* 让它在“我的勋章”页更贴合 */
#livethread { padding: 10px 12px !important; }
#livethread .livethreadtitle img { vertical-align: middle; }
`;
doc.head.appendChild(style);
// 把 #livethread 挪到 body 直接子级(避免它原本嵌套导致 body>* 隐藏规则误伤)
// 注意:这样仍然在同一个页面环境内,功能不会丢。
if (live.parentElement !== doc.body) {
doc.body.appendChild(live);
}
// 自动高度:随内容变化而变
const resize = () => {
// 给一点余量,避免滚动条闪烁
const h = Math.max(200, live.scrollHeight + 24);
iframe.style.height = h + 'px';
};
resize();
// 监听内容变化:新回复、展开等
const mo = new MutationObserver(() => resize());
mo.observe(live, { childList: true, subtree: true, characterData: true });
// 更稳妥:ResizeObserver(如果浏览器支持)
if ('ResizeObserver' in win) {
const ro = new win.ResizeObserver(() => resize());
ro.observe(live);
}
// 兜底:定时修正(避免某些异步资源加载导致高度不准)
let ticks = 0;
const timer = win.setInterval(() => {
resize();
ticks += 1;
if (ticks >= 20) win.clearInterval(timer);
}, 500);
log('已裁剪并嵌入 #livethread');
} catch (e) {
log('裁剪iframe失败:', e);
// 常见原因:X-Frame-Options / CSP 阻止、或跨域(一般同域不会)
}
});
}
(async function main() {
// 避免重复插入
if (document.querySelector('#gm_livethread_host')) return;
let target;
try {
target = await waitForElement(TARGET_SELECTOR);
} catch (e) {
console.warn(' 未找到网页②插入点元素:', TARGET_SELECTOR, e);
return;
}
const { host, iframe } = createHostBox();
// 插入到目标前
if (INSERT_BEFORE && target.parentNode) {
target.parentNode.insertBefore(host, target);
} else {
target.prepend(host);
}
cropIframeToLiveThread(iframe);
})();
})();
星象占卜 对于有比较强交换意愿的坛友来说很有价值了 其实可以关注帖子,不过只能关注到最新回复而且很多都是没用消息所以就放弃了
看到这个脚本感觉眼前一亮=3=~ 补货之后是勋章交换的高峰期,可以选择在那个时间点打开这个脚本,能更方便一点呢https://img.gamemale.com/album/202508/31/092111u1rzt6h6tzeezd11.jpg 大佬好厉害!!!看起来很有用的样子!!! 把勋章交换的信息和商城结合倒是方便了不少 闲鱼换果壳,果隆,武士刀,秘银甲 致远星战况激烈,我也是火星人……原来还真的有坛内勋章交易渠道,还以为必须进什么群之类的,火速上了脚本 这样的话,也是很方便的能看到交易信息了{:6_163:} 还真没什么注意有这个勋章交易帖~小插件方进去确实更直观不少惹呢~感谢大佬分享;P 才知道還有交易貼哦,感謝大佬。 以前没怎么注意过还能交换,在勋章商城上面信息就一目了然了啊:loveliness: 更完善了欸~咱确实是从没点开过那个帖子的(´×ω×`) 挺不错的,信息通达,可以随时知道勋章交易动态了 感觉是好东西啊这,只不过最近大家的交换欲望确实是低了不少,更何况我想要的目前基本没什么人换:'( 是不是可以直接给论坛加这个功能,就不用再弄油猴脚本了 好东西啊,一直有想要的勋章,这下可以时时关注了 有用尤其是对随时了解勋章信息的 https://img.gamemale.com/album/202508/27/154618wt52fzit25qb9aaf.jpg倒是很方便和别人交换勋章了 这样的话其实我觉得只限定在二手市场会更好,商城抢勋章时加载容易浪费时间来着,