2012-03-28 185 views
47

我試圖讓我的Chrome擴展程序在加載新頁面時運行函數init(),但我在嘗試瞭解如何執行此操作時遇到問題。據我瞭解,我需要做的background.html如下:Chrome擴展代碼和內容腳本vs注入腳本

  1. 使用chrome.tabs.onUpdated.addListener()檢查頁面時 改變
  2. 使用chrome.tabs.executeScript運行一個腳本。

這是我的代碼有:

//background.html 
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { 
    chrome.tabs.executeScript(null, {code:"init();"}); 
}); 

//script.js 
function init() { 
    alert("It works!"); 
} 

我也想知道如果init()函數將有機會獲得我的位於其他JS文件等功能?在Chrome擴展

回答

142

JavaScript代碼可以在下面的組可分爲:

  • 擴展碼 - 所有的完全訪問許可chrome.*的API。
    這包括background page以及可通過chrome.extension.getBackgroundPage()直接訪問它的所有頁面,例如browser pop-ups

  • Content scripts(通過清單文件或chrome.tabs.executeScript) - Partial訪問一些chrome的API的,完全訪問頁面的DOM(任何window對象,包括幀)。
    內容腳本在擴展名和頁面之間的範圍內運行。內容腳本的全局window對象與頁面/擴展的全局名稱空間不同。

  • 注入腳本(通過內容腳本中的this method) - 完全訪問頁面中的所有屬性。 無法訪問任何chrome.* API。
    注入腳本的行爲就像它們被頁面本身包含在一起,並且沒有以任何方式連接到擴展。請參閱this post以瞭解有關各種噴射方法的更多信息。

要從注入腳本發送消息到內容腳本,必須使用事件。以this answer爲例。注意:從一個上下文到另一個上下文擴展的消息自動(JSON) - 串行化和解析


在你的情況,在後臺頁面(chrome.tabs.onUpdated)代碼中的內容腳本script.js評估之前很可能被調用。所以,你會得到一個ReferenceError,因爲init不是。

此外,當您使用chrome.tabs.onUpdated,請確保您測試頁是否滿載,因爲事件觸發兩次:加載之前,並在表面處理:

//background.html 
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { 
    if (changeInfo.status == 'complete') { 
     // Execute some script when the page is fully (DOM) ready 
     chrome.tabs.executeScript(null, {code:"init();"}); 
    } 
}); 
+0

感謝您對'鉻尖.tabs.onUpdated'發射兩次。所以我想我的問題是我將如何注入'init()'?我應該注入所有的JavaScript嗎?當用戶點擊Browser Action圖標時,通常調用'init()','init()'觸發一堆其他函數。 – Jon 2012-03-28 21:51:04

+1

@ user1277607當它必須訪問任何頁面的全局變量時,注入腳本。當'function init'必須訪問頁面和擴展代碼時,請使用內容腳本。請參閱** [鏈接的答案](http://stackoverflow.com/a/9517879/938089?building-a-chrome-extension-inject-code-in-a-page-using-a-content-script)* *查看如何注入腳本,以及** [這個答案](http://stackoverflow.com/a/9636008/938089?chrome-extension-retrieving-gmails-original-message)**的實施指南內容腳本必須訪問頁面的變量。 – 2012-03-28 21:59:38

+0

非常感謝。它工作得很漂亮:) – Jon 2012-03-29 00:01:41

相關問題