奇怪的未捕获的TypeError:无法将属性'onclick'设置为null [英] weird Uncaught TypeError: Cannot set property 'onclick' of null

查看:79
本文介绍了奇怪的未捕获的TypeError:无法将属性'onclick'设置为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在学习开发Google chrome扩展程序.我现在尝试获取一个按钮以列出控制台中的所有 span 元素.但是,我似乎无法设置按钮的功能并保持收到奇怪的 Uncaught TypeError:无法设置null的属性"onclick" .

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:

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:

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!

推荐答案

在manifest.json中声明 background 时,它将创建一个后台页面,在该页面上运行指定的脚本.这是一个隐藏的单独页面.您可以调试它自己的单独的devtools .

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.

browser_action page_action 弹出窗口也是一个单独的页面.它与后台脚本/页面无关.它还有自己的独立devtool,您可以通过右键单击弹出窗口并选择检查"来访问.

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".

您可以使用这两个devtools来调试问题:设置断点,通过Ctrl-R或F5键重新加载页面,单步执行代码并实际查看会发生什么,因此无需猜测.

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.

当前,您在两个页面中运行相同的main.js.因此,一个main.js实例在后台脚本的页面中运行,其中DOM为空,因此自然找不到任何元素.

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.

解决方案是将其分为两个脚本.一个脚本将是注册API内容的后台脚本.另一个脚本将在弹出窗口中运行,并处理UI内容.

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. 在manifest.json中声明"background":{"scripts":["bg.js","persistent":false]}

制作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()],
    }]);
  });
});

  • 制作popup.js:

  • Make popup.js:

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

  • 将其加载到您的html中:< script src = popup.js></script>

    不需要 defer async 属性.也不需要 window.load :脚本DOM准备就绪时已经运行,因为这是HTML中的最后一件事.

    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.

    注释:

    • 要查看控制台输出,请使用正确的devtools,如本答案开头所述.
    • 要在不匹配的网站上将图标显示为灰色,请参见此答案.

    这篇关于奇怪的未捕获的TypeError:无法将属性'onclick'设置为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆