2011-09-11 47 views
5

我试图做一个user.js到Facebook的/ messages页面,但看起来像greasemonkey doens't没有通知当导航从/改变/消息。它也出现在其他内部页面中。 首先,我认为这是由AJAX导航引起的,但URL更改(不是哈希部分),所以这是正常导航,对吧?为什么greasemonkey在facebook中没有检测到页面更改?

这是我使用的测试页:

// ==UserScript== 
// @name   Test 
// @namespace  none 
// @description just an alert when page changes 
// @include  http*://www.facebook.com/* 
// ==/UserScript== 

alert(location.href); 

我该如何正确检测网页的变化?


火狐版本:6.0.2

Greasemonkey的版本:0.9.11

+0

这个问题可能是相关的。 http://stackoverflow.com/questions/3522090/event-when-window-location-href-changes – bronsoja

回答

8

对于支持该功能的浏览器,包括Firefox 4+,脸谱采取HTML5 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。

+0

我不认为你必须使用代理 - 你不能只处理'window.onpopstate'事件? – Coderer

+0

只有当您使用向前或向后按钮(或向前和向后API调用)时,'onpopstate'才会检测到pushState何时被调用新页面。 – rampion

+0

这种方法的问题是新的页面元素不一定在'old.apply(window.history,arguments)'返回后加载,所以它可能没有准备好供脚本处理。 – rampion

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”事件对于正在重新插入到已使用脚本修改的页面的内容,因此您需要确保检查通常对页面所做的任何更改是否已完成,以防止插入重复控件或任何其他内容。

0

+1 to @rampion suggestions。我想执行简单的重定向,但在页面上寻找元素并不是非常有用,因为我不想无意间重定向用户。

反正,我用这个代码安装监听器哪里需要在用户点击特别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

我找不到任何方法来可靠地检测URL的变化,无论使用该网站来改变URL的方法。 @andy-e的方法看起来很棒,但由于某种原因,对我而言并不适用。也许我无法正确地创建脚本@grant标记。

相关问题