我试图在facebook中对user.js进行/ message页面,但看起来像在导航从/到/消息更改时不会注意到。它也出现在其他内部页面中。 首先我认为它是由AJAX导航引起的,但URL改变了(不是散列部分),所以这是正常的导航,对吧?
这是我使用的测试页面:
// ==UserScript==
// @name Test
// @namespace none
// @description just an alert when page changes
// @include http*://www.facebook.com/*
// ==/UserScript==
alert(location.href);
如何正确检测页面更改?
Firefox版本:6.0.2
Greasemonkey版本:0.9.11
答案 0 :(得分:9)
对于支持它的浏览器,包括Firefox 4+,Facebook利用HTML5 History API。此API允许使用history.pushState()
方法更改位置,但实际上不会发生导航。虽然页面似乎已经发生了变化,但所有发生的事情都是幕后的ajax调用,它会改变大部分内容。
如果您想捕获此更改,则必须使用自己的函数代理pushState()
方法:
(function (old) {
window.history.pushState = function () {
old.apply(window.history, arguments);
alert(window.location.href);
}
})(window.history.pushState);
在https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history了解有关历史记录API的更多信息。
答案 1 :(得分:3)
另一种方法是为页面挂钩DOMNodeInserted
,并在插入后路径与/messages
匹配时运行:
// ==UserScript==
// ...
// @include https://www.facebook.com/*
// ...
// ==/UserScript==
var url = document.location.toString();
function scriptBody(){
if (!url.match(/facebook.com\/messages/)) return;
// ...
// do stuff
// ...
});
scriptBody(); // run on initial page load
document.querySelector('html').addEventListener('DOMNodeInserted', function(ev){
var new_url = document.location.toString();
if (url == new_url) return; // already checked or processed
url = new_url;
scriptBody(); // run when URL changes
});
请注意,如果您的用户使用前进/后退按钮,您可能会为正在重新插入已使用脚本修改的页面的内容获取“DOMNodeInserted”事件,因此您需要确保检查是否通常对页面进行了任何更改,以防止插入重复控件或其他任何内容。
答案 2 :(得分:0)
+1 @rampion建议。我想执行一个简单的重定向,在页面上查找元素并不是很有用,因为我不想无意中重定向用户。
无论如何,我使用此代码安装了一个侦听器,当用户点击特定href
的链接时,该侦听器会根据需要重定向:
if (document.addEventListener ){
document.addEventListener("click", function(event) {
var targetElement = event.target || event.srcElement;
// TODO: support deeper search for parent element with a href attribute
var href = targetElement.getAttribute('href') || targetElement.parentElement.getAttribute('href') ;
if (href && videoURLRe.test(href)) {
var target = "";
if (href.indexOf("/") == 0) {
target = "https://m.facebook.com" + href
} else {
target = href.replace("www.facebook", "m.facebook");
}
window.location.assign(target);
}
}, true);
}
工作非常整洁。我必须想出正确的第三个addEventListener参数,以便我的侦听器在任何其他参数之前执行。
有关完整的脚本,请查看https://greasyfork.org/en/scripts/8176-switch-to-mobile-version-on-facebook-video-page
无论网站使用何种方法更改该网址,我都无法找到可靠地检测网址更改的方法。 @ andy-e方法看起来很棒但是由于某种原因对我不起作用。也许我无法正确制作脚本@grant
标签。