内容脚本之间的通信 | Chrome 分机
Communication between content scripts | Chrome Extension
我有一个将 iframe 注入网页的内容脚本。
content.js
var iframe = document.createElement('iframe');
iframe.id = "frame";
iframe.style.cssText = "position:fixed;top: 15px;right: 15px;width: 250px;height: 245px;overflow: hidden;background-color:#FFFFFF;border-radius: 5px;";
iframe.src = chrome.runtime.getURL('frame.html');
document.body.appendChild(iframe);
iframe 显示一些文本值,有一个提交按钮和一个关闭按钮。
frame.html的一部分
<div class="header">
<span class="close">Name</span>
<span class="close-btn" id="close-btn">×</span>
</div>
<div class="details-container">
<span class="label">First Name : </span>
<span id="fname" type="text" ></span>
</div>
<div class="details-container">
<span class="label">Last Name : </span>
<span id="lname" type="text" /></span>
</div>
<div class="btn-details-container">
<button class="copy" id="copy-name">Copy</button>
</div>
frame.html 有 frame.js 链接到它。
我想在这里做两件事。
- Close/Remove/Hide 当用户点击 iframe 上的关闭按钮时的 iframe(#close-btn)
- 要动态设置的span中名字和姓氏的值(摘自当前网页DOM)
问题:
1)我不知道如何将 frame.html 上的点击事件传播到内容脚本以关闭 iframe(无法在 frame.js 和 content.js 之间建立通信)
2)无法为#fname 和#lname 设置span.textContent,因为frame.js 无法读取网页DOM。
Chrome 和基于 Chromium 的浏览器
在 iframe 中使用 chrome.tabs.sendMessage to communicate with the owner tab of the iframe, which can be retrieved using chrome.tabs.getCurrent。
content.js:
var FRAME_URL = chrome.runtime.getURL('frame.html');
var iframe = document.createElement('iframe');
iframe.src = FRAME_URL;
document.body.appendChild(iframe);
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
switch (msg.cmd) {
case 'close':
iframe.remove();
iframe = null;
break;
case 'getData':
sendResponse([
['fname', document.querySelector('.web.page.selector.for.fname').textContent],
['lname', document.querySelector('.web.page.selector.for.lname').textContent],
]);
break;
}
});
iframe.js:
tellParent({cmd: 'getData'}, data => {
for (const [id, val] of data) {
document.getElementById(id).textContent = val;
}
});
document.querySelector('.close-btn').onclick = () => {
tellParent({cmd: 'close'});
};
function tellParent(msg, callback) {
chrome.tabs.getCurrent(tab => {
chrome.tabs.sendMessage(tab.id, msg, {frameId: 0}, callback);
});
}
火狐
Firefox 的内部架构不同,因此它运行此类 iframe 时具有与内容脚本相同的限制,并且它们无法访问 chrome.tabs
。解决方法是通过后台脚本发送消息。
iframe.js 需要一个不同的 tellParent:
function tellParent(msg, callback) {
chrome.runtime.sendMessage(msg, callback);
}
background.js
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (sender.frameId) {
chrome.tabs.sendMessage(sender.tab.id, msg, {frameId: 0}, sendResponse);
return true;
}
});
我有一个将 iframe 注入网页的内容脚本。
content.js
var iframe = document.createElement('iframe');
iframe.id = "frame";
iframe.style.cssText = "position:fixed;top: 15px;right: 15px;width: 250px;height: 245px;overflow: hidden;background-color:#FFFFFF;border-radius: 5px;";
iframe.src = chrome.runtime.getURL('frame.html');
document.body.appendChild(iframe);
iframe 显示一些文本值,有一个提交按钮和一个关闭按钮。
frame.html的一部分
<div class="header">
<span class="close">Name</span>
<span class="close-btn" id="close-btn">×</span>
</div>
<div class="details-container">
<span class="label">First Name : </span>
<span id="fname" type="text" ></span>
</div>
<div class="details-container">
<span class="label">Last Name : </span>
<span id="lname" type="text" /></span>
</div>
<div class="btn-details-container">
<button class="copy" id="copy-name">Copy</button>
</div>
frame.html 有 frame.js 链接到它。
我想在这里做两件事。
- Close/Remove/Hide 当用户点击 iframe 上的关闭按钮时的 iframe(#close-btn)
- 要动态设置的span中名字和姓氏的值(摘自当前网页DOM)
问题:
1)我不知道如何将 frame.html 上的点击事件传播到内容脚本以关闭 iframe(无法在 frame.js 和 content.js 之间建立通信)
2)无法为#fname 和#lname 设置span.textContent,因为frame.js 无法读取网页DOM。
Chrome 和基于 Chromium 的浏览器
在 iframe 中使用 chrome.tabs.sendMessage to communicate with the owner tab of the iframe, which can be retrieved using chrome.tabs.getCurrent。
content.js:
var FRAME_URL = chrome.runtime.getURL('frame.html');
var iframe = document.createElement('iframe');
iframe.src = FRAME_URL;
document.body.appendChild(iframe);
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
switch (msg.cmd) {
case 'close':
iframe.remove();
iframe = null;
break;
case 'getData':
sendResponse([
['fname', document.querySelector('.web.page.selector.for.fname').textContent],
['lname', document.querySelector('.web.page.selector.for.lname').textContent],
]);
break;
}
});
iframe.js:
tellParent({cmd: 'getData'}, data => {
for (const [id, val] of data) {
document.getElementById(id).textContent = val;
}
});
document.querySelector('.close-btn').onclick = () => {
tellParent({cmd: 'close'});
};
function tellParent(msg, callback) {
chrome.tabs.getCurrent(tab => {
chrome.tabs.sendMessage(tab.id, msg, {frameId: 0}, callback);
});
}
火狐
Firefox 的内部架构不同,因此它运行此类 iframe 时具有与内容脚本相同的限制,并且它们无法访问 chrome.tabs
。解决方法是通过后台脚本发送消息。
iframe.js 需要一个不同的 tellParent:
function tellParent(msg, callback) { chrome.runtime.sendMessage(msg, callback); }
background.js
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (sender.frameId) { chrome.tabs.sendMessage(sender.tab.id, msg, {frameId: 0}, sendResponse); return true; } });