You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron项目中Uncaught TypeError: Cannot read properties of null (reading 'onclick')错误排查求助

Electron录屏项目报错排查:Uncaught TypeError: Cannot read properties of null (reading 'onclick')

问题场景

跟着YouTube教程开发Electron录屏项目时,触发错误:

Uncaught TypeError: Cannot read properties of null (reading 'onclick')

相关代码

main.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World!</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css">
    <link rel="stylesheet" href="index.css" />
    <script defer src="render.js"></script>
  </head>
  <body>
    <h1>Electron recorder</h1>
    <video></video>

    <button id="startBtn" class="button is-primary"></button>
    <button id="stopBtn" class="button is-warning"></button>

    <hr />
    <button id="videoSelectionBtn" class="button is-text"></button>
  </body>
</html>

render.js问题代码片段

console.log(videoSelectionBtn)          // 输出NULL 
videoSelectionBtn.onclick() = getVideoResources;

render.js完整代码

// Buttons
const videoElement = document.querySelector('video');
const startBtn = document.querySelector('startBtn');
const stopBtn = document.querySelector('stopBtn');
const videoSelectionBtn = document.querySelector('videoSelectionBtn');

console.log(videoSelectionBtn)          // 输出NULL 
videoSelectionBtn.onclick() = getVideoResources;


const { desktopCapturer, remote } = require('electron')
const { Menu } = remote;

async function getVideoResources() {
    const inputSource = await desktopCapturer.getSources({
        types: ['window', 'screen']
    })

    const videoOptionsMenu = Menu.buildFromTemplate(
        inputSource.map(source => {
            return {
                label: source.name,
                click: () => selectSource(source) 
            };
        })
    );

    videoOptionsMenu.popup();
}

async function selectSource(source) {
    videoSelectionBtn.innerText = source.name;
    const constraints = {
        audio: false,
        video: {
            mandatory: {
                chromeMediaSource: 'dekstop',
                chromeMediaSourceId: source.id
            }
        }
    };

    const stream = await navigator.mediaDevices.getUserMedia(constraints);

    videoElement.srcObject = stream;
    videoElement.play();
}

问题解答

1. 此类问题的调试思路与自查点

  • 检查选择器语法:用querySelector选id元素必须加#前缀,选class要加.,直接写名称会匹配标签名,大概率找不到元素。
  • 验证元素存在性:用console.log打印获取的元素,若输出null,优先核对HTML里的id/class拼写和JS选择器是否一致。
  • 确认代码执行时机:确保JS在DOM完全加载后执行(比如用defer属性,或把脚本放</body>前),避免元素未渲染就尝试获取。
  • 检查事件绑定写法:事件绑定是赋值函数引用,不需要加括号,比如onclick直接赋值函数名即可。

2. 错误的根本原因

  • 选择器缺失前缀:所有通过id获取元素的querySelector都没加#,比如document.querySelector('videoSelectionBtn')应该写成document.querySelector('#videoSelectionBtn'),导致无法找到DOM元素,返回null。
  • 事件绑定语法错误:videoSelectionBtn.onclick() = getVideoResources;是错误写法,正确绑定应为videoSelectionBtn.onclick = getVideoResources;(去掉括号,直接赋值函数引用)。

修正后的render.js关键代码

// Buttons
const videoElement = document.querySelector('video');
const startBtn = document.querySelector('#startBtn');
const stopBtn = document.querySelector('#stopBtn');
const videoSelectionBtn = document.querySelector('#videoSelectionBtn');

console.log(videoSelectionBtn)          // 现在会输出对应的button元素
videoSelectionBtn.onclick = getVideoResources;

内容的提问来源于stack exchange,提问作者Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 04:06:21