我正在尝试编写一个用户脚本来重定向某些网页(包括 Facebook)的 URL。我(有限)的理解是,用户脚本没有直接的方法来告诉 URL 何时发生变化(有
window.onurlchange
,但这只适用于 Tampermonkey。我在 Firefox 上使用 Firemonkey)。我将脚本设置为在 document-start
运行,但是当网页导航到新 URL 时,这似乎并不总是运行(可能是在同一域中时?)
我已经在 stackoverflow 上阅读了一些解决方法,您可以在下面我的用户脚本的代码中看到:
// ==UserScript==
// @name Redirect
// @match https://www.facebook.com/groups/*
// @exclude https://www.facebook.com/groups/*/*/
// @run-at document-start
// ==/UserScript==
function fireRedirect() {
let mHref = window.location.href;
if ( !mHref.includes("sorting_setting") ) {
window.location = mHref.concat("?sorting_setting=CHRONOLOGICAL");
}
}
window.onpopstate = fireRedirect();
new MutationObserver(mutationsList => {
console.log(mutationsList[0].target.textContent);
fireRedirect();
})
.observe(
document.querySelector('title'),
{subtree: true, childList: true}
);
fireRedirect();
如果我从地址栏手动导航到像 www.facebook.com/groups/examplegroupname 这样的 URL,则会触发此操作,但如果我在主 www.facebook.com 主页上,并且单击链接转到 www.facebook.com/groups/examplegroupname,脚本不会运行。如果我只是刷新页面,然后它将运行。 (这也是我知道 @exclude 不是问题所在的方式。)
有没有更好的方法来处理这个问题?
我认为对此没有通用的解决方案,但对于上面提供的情况,使用突变观察器来检测标题更改似乎是最好的方法。阻止其工作的唯一问题是这一行:
// @run-at document-start
似乎在文档开始时(当 dom 仍在加载时)注入脚本并不能正确注入突变观察器。要修复它,我们可以使用
document-end
来代替(在 dom 完成加载时运行)。以下是修改后的脚本(在 FireMonkey 上测试):
// ==UserScript==
// @name Redirect
// @match https://www.facebook.com/*
// @exclude https://www.facebook.com/groups/*/*/
// @run-at document-end
// ==/UserScript==
function fireRedirect() {
let mHref = window.location.href;
let mPaths = window.location.pathname.split("/").filter(path => !!path);
if ( !mHref.includes("sorting_setting") && mPaths[0] === "groups" && mPaths.length === 2 ) {
window.location = mHref.concat("?sorting_setting=CHRONOLOGICAL");
}
}
new MutationObserver(mutationsList => {
console.log(mutationsList[0].target.textContent);
fireRedirect();
})
.observe(
document.querySelector('title'), {
subtree: true,
childList: true
}
);
fireRedirect();