2013-08-23 91 views
8

假設我在YouTube視頻頁面上加載了一個擴展程序。我注意到,當使用Chrome按鈕來回導航時,擴展程序最有可能獲勝加載。Chrome擴展程序無法在YouTube上的瀏覽器導航中加載

舉個例子,我有2個文件,清單:

{ 
    "name": "back forth", 
    "version": "0.1", 
    "manifest_version": 2, 
    "description": "back forth", 
    "permissions": ["storage", "*://www.youtube.com/watch*"], 
    "content_scripts": [ 
     { 
      "matches": ["*://www.youtube.com/watch*"], 
      "js": ["contentscript.js"] 
     } 
    ] 
} 

和contentscript

alert("loaded"); 

瀏覽時來回警報並不總是露面。我該如何克服這一點,以便擴展每次加載?

+0

相似http://stackoverflow.com/a/34100952/72321 – Dennis

回答

17

YouTube已開始使用基於pushState的導航進行試用。通常,只能通過注入攔截對history.replaceState/history.pushState(或在後臺頁面中使用chrome.webNavigation.onHistoryStateUpdated事件)的調用的代碼,才能在內容腳本中檢測到此類導航。

此答案的其餘部分僅限於YouTube。
YouTube在加載過程中在頁面頂部顯示一個(紅色)進度條。這個進度條是使用CSS過渡動畫的。由於轉換事件冒泡,因此可以將轉換事件偵聽器綁定到<body>,並在這些情況下檢查導航。

你必須要在*://www.youtube.com/*而不是*://www.youtube.com/watch*插入你的內容腳本,因爲pushState的可用於導航從//watch..

function afterNavigate() { 
    if ('/watch' === location.pathname) { 
     alert('Watch page!'); 
    } 
} 
(document.body || document.documentElement).addEventListener('transitionend', 
    function(/*TransitionEvent*/ event) { 
    if (event.propertyName === 'width' && event.target.id === 'progress') { 
     afterNavigate(); 
    } 
}, true); 
// After page load 
afterNavigate(); 

注意:此方法取決於進度條插入的事實。每當Google決定重命名進度欄的ID或完全刪除進度欄時,您的代碼將停止工作。

注2:這僅適用於活動選項卡。如果您需要在選項卡未聚焦時檢測到導航更改,則需要綁定window.onfocuswindow.onblur事件,並檢查document.title是否在這些事件之間發生了更改。

+0

感謝您的回答。使用這種方法它可以工作,但它不像DOMContentLoaded那麼早,看起來這相當於'load',是否有檢測DOMContentLoaded類的點? – Noitidart

+1

@Noitidart如果你真的想盡快得到通知,你可以綁定到'transitionstart'事件,輪詢文檔更改(使用'setTimeout'或'setInterval')。當你找到想要的元素時,取消註冊transitionstart事件+停止輪詢+調用你的自定義回調。爲了確保不浪費CPU週期,將其與transitionend事件結合起來;如果您的輪詢邏輯在此時未檢測到任何內容,請移除事件偵聽器,停止輪詢器並調用回調。 –

+0

天才的想法@RobW謝謝!我嘗試添加'window.onpopstate = function(e){console.log(e)}'我認爲這樣做會做到這一點,但我沒有得到任何回調。 – Noitidart

相關問題