2012-03-28 191 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

相关问题