2012-04-13 85 views
3

我正在尋找將Safari中的新選項卡重定向到某個URL,實質上是更改了默認的新選項卡頁面。但是,我不想重定向通過以下鏈接打開的新選項卡。Safari擴展:全新選項卡的事件?

Windows and Tabs API描述標籤「開放」的事件,但是當任何新標籤頁中打開(包括新的標籤從鏈接打開),這些被解僱。

有沒有辦法爲只有通過點擊新選項卡按鈕創建的選項卡捕獲新選項卡事件?

在此先感謝!

回答

6

在您的open事件處理程序中,首先檢查事件目標是否爲選項卡。如果是,請在該選項卡上註冊beforeNavigate事件的事件處理程序。如果beforeNavigate事件在50毫秒內未觸發,還設置一個超時註銷處理程序。例如:

function handleOpen(e) { 
    if (e.target instanceof SafariBrowserTab) { 
     e.target.addEventListener('beforeNavigate', handleBeforeNavigate, false); 
     setTimeout(function() { 
      e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false); 
     }, 50); 
    } 
} 

現在,還有爲beforeNavigate事件三個相關的可能的結果如下一個標籤頁中打開事件。

案例1beforeNavigate事件不會在超時時間內觸發。這通常意味着標籤是空的。空標籤不能是鏈接點擊的結果,所以我們可以把一些代碼在超時功能做任何我們喜歡它:

function handleOpen(e) { 
    if (e.target instanceof SafariBrowserTab) { 
     e.target.addEventListener('beforeNavigate', handleBeforeNavigate, false); 
     setTimeout(function() { 
      e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false); 
      takeOverTab(); 
     }, 50); 
    } 
} 

案例2:本beforeNavigate事件將觸發,其url財產的值將爲null。這意味着該選項卡將加載「熱門站點」頁面或「書籤」頁面(新選項卡的選項中包含兩個特殊的Safari頁面)。就像一個空的標籤,這樣的標籤不可能是鏈接點擊的結果,所以我們可以按照我們喜歡的標籤來做。例如:

function handleBeforeNavigate(e) { 
    e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false); 
    if (e.url === null) { 
     takeOverTab(); 
    } 
} 

案例3:本beforeNavigate會火,其url值將是一個非空字符串:那就是,一個實際的URL。這是一個棘手的情況,因爲選項卡可能是由鏈接點擊,新選項卡命令(如果用戶已配置Safari以在他的主頁上打開新選項卡)或另一個應用程序或擴展的操作產生的。讓我們來看一下標籤是鏈接點擊案例3A的結果的情況;它是新選項卡命令的結果案例3B;和其他應用案例案例3C。

我想不出一種區分3B和3C的方法。如果真的沒有辦法區分這兩種情況,那麼它可能會對您的應用程序非常不利,因爲您可能不希望重定向由其他應用程序打開的選項卡。

如果您不在乎您的應用是否會干擾3C標籤,至少有一種方法可以告訴3B/3C標籤中的3A標籤。這是對我而言的方式:

  • 在每個頁面中使用注入的腳本來監聽鏈接點擊。點擊鏈接後,將URL和點擊時間轉發到全局頁面,以便將來參考。例如:

    function handleMessage(e) { 
        if (e.name === 'linkClicked') { 
         lastClickedLinkUrl = e.message.url; 
         lastLinkClickTime = e.message.clickTime; 
        } 
    } 
    
  • 在你beforeNavigate處理程序,測試該事件的url值是否是從最後點擊鏈接的URL不同。如果是,則新選項卡不是由該鏈接點擊產生的,因此它可能不是由任何鏈接點擊產生的。如果兩個URL相同,請檢查自上次鏈接點擊以來是否已超過100毫秒。如果是這種情況,這可能只是一個巧合,因爲這些URL是相同的,所以您可以再次推斷新標籤不是由鏈接點擊產生的。例如:

    function handleBeforeNavigate(e) { 
        e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false); 
        if (e.url === null) { 
         takeOverTab(); 
        } else if (e.url !== lastClickedLinkUrl || (new Date) - lastLinkClickTime > 100) { 
         takeOverTab(); 
        } 
    } 
    

注意,該檢測方法並非萬無一失。可能有很多方法可能會出錯。不過,我希望這有助於。

+0

非常感謝!我會給你一個鏡頭,讓你知道它是如何發展的。 – Kevin 2012-04-16 18:38:22

+0

再次感謝!你的代碼非常有用,特別是記錄鏈接點擊的想法(案例3A)。 – Kevin 2012-05-07 22:56:09

+0

你能告訴我應該如何監聽inject.js中的點擊嗎? – itzhar 2015-04-27 09:13:18