使用背景指令碼管理事件

擴充功能是用來修改或改善 Chrome 瀏覽體驗的事件型程式。事件是瀏覽器觸發條件,例如前往新頁面、移除書籤或關閉分頁。擴充功能會使用背景指令碼監控這些事件,然後以指定指示回應。

系統會在需要時載入背景頁面,並在閒置時卸載。以下列舉幾個事件:

  • 擴充功能會先安裝或更新到新版本,
  • 背景頁面正在監聽事件,並傳送事件。
  • 內容指令碼或其他擴充功能會傳送訊息
  • 擴充功能中的另一個檢視畫面 (例如彈出式視窗),會呼叫 runtime.getBackgroundPage

載入完成後,背景頁面只要執行動作 (例如呼叫 Chrome API 或發出網路要求) 就會持續運作。此外,除非所有可見的檢視畫面和所有訊息通訊埠都關閉,否則背景頁面不會卸載。請注意,開啟檢視畫面並不會導致事件頁面載入,但只會禁止事件頁面載入後關閉。

有效的背景指令碼會保持暫停狀態,直到監聽到火災事件、根據指定指示做出回應後,再卸載。

註冊背景指令碼

背景指令碼會透過 "background" 欄位下的資訊清單登錄。它們會列於 "scripts" 鍵之後的陣列中,而 "persistent" 應指定為 false。

{
  "name": "Awesome Test Extension",
  ...
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  ...
}

您可以為模組化程式碼註冊多個背景指令碼。

{
    "name": "Awesome Test Extension",
    ...
    "background": {
      "scripts": [
        "backgroundContextMenus.js",
        "backgroundOmniBox.js",
        "backgroundOauth.js"
      ],
      "persistent": false
    },
    ...
  }

如果擴充功能目前使用永久的背景頁面,請參閱背景遷移指南,瞭解如何改用非永久模型。

初始化擴充功能

監聽 runtime.onInstalled 事件,在安裝時初始化擴充功能。使用此事件可設定狀態或一次性初始化,例如內容選單

chrome.runtime.onInstalled.addListener(function() {
  chrome.contextMenus.create({
    "id": "sampleContextMenu",
    "title": "Sample Context Menu",
    "contexts": ["selection"]
  });
});

設定事件監聽器

為擴充功能依附的事件建立背景指令碼。定義與函式相關的事件後,背景指令碼可暫時關閉,直到事件觸發為止,避免擴充功能缺少重要觸發條件。

事件監聽器必須在網頁開頭同步註冊。

chrome.runtime.onInstalled.addListener(function() {
  chrome.contextMenus.create({
    "id": "sampleContextMenu",
    "title": "Sample Context Menu",
    "contexts": ["selection"]
  });
});

// This will run when a bookmark is created.
chrome.bookmarks.onCreated.addListener(function() {
  // do something
});

請勿以非同步方式註冊事件監聽器,否則無法正確觸發事件監聽器。

chrome.runtime.onInstalled.addListener(function() {
  // ERROR! Events must be registered synchronously from the start of
  // the page.
  chrome.bookmarks.onCreated.addListener(function() {
    // do something
  });
});

擴充功能可以呼叫 removeListener,將事件監聽器從背景指令碼中移除。如果移除所有事件的監聽器,Chrome 將不再為該事件載入擴充功能的背景指令碼。

chrome.runtime.onMessage.addListener(function(message, sender, reply) {
    chrome.runtime.onMessage.removeListener(event);
});

篩選事件

使用支援事件篩選器的 API,將事件監聽器限制為擴充功能重視的情況。如果擴充功能正在監聽 tabs.onUpdated 事件,請嘗試改用搭配篩選器的 webNavigation.onCompleted 事件,因為分頁 API 不支援篩選器。

chrome.webNavigation.onCompleted.addListener(function() {
    alert("This is my favorite website!");
}, {url: [{urlMatches : 'https://www.google.com/'}]});

回應聽眾

事件監聽器會在事件觸發後觸發功能。如要回應事件,請在事件監聽器事件內建構所需回應。

chrome.runtime.onMessage.addListener(function(message, callback) {
  if (message.data == "setAlarm") {
    chrome.alarms.create({delayInMinutes: 5})
  } else if (message.data == "runLogic") {
    chrome.tabs.executeScript({file: 'logic.js'});
  } else if (message.data == "changeColor") {
    chrome.tabs.executeScript(
        {code: 'document.body.style.backgroundColor="orange"'});
  };
});

卸載背景指令碼

資料應定期保留,確保在擴充功能當機但未收到 onSuspend 時,不會遺失重要資訊。請使用 storage API 來解決這個問題。

chrome.storage.local.set({variable: variableInformation});

如果擴充功能使用訊息傳遞,請確認所有通訊埠均已關閉。背景指令碼必須等到所有訊息通訊埠都關閉後,才能卸載。監聽 runtime.Port.onDisconnect 事件就能提供深入分析資訊,瞭解開放通訊埠關閉的時間。您可以使用 runtime.Port.disconnect 手動關閉這些程式。

chrome.runtime.onMessage.addListener(function(message, callback) {
  if (message == 'hello') {
    sendResponse({greeting: 'welcome!'})
  } else if (message == 'goodbye') {
    chrome.runtime.Port.disconnect();
  }
});

透過監控擴充功能項目出現且從 Chrome 工作管理員消失的時間,您可以觀察背景指令碼的生命週期。

ALT_TEXT_HERE

按一下 Chrome 選單,將遊標懸停在更多工具上,然後選取「工作管理員」,即可開啟工作管理員。

背景指令碼會在閒置幾秒鐘後自行卸載。如果需要最後幾分鐘清理,請監聽 runtime.onSuspend 事件。

chrome.runtime.onSuspend.addListener(function() {
  console.log("Unloading.");
  chrome.browserAction.setBadgeText({text: ""});
});

不過,持續保存資料應比依賴 runtime.onSuspend 更優先。但這項功能無法盡可能減少需要執行的清理作業,而且在發生當機時亦無法提供協助。