0

I have extension with content script and script injected into page. Injected script has reference to some DOM node and I want to pass it to content script. I know that injected script and content script live in different contexts, but they share DOM so it must be possible.

Ideally each DOM node would have unique ID, so I can get one, send to content script via message and then retrieve DOM node by this ID. But there is no such ID as far as I know.

My current solution is to send full node path, like root/child#1/child#10/....

Is there more effective solution?

kriomant
  • 2,216
  • 1
  • 16
  • 21

1 Answers1

2

You could dispatch a bubbling event, and use the event.target property to get the node's reference:

// 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);

If you wish to pass additional information with the event, set the event.detail property:

// set
var event = new CustomEvent(myEventName, {
    bubbles: true,
    detail: 'any serializable type'
});

// read (in event listener
console.log( event.detail );

For more information, see CustomEvent (MDN) and Building a Chrome Extension - Inject code in a page using a Content script (for those who are unfamiliar with the script injection technique).

Community
  • 1
  • 1
Rob W
  • 341,306
  • 83
  • 791
  • 678