将消息传递给 Chrome 扩展内容脚本,而不将其指定为后台脚本
Pass message to Chrome extension content script without specifying it as a background script
我正在尝试向 Chrome 上下文菜单添加一项功能,以从所选文本添加待办事项。我从 background.js
的上下文菜单中传递选定的文本,如下所示:
function onClickHandler(info, tab) {
chrome.extension.sendMessage(info.selectionText, function(){});
}
chrome.contextMenus.onClicked.addListener(onClickHandler);
chrome.runtime.onInstalled.addListener(function() {
chrome.contextMenus.create({"title": "Add: %s", "contexts":["selection"]});
});
然后在 app.js
内容脚本中收听消息:
chrome.extension.onMessage.addListener(function(task, sender, sendResponse) {
Task.setNewTask(task); // Saves the task in storage
});
当我的扩展程序在选项卡中打开时,消息会被正确接收,但当它关闭时,消息将无法正常工作。这是因为我没有在 manifest.json
:
中将 app.js
设置为后台脚本
"permissions": [
"storage",
"contextMenus",
"tabs",
"notifications"
],
"background": {
"scripts": ["background.js"]
}
我不将 app.js
作为后台脚本的原因是因为它包含我应用程序的其余代码,当尝试在后台 运行 时会产生错误而没有 DOM.
不幸的是,我无法轻松地在 background.js
文件中进行存储,因为我需要访问内容脚本中的函数 Task.setNewTask
。
我的应用程序有多种存储数据的方法,具体取决于环境——如果我必须将此逻辑放在 background.js
中,将会有很多重复。
我试过将我的应用程序作为背景页面:
"background": {
"page": "index.html"
},
然后在页面底部包含两个脚本:
<script src="background.js"></script>
<script src="js/app.js"></script>
</body>
但是我的应用程序仍然不会在后台添加新任务。
有没有办法:
- 保持
background.js
尽可能简单,
- 不包括
app.js
作为后台脚本,
- 当
app.js
不在后台时仍然收到消息?
哦,亲爱的。您在哪里找到要修改的基本代码?
chrome.extension.sendMessage
/chrome.extension.onMessage
已弃用 甚至不再出现在文档中。
但即使您将它们更改为适当的 chrome.runtime
等效项,与内容脚本通信仍然是错误的功能。
您的原始代码失败,因为 chrome.runtime.sendMessage
(和 已弃用 chrome.extension
等效)仅发送到扩展页面(例如chrome-extension://yourid/
起源),而不是内容脚本。
您修改的代码失败,因为消息传递永远不会将消息发送到 运行 来自的相同 JS 上下文。
您需要的是 chrome.tabs.sendMessage
函数,它允许您指定上下文脚本所在的选项卡。如果您想将它发送到当前选项卡,它会作为参数传递给 onClicked
侦听器。
function onClickHandler(info, tab) {
chrome.tabs.sendMessage(tab.id, info.selectionText);
}
在上下文脚本方面,不要忘记更改为 chrome.runtime
:
chrome.runtime.onMessage.addListener(function(task, sender, sendResponse) {
Task.setNewTask(task); // Saves the task in storage
});
我正在尝试向 Chrome 上下文菜单添加一项功能,以从所选文本添加待办事项。我从 background.js
的上下文菜单中传递选定的文本,如下所示:
function onClickHandler(info, tab) {
chrome.extension.sendMessage(info.selectionText, function(){});
}
chrome.contextMenus.onClicked.addListener(onClickHandler);
chrome.runtime.onInstalled.addListener(function() {
chrome.contextMenus.create({"title": "Add: %s", "contexts":["selection"]});
});
然后在 app.js
内容脚本中收听消息:
chrome.extension.onMessage.addListener(function(task, sender, sendResponse) {
Task.setNewTask(task); // Saves the task in storage
});
当我的扩展程序在选项卡中打开时,消息会被正确接收,但当它关闭时,消息将无法正常工作。这是因为我没有在 manifest.json
:
app.js
设置为后台脚本
"permissions": [
"storage",
"contextMenus",
"tabs",
"notifications"
],
"background": {
"scripts": ["background.js"]
}
我不将 app.js
作为后台脚本的原因是因为它包含我应用程序的其余代码,当尝试在后台 运行 时会产生错误而没有 DOM.
不幸的是,我无法轻松地在 background.js
文件中进行存储,因为我需要访问内容脚本中的函数 Task.setNewTask
。
我的应用程序有多种存储数据的方法,具体取决于环境——如果我必须将此逻辑放在 background.js
中,将会有很多重复。
我试过将我的应用程序作为背景页面:
"background": {
"page": "index.html"
},
然后在页面底部包含两个脚本:
<script src="background.js"></script>
<script src="js/app.js"></script>
</body>
但是我的应用程序仍然不会在后台添加新任务。
有没有办法:
- 保持
background.js
尽可能简单, - 不包括
app.js
作为后台脚本, - 当
app.js
不在后台时仍然收到消息?
哦,亲爱的。您在哪里找到要修改的基本代码?
chrome.extension.sendMessage
/chrome.extension.onMessage
已弃用 甚至不再出现在文档中。
但即使您将它们更改为适当的 chrome.runtime
等效项,与内容脚本通信仍然是错误的功能。
您的原始代码失败,因为
chrome.runtime.sendMessage
(和 已弃用chrome.extension
等效)仅发送到扩展页面(例如chrome-extension://yourid/
起源),而不是内容脚本。您修改的代码失败,因为消息传递永远不会将消息发送到 运行 来自的相同 JS 上下文。
您需要的是 chrome.tabs.sendMessage
函数,它允许您指定上下文脚本所在的选项卡。如果您想将它发送到当前选项卡,它会作为参数传递给 onClicked
侦听器。
function onClickHandler(info, tab) {
chrome.tabs.sendMessage(tab.id, info.selectionText);
}
在上下文脚本方面,不要忘记更改为 chrome.runtime
:
chrome.runtime.onMessage.addListener(function(task, sender, sendResponse) {
Task.setNewTask(task); // Saves the task in storage
});