我有一个包含单个元素的简单页面,id="test"
。我使用以下内容脚本进行了简单的扩展:
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
var elem = document.getElementById("test");
console.log(test.value);
test.value = 3;
});
现在,如果我单击扩展按钮,它会打印undefined
,然后继续打印3.但是,如果我尝试从控制台访问此值,它仍然是未定义的,并且更改它不会影响扩展名打印的内容。有没有办法从扩展名中实际访问此值?
更新:好的,我发现扩展程序在一个不共享“扩展程序”的单独环境中运行。使用主脚本,所以我需要在实际页面中注入一个脚本来执行此操作。
答案 0 :(得分:0)
Content scripts
在名为隔离世界的特殊环境中执行。他们可以访问注入页面的DOM,但不能访问页面创建的任何JavaScript变量或函数。它将每个内容脚本视为在其运行的页面上没有执行其他JavaScript。反过来也是如此:页面上运行的JavaScript无法调用任何函数或访问由content scripts
定义的任何变量。
虽然content scripts
的执行环境和托管它们的页面彼此隔离,但它们共享对页面DOM的访问权限。如果页面希望与内容脚本(或通过内容脚本扩展)进行通信,则必须通过共享DOM进行通信。
在内容脚本中 -
var port = chrome.runtime.connect();
window.addEventListener("message", function(event) {
// We only accept messages from ourselves
if (event.source != window)
return;
if (event.data.type && (event.data.type == "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
port.postMessage(event.data.text);
}
}, false);
在您的页面脚本中 -
document.getElementById("theButton").addEventListener("click",
function() {
window.postMessage({ type: "FROM_PAGE", text: "Hello from the webpage!" }, "*");
}, false);
在内容脚本中 -
function main() {
var elem = document.getElementById("test");
console.log(test.value);
test.value = 3;
}
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ main +')();'));
(document.body || document.head).appendChild(script);
在注入或您的内容脚本中添加一个事件监听器:
document.addEventListener('yourCustomEvent', function (e)
{
var data=e.detail;
console.log("received "+data);
});
另一方面(内容或注入脚本)调用事件:
var data="anything";
var evt=document.createEvent("CustomEvent");
evt.initCustomEvent("yourCustomEvent", true, true, data);
document.dispatchEvent(evt);
答案 1 :(得分:0)
元素在页面和扩展上下文之间共享的一件事是data-*
属性。
您可以通过.dataset
界面操作它们:
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
var elem = document.getElementById("test");
console.log(test.dataset.value);
test.dataset.value = 3; // will become "3"
});
这将对应于DOM中元素的data-value="3"
属性。
更一般地说,
function storeValue(id, key, value) {
var element = document.getElementById(id);
if(!element) throw Error("Element #" + id = " not found");
element.dataset[key] = JSON.stringify(value);
}
function readValue(id, key) {
var element = document.getElementById(id);
if(!element) throw Error("Element #" + id = " not found");
var value = element.dataset[key];
if(typeof value == "undefined") return undefined;
else return JSON.parse(value);
}
storeValue("test", "value", 3);
console.log(readValue("test", "value"));
我添加了序列化/反序列化,因为属性只能是字符串。