2011-09-11 79 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標記。

相關問題