2012-03-28 5 views
47

Ich versuche, meine Chrome-Erweiterung, um die Funktion init() immer wenn eine neue Seite geladen wird, aber ich habe Probleme zu versuchen, zu verstehen, wie dies zu tun. Von dem, was ich verstehe, muß ich folgend in background.html tun:Chrome Extension-Code vs Content-Skripts vs injizierten Skripts

  1. Verwenden chrome.tabs.onUpdated.addListener() überprüfen, wenn die Seite
  2. Verwendung geändert chrome.tabs.executeScript ein Skript auszuführen.

Dies ist der Code, den ich habe:

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

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

Ich bin auch gefragt, ob die init() Funktion den Zugriff auf meine anderen Funktionen in anderen JS-Dateien befinden haben wird?

Antwort

142

JavaScript-Code in Chrome-Erweiterungen können in folgende Gruppen unterteilt werden:

  • Dateisuffix - Voller Zugriff auf alle zulässigen chrome.* APIs.
    Dazu gehören die , und alle Seiten, die über chrome.extension.getBackgroundPage() direkten Zugriff darauf haben, wie die browser pop-ups.

  • Content scripts (über die Manifest-Datei oder chrome.tabs.executeScript) - Partial Zugang zu einigen der chrome APIs, vollen Zugriff auf die DOM-Seite (nicht einem der window Objekte, einschließlich Frames).
    Inhaltsskripts werden in einem Bereich zwischen der Erweiterung und der Seite ausgeführt. Das globale Objekt window eines Inhaltsskripts unterscheidet sich vom globalen Namespace der Seite/Erweiterung.

  • Injizierte Skripte (über this method in einem Inhaltsskript) - Voller Zugriff auf alle Eigenschaften auf der Seite. Kein Zugriff auf eine der chrome.* APIs.
    Injizierte Skripts verhalten sich so, als wären sie von der Seite selbst enthalten und sind in keiner Weise mit der Erweiterung verbunden. Weitere Informationen zu den verschiedenen Injektionsmethoden finden Sie unter this post.

Um eine Nachricht vom injizierten Skript an das Inhaltsskript zu senden, müssen Ereignisse verwendet werden. Ein Beispiel finden Sie in this answer. Hinweis: Nachrichten, die innerhalb einer Erweiterung von einem Kontext in einen anderen transportiert werden, werden automatisch (JSON) -serialisiert und geparst. genannt wahrscheinlich


In Ihrem Fall wird der Code im Hintergrund Seite (chrome.tabs.onUpdated), bevor die Content-Skript script.js ausgewertet wird. Sie erhalten also eine ReferenceError, weil init nicht ist.

Auch wenn Sie chrome.tabs.onUpdated verwenden, stellen Sie sicher, dass Sie testen, ob die Seite vollständig geladen ist, weil das Ereignis ausgelöst wird zweimal: Vor Ladung und Ziel:

//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

Sie für die Spitze danken über 'Chrom .tabs.onUpdated' wird zweimal ausgelöst. Also meine Frage ist, wie würde ich 'init()' injizieren? Sollte ich alle meine JavaScripts injizieren? 'init()' wird normalerweise aufgerufen, wenn der Benutzer auf das Browseraktionssymbol klickt, und 'init()' löst eine Reihe anderer Funktionen aus. – Jon

+1

@ user1277607 Wenn es auf eine der globalen Variablen der Seite zugreifen muss, injizieren Sie das Skript. Wenn 'function init' auf den Seiten- und Erweiterungscode zugreifen muss, verwenden Sie ein Inhaltsskript. Siehe die ** [verknüpfte Antwort] (http://stackoverflow.com/a/9517879/938089?building-a-chrome-extension-inject-code-in-a-a-page-using-a-content-script) * * um zu sehen, wie Skripte injiziert werden, und ** [http://stackoverflow.com/a/9636008/938089?chrome-extension-retrieving-gmails-original-message] ** für eine Richtlinie zur Implementierung eines Inhaltsskript, das auf die Variablen der Seite zugreifen muss. –

+0

vielen Dank. Es hat wunderbar funktioniert :) – Jon