weird Uncaught TypeError: Cannot set property 'onclick' of null

泄露秘密 提交于 2021-01-29 15:01:05

问题


I'm currently learning to develop a google chrome extension. I'm trying to get a button to list all of the span elements in the console for now. However, I can't seem to set the function of the button and keep getting a weird Uncaught TypeError: Cannot set property 'onclick' of null error.

index.html:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>Simple Greeting Dashboard</title>
    <link rel="stylesheet" href="style.css" />
</head>

<body>
    <button id="main-switch">Update prices:</button>
    <script src="main.js" defer></script>
</body>


</html>

main.js:

window.onload = function() {
    console.log("This is working!");

    chrome.runtime.onInstalled.addListener(function() {
        chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
            chrome.declarativeContent.onPageChanged.addRules([{
                conditions: [new chrome.declarativeContent.PageStateMatcher({
                    pageUrl: { hostEquals: 'steamcommunity.com' },
                })],
                actions: [new chrome.declarativeContent.ShowPageAction()]
            }]);
        });
    });

    function update_prices() {
        var elements = document.getElementsByTagName('span');
        console.log("Elements:", elements);
    }
    document.getElementById('main-switch').onclick = update_prices;
};

manifest.json:

{
    "name": "Steam price helper",
    "version": "1.0",
    "description": "Helps with prices on the Steam community market",
    "incognito": "split",
    "background": {
        "scripts": ["main.js"],
        "persistent": true
    },
    "permissions": [
        "activeTab",
        "storage",
        "declarativeContent"
    ],

    "page_action": {
        "default_popup": "index.html",
        "default_icon": {
            "256": "download.png"
        }
    },

    "manifest_version": 2
}

I've looked at other questions that have the same problem, but none of those solutions seem to work. Thanks in advance!


回答1:


When you declare background in manifest.json, it creates a background page where the specified scripts run. It's a hidden separate page. You can debug it its own separate devtools.

The browser_action or page_action popup is also a separate page. It's not related to the background script/page. It also has its own separate devtools which you can access by right-clicking inside the popup and choosing "Inspect".

You can use both devtools to debug the problem: set breakpoints, reload the page via Ctrl-R or F5 key, step through the code and actually see what happens so there's no need to guess.

Currently you run the same main.js in two pages. So, one instance of main.js runs in the background script's page where DOM is empty and naturally it doesn't find any elements.

The solution is to split it into two scripts. One script will be the background script that registers API stuff. Another script will run in the popup and deal with UI stuff.

  1. In manifest.json declare "background": {"scripts": ["bg.js", "persistent":false]}

  2. Make bg.js:

    chrome.runtime.onInstalled.addListener(() => {
      chrome.declarativeContent.onPageChanged.removeRules(() => {
        chrome.declarativeContent.onPageChanged.addRules([{
          conditions: [
            new chrome.declarativeContent.PageStateMatcher({
              pageUrl: {hostEquals: 'steamcommunity.com'},
            }),
          ],
          actions: [new chrome.declarativeContent.ShowPageAction()],
        }]);
      });
    });
    
  3. Make popup.js:

    document.getElementById('main-switch').onclick = function () {
      var elements = document.getElementsByTagName('span');
      console.log('Elements:', elements);
    };
    
  4. Load it in your html: <script src=popup.js></script>

    No need for defer or async attributes. No need for window.load either: the script already runs when DOM is ready as it's the last thing in HTML.

Notes:

  • To view the console output, use the correct devtools as explained at the beginning of this answer.
  • To gray out the icon on non-matching sites, see this answer.


来源:https://stackoverflow.com/questions/64589720/weird-uncaught-typeerror-cannot-set-property-onclick-of-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!