我有内容脚本的扩展和注入页面的脚本。注入的脚本引用了一些 DOM 节点,我想将它传递给内容脚本。我知道注入脚本和内容脚本存在于不同的上下文中,但它们共享 DOM,所以它必须是可能的。
理想情况下,每个 DOM 节点都有唯一的 ID,所以我可以得到一个,通过消息发送到内容脚本,然后通过这个 ID 检索 DOM 节点。但据我所知,没有这样的身份证。
我目前的解决方案是发送完整的节点路径,例如root/child#1/child#10/...
.
有没有更有效的解决方案?
我有内容脚本的扩展和注入页面的脚本。注入的脚本引用了一些 DOM 节点,我想将它传递给内容脚本。我知道注入脚本和内容脚本存在于不同的上下文中,但它们共享 DOM,所以它必须是可能的。
理想情况下,每个 DOM 节点都有唯一的 ID,所以我可以得到一个,通过消息发送到内容脚本,然后通过这个 ID 检索 DOM 节点。但据我所知,没有这样的身份证。
我目前的解决方案是发送完整的节点路径,例如root/child#1/child#10/...
.
有没有更有效的解决方案?
您可以分派一个冒泡事件,并使用该event.target
属性来获取节点的引用:
// content script
var myEventName = 'whatever' + Math.random(); // Unpredictable, avoid conflicts
document.addEventListener(myEventName, function(event) {
event.stopPropagation(); // No need to bubble further
var element = event.target;
// ... rest of your code
}, true); // <-- Get event at capture phase
// Inject the injected script
var script = document.createElement('script');
script.textContent = '(' + function(myEventName) {
function sendElementToContentScript(element) {
var event = new CustomEvent(myEventName, { bubbles: true });
element.dispatchEvent(event);
}
// ... rest of your code, e.g. sendElementToContentScript(document.body);
} + ')("' + myEventName + '");';
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);
如果您希望通过事件传递其他信息,请设置event.detail
属性:
// set
var event = new CustomEvent(myEventName, {
bubbles: true,
detail: 'any serializable type'
});
// read (in event listener
console.log( event.detail );
有关更多信息,请参阅CustomEvent
(MDN) 和构建 Chrome 扩展程序 - 使用内容脚本在页面中注入代码(适用于不熟悉脚本注入技术的人)。