How to access the webpage DOM rather than the extension page DOM?

前端 未结 1 734
眼角桃花
眼角桃花 2020-11-21 06:01

I\'m writing a Chrome extension and trying to overlay a

over the current webpage as soon as a button is clicked in the popup.html file.

When

相关标签:
1条回答
  • Extension pages/scripts such as the browser_action popup or background script have their own DOM, document, window, and a chrome-extension:// URL (use devtools for that part of the extension to inspect it).

    You need a content script to access DOM of web pages and interact with a tab's contents. Content scripts will execute in the tab as a part of that page, not as a part of the extension.

    Method 1. Declarative

    manifest.json:

    "content_scripts": [{
      "matches": ["*://*.example.com/*"],
      "js": ["contentScript.js"]
    }],
    

    It will run once when the page loads. After that happens, use messaging but note, it can't send DOM elements, Map, Set, ArrayBuffer, classes, functions, and so on - it can only send JSON-compatible simple objects and types so you'll need to manually extract the required data and pass it as a simple array or object.

    Method 2. Programmatic

    Use chrome.tabs.executeScript to inject a content script on demand.

    The callback of this method receives results of the last expression in the content script so it can be used to extract data which must be JSON-compatible, see method 1 note above.

    Required permissions in manifest.json:

    • Best case: "activeTab", suitable for a response to a user action (usually a click on the extension icon in the toolbar). Doesn't show a permission warning when installing the extension.

    • Usual: "*://*.example.com/" plus any other sites you want.

    • Worst case: "<all_urls>" or "*://*/", "http://*/", "https://*/" - when submitting into Chrome Web Store all of these put your extension in a super slow review queue because of broad host permissions.


    As an example of the second method, let's add that div when a browser action is clicked. We'll use chrome.tabs.executeScript() in the browserAction click handler to inject a content script as a file or a literal code string if it's small.

    • Simple call:

      chrome.tabs.executeScript({ code: `(${ inContent })()` });
      function inContent() {
        const el = document.body.appendChild(document.createElement('div'));
        el.style.cssText = 'position:fixed; top:0; left:0; right:0; background:red';
        el.textContent = 'DIV';
      }
      
    • Calling with parameters and receiving a response:

      chrome.tabs.executeScript({
        code: `(${ inContent })(${ JSON.stringify({ foo: 'bar' }) })`
      }, ([result] = []) => {
        if (!chrome.runtime.lastError) {
          console.log(result); // shown in devtools of the popup window
        }
      });
      function inContent(params) {
        document.body.insertAdjacentHTML('beforeend',
          `<div style="
            all:unset;
            position:fixed;
            top:0; left:0; right:0; bottom:0;
            background-color:rgba(0,255,0,0.3)"
          >${params.foo}</div>`);
        return {
          success: true,
          html: document.body.innerHTML,
        };
      }
      

    This example uses automatic conversion of inContent function's code to string, the benefit here is that IDE can apply syntax highlight and linting. The obvious drawback is that the browser wastes time to parse the code, but usually it's less than 1 millisecond thus negligible.

    0 讨论(0)
提交回复
热议问题