Angular中用getElementById操作嵌套div报Cannot set innerHTML of null错误
Hey there! Let's break down what's going wrong here and how to fix it quickly.
The Root Cause
Right now, you're building an HTML string and storing it in this.treeContent—but this string hasn't been added to the actual DOM (page structure) yet. When you call document.getElementById('tree' + htmlData.Id), the browser looks through the live DOM for that element, can't find it, and returns null. Trying to set innerHTML on null throws the error you're seeing.
Fix 1: Insert the HTML into the DOM First
First, add your assembled treeContent to a container on the page, then you can safely target the element:
// Step 1: Build your HTML string as before this.treeContent = this.treeContent + '<div id="tree' + htmlData.Id + '" class="col-md-12">' + htmlData.Label + '</div>'; // Step 2: Insert the string into a DOM container (replace 'treeContainer' with your actual container ID) document.getElementById('treeContainer').innerHTML = this.treeContent; // Step 3: Now the element exists in the DOM—you can modify it document.getElementById('tree' + htmlData.Id).innerHTML = '<button type="button" id="button' + htmlData.Id + '" value="' + htmlData.Id + '">' + htmlData.Label + '</button>';
Fix 2: Build the Full HTML Upfront (More Efficient)
Instead of building the div first and then modifying it, just include the button in your initial string. This saves you a second DOM lookup:
// Build the button HTML first const buttonHtml = '<button type="button" id="button' + htmlData.Id + '" value="' + htmlData.Id + '">' + htmlData.Label + '</button>'; // Add the button directly inside the div in your initial string this.treeContent = this.treeContent + '<div id="tree' + htmlData.Id + '" class="col-md-12">' + buttonHtml + '</div>'; // Later, insert this.treeContent into your DOM container as usual
Fix 3: Use DOM APIs (Safer & More Maintainable)
String concatenation can get messy (especially if htmlData.Label has special characters like quotes). Using the browser's DOM creation methods avoids this and lets you work with elements directly:
// Create the div element const treeDiv = document.createElement('div'); treeDiv.id = 'tree' + htmlData.Id; treeDiv.className = 'col-md-12'; // Create the button element const button = document.createElement('button'); button.type = 'button'; button.id = 'button' + htmlData.Id; button.value = htmlData.Id; button.textContent = htmlData.Label; // Use textContent to avoid XSS risks // Add the button to the div treeDiv.appendChild(button); // Add the div to your page's container document.getElementById('treeContainer').appendChild(treeDiv); // If you need to modify the div later, just use the treeDiv variable—no need for getElementById!
Quick Note on Security
If htmlData.Label comes from user input, using innerHTML can expose you to XSS attacks. Using textContent (like in Fix 3) is safer because it treats the content as plain text, not HTML.
内容的提问来源于stack exchange,提问作者F3cro

