I have seen many questions about this error but, I haven’t found the answer on any of them.
I’m creating an interactive page to create patterns based on geometric shapes and I’m having problems adding a new element with a function that creates a new element and adds the element to a “base” div. Then, the base div is cloned to create the pattern.
In the HTML I’ve created a color picker to preselect the color before creating the element, and a button that contains a function to create and append the new element to the base div.
Also in the HTML, I created the SVG shapes with a “display:none” style, and when I retrieve them with JS, I just change it to “display:block”.
I can append many elements with javascript instructions (there are some examples in the code), but when I put these instructions inside a function, the code doesn’t work and I got the error: “Uncaught TypeError: Cannot read property ‘style’ of null”
This is my code, I included comments for easier reading. Hope you can help me.
//Global variables var picker = document.getElementById('picker'); var color = picker.value; //Base elements var myRow = document.getElementById("row"); var myDiv = document.createElement("base"); myDiv.className = 'base'; // Retrieves the 'out_circle' SVG from HTML and defines properties var innerDiv = document.getElementById("out_circle"); innerDiv.style.display = "block"; innerDiv.style.fill = "#3c00ff"; innerDiv.style.position = "absolute"; // Adds the element to the base div myDiv.appendChild(innerDiv); // Retrieves the 'sqr_small' SVG from HTML and defines properties var innerDiv = document.getElementById("sqr_small"); innerDiv.style.display = "block"; innerDiv.style.fill = "purple"; innerDiv.style.position = "absolute"; innerDiv.style.margin = "5"; // Adds the element to the base div myDiv.appendChild(innerDiv); // Retrieves the 'diamond' SVG from HTML and defines properties var innerDiv = document.getElementById("diamond"); innerDiv.style.display = "block"; innerDiv.style.fill = "green"; innerDiv.style.position = "absolute"; // Adds the element to the base div myDiv.appendChild(innerDiv); // Retrieves the 'slash_right' SVG from HTML and defines properties var innerDiv = document.getElementById("slash_right"); innerDiv.style.display = "block"; innerDiv.style.fill = "orange"; innerDiv.style.position = "absolute"; // Adds the element to the base div myDiv.appendChild(innerDiv); //*****NOT WORKING FUNCTION***** function create_Lslash() { // Retrieves the 'slash_left' SVG from HTML and defines properties var innerDiv = document.getElementById("slash_left"); innerDiv.style.display = "block"; innerDiv.style.fill = color; innerDiv.style.position = "absolute"; // Adds the element to base div myDiv.appendChild(innerDiv); } // Clones the div to create a row var i = 0; while (i < 10) { myRow.appendChild(myDiv.cloneNode(true)); i++; } //Clones the row to create a grid var i = 0; while (i < 10) { document.body.appendChild(myRow.cloneNode(true)); i++; }
/* a minimalist set of CSS resets */ /* default to border-box */ html { box-sizing: border-box; font-size: 16px; } *, *:before, *:after { box-sizing: inherit; } /* adjust typography defaults */ body { margin: 1rem; font-family: sans-serif; line-height: 1.5; } .base { display: inline-block; height: 50px; width: 50px; margin: 0px; padding: 0px; position: relative; } .row { display: block; height: 50px; }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="https://glitch.com/favicon.ico" /> <title>Patterns</title> <!-- import the webpage's stylesheet --> <link rel="stylesheet" href="/style.css" /> <!-- import the webpage's javascript file --> <script src="/script.js" defer></script> </head> <body> <!-- Color picker --> <div style="padding:40px 0 0 0;"> <input type="color" id="picker" value="#0000ff"> </div> <!-- "Create" button --> <div style="padding:40px 0 40px 0;"> <button id="creator" onclick="create_Lslash()">Create</button> </div> <div id="row" class="row"></div> <!-- Elements to append --> <div> <!-- Diamond --> <svg id="diamond" x="0px" y="0px" width="50px" height="50px" viewbox="0 0 50 50" style="enable-background:new 0 0 50 50; display:none;" xml:space="preserve"> <style type="text/css"> </style> <rect x="7.32" y="7.32" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -10.3553 25)" class="st0" width="35.36" height="35.36"/> </svg> <!-- Out_circle --> <svg id="out_circle" x="0px" y="0px" width="50px" height="50px" viewbox="0 0 50 50" style="enable-background:new 0 0 50 50; display:none;" xml:space="preserve"> <style type="text/css"> </style> <defs> </defs> <g> <path class="st0" d="M25,50h25V25C50,38.81,38.81,50,25,50z"/> <path class="st0" d="M25,0c13.81,0,25,11.19,25,25V0H25z"/> <path class="st0" d="M0,25v25h25C11.19,50,0,38.81,0,25z"/> <path class="st0" d="M25,0H0v25C0,11.19,11.19,0,25,0z"/> </g> </svg> <!-- Small square --> <svg id="sqr_small" x="0px" y="0px" width="40px" height="40px" viewbox="0 0 40 40" style="enable-background:new 0 0 40 40; display:none;" xml:space="preserve"> <defs> </defs> <rect width="40" height="40"/> </svg> <!-- Right slash --> <svg id="slash_right" x="0px" y="0px" width="50px" height="50px" viewbox="0 0 50 50" style="enable-background:new 0 0 50 50; display:none;" xml:space="preserve"> <defs> </defs> <g> <polygon class="st0" points="6.36,0 0,0 0,6.36 43.64,50 50,50 50,43.64 " /> </g> </svg> <!-- Left slash --> <svg id="slash_left" x="0px" y="0px" width="50px" height="50px" viewbox="0 0 50 50" style="enable-background:new 0 0 50 50; display:none;" xml:space="preserve"> <defs> </defs> <g> <polygon class="st0" points="0,43.64 0,50 6.36,50 50,6.36 50,0 43.64,0 "/> </g> </svg> </div> </body> </html>
Advertisement
Answer
The error appears when you click the Create button second time.
The function create_Lslash()
calls myDiv.appendChild(innerDiv)
. As innerDiv
here is an existing element svg#slash_left
, it is moved from it’s current position to new position (child of myDiv
). But you don’t append myDiv
back to the html document after this.
Hence, svg#slash_left
is not found in the document when you click Create again and var innerDiv = document.getElementById("slash_left");
evaluates to null
.
Ref: Node.appendChild