我试图从面板脚本(popup.js)发送一个click事件到内容脚本(content.js),这是我尝试过的代码。所需的输出不会在控制台上打印。
popup.html
<button id="start-btn" onclick="myFunction()">Clip</button>
popup.js
function myFunction() {
addon.port.emit('message', 'hello world');
}
content.js
self.port.on("message", function(text) {
console.log(text);
});
index.js(主)
var panels = require("sdk/panel");
var self = require("sdk/self");
var data = require("sdk/self").data;
var pageMod = require("sdk/page-mod");
pageMod.PageMod({
include: "*",
contentScriptWhen: 'ready',
contentScriptFile:
[data.url("js/jquery-3.1.0.min.js"),
data.url("js/content.js")]
});
var panel = panels.Panel({
contentURL: self.data.url("popup.html"),
onHide: handleHide
});
答案 0 :(得分:1)
为了将消息从sdk/panel传递到内容脚本,您必须通过后台脚本进行转发。因此,通信看起来像面板脚本⟷背景脚本⟷内容脚本。
由于您可能拥有许多不同的内容脚本,因此这很复杂。每个选项卡甚至可以有多个内容脚本。因此,您必须在附加内容脚本时跟踪它们并使其保持井井有条,至少通过选项卡。这样您就可以最终将消息中继到正确的内容脚本。
面板因为是用户界面,通常会想要向活动标签发送消息。另一方面,它可能希望将消息发送到特定选项卡或特定选项卡中的特定脚本。您需要确定加载项所需的粒度级别。
以下脚本将通过Page-Mod将内容脚本加载到每个选项卡中(根据包含的URL为'*'
的问题)。每个内容脚本都由选项卡跟踪。没有规定每个选项卡有多个内容脚本。应该真正监听Tab事件,以使内容脚本列表中的条目无效。但是,在此示例中未执行此操作。单击ActionButton后将显示该面板。单击面板中的按钮时,面板会向后台脚本发送relay
消息,然后解码relay
消息并将其发送到相应的内容脚本。
我为relay
消息强加了一种格式。那种格式是:
{
target: {
type:targetType, //Currently, the only valid targetType is 'content'.
id:targetId //A tab ID, or 'activeTab'
},
emitType:emitType, //The type of emit message that will be sent.
data:message //The contents of the relayed message.
}
代码:
index.js :
var panels = require("sdk/panel");
var self = require("sdk/self");
var data = require("sdk/self").data;
var pageMod = require("sdk/page-mod");
var tabs = require("sdk/tabs");
//Open the Browser Console
var utils = require('sdk/window/utils');
activeWin = utils.getMostRecentBrowserWindow();
activeWin.document.getElementById('menu_browserConsole').doCommand();
var workers={};
//PageMod
pageMod.PageMod({
include: "*",
contentScriptWhen: 'ready',
contentScriptFile: [
//data.url("js/jquery-3.1.0.min.js"),
data.url("js/content.js")
],
onAttach: attachWorker
});
function attachWorker(worker){
if(!workers.hasOwnProperty(worker.tab.id)){
//Have not previously had this tab
workers[worker.tab.id]={};
}
//This does not account for the possibility of having multiple workers
// per tab at one time.
//Remember the worker
console.log('index.js: Attached worker on tab=',worker.tab.id);
workers[worker.tab.id].worker = worker;
}
//Panel
var panel = panels.Panel({
contentURL: self.data.url("popup.html"),
onHide: handleHide
});
panel.port.on('message',receiveMessage);
panel.port.on('relay',receiveRelay);
function handleHide(){
}
function receiveMessage(message){
console.log('index.js: received message:',message);
}
function receiveRelay(data){
console.log('index.js: received relay:',data);
let emitPort;
let targetId;
if(typeof data !== 'object'){
console.log('index.js: received relay: data was not an object');
return;
}//else
if(!data.hasOwnProperty('target')){
console.log('index.js: received relay: No target specified');
return;
}//else
if(data.target.type === 'content'){
if(data.target.id && data.target.id === 'activeTab'){
targetId = tabs.activeTab.id;
}else{
targetId = data.target.id;
}
console.log('index.js: received relay: target ID: ', targetId);
if(!workers.hasOwnProperty(targetId) || !workers[targetId].worker){
console.log('index.js: received relay: No target worker available for ID: '
, targetId);
return;
}//else
emitPort = workers[targetId].worker.port;
}else{
//None yet defined
console.log('index.js: received relay: Target type not understood. Type: '
, data.target.type);
return;
}
console.log('index.js: received relay: emitType=', data.emitType, ' ::data='
, data.data);
emitPort.emit(data.emitType,data.data);
}
//Action button
var ui = require("sdk/ui");
var action_button = ui.ActionButton({
id: "panel-show-button",
label: "Show panel",
icon: "./icon.png",
onClick: function(state) {
panel.show();
}
});
数据/ JS / content.js :
console.log('In content.js');
self.port.on("message", function(text) {
console.log('content.js: received message:',text);
});
数据/ popup.js :
function myFunction() {
console.log('popup.js: Button clicked. Sending relayed message');
//addon.port.emit('message', 'hello world');
sendRelay('content','activeTab','message','Button clicked in panel');
}
function sendRelay(targetType,targetId,emitType,message) {
addon.port.emit('relay', {
target: {
type:targetType, //Currently, the only valid targetType is 'content'.
id:targetId //A tab ID, or 'activeTab'
},
emitType:emitType, //The type of emit message that will be sent.
data:message //The contents of the relayed message.
});
}
数据/ popup.html :
<html>
<head>
<meta charset='utf-8'>
<script type="text/javascript" src="popup.js"></script>
</head>
<body>
<button id="start-btn" onclick="myFunction()">Clip</button>
</body>
</html>
的package.json :
{
"title": "Demo passing a message panel-background-content",
"name": "relaymessge",
"id": "relaymessage@ex",
"version": "0.0.1",
"description": "Demonstrate passing a message from a panel -> background script -> content script.",
"main": "index.js",
"author": "Makyen, vivek",
"engines": {
"firefox": ">=38.0a1",
"fennec": ">=38.0a1"
},
"keywords": [
"jetpack"
]
}