keep getting "Uncaught TypeError: Cannot read properties of null (reading 'setAttribute)" error

hi, i am trying to implement a dark/light mode toggle into my code and keep getting this error -- i feel like the dev tools is trying to tell me its running JS before it loads or finds the elements targeted but everything looks right on my end. probably a silly mistake but wanted to get some more eyes on this:
3 Replies
griff
griff3mo ago
<!DOCTYPE >
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Page Name</title>
<meta name="title" content="site name">
<meta name="description" content="place meta description content here">

<!-- Compiled CSS -->
<link rel="stylesheet" href="src/css/style.css">
<!-- Icons -->
<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
<!-- Favicon -->
<link rel="shortcut icon" href="favicon-32x32.png" type="favicon">
<!-- Google Font -->
<!-- Preload Images -->
</head>
<body>
<!-- Header -->
<header class="header">
<div class="header-logo">
<h1>Logo here</h1>
</div>
<nav class="nav">
<ul class="nav-list">
<li class="nav-item">
<a href="" class="nav-link">Home</a>
</li>
<li class="nav-item">
<a href="" class="nav-link">About</a>
</li>
<li class="nav-item">
<a href="" class="nav-link">Services</a>
</li>
<li class="nav-item">
<a href="" class="nav-link">Pricing</a>
</li>
<li class="nav-item">
<a href="" class="nav-link">Contact</a>
</li>
</ul>
</nav>
<div class="nav-right">
<button
class="dark-mode
data-theme-toggle
aria-label="Change to light theme"">
<img src="src/img/moon.svg" alt="" class="dark-mode-icon">
</button>
<div class="hamburger">
<span class="hamburger-bar"></span>
<span class="hamburger-bar"></span>
<span class="hamburger-bar"></span>
</div>
</div>

<!DOCTYPE >
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Page Name</title>
<meta name="title" content="site name">
<meta name="description" content="place meta description content here">

<!-- Compiled CSS -->
<link rel="stylesheet" href="src/css/style.css">
<!-- Icons -->
<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
<!-- Favicon -->
<link rel="shortcut icon" href="favicon-32x32.png" type="favicon">
<!-- Google Font -->
<!-- Preload Images -->
</head>
<body>
<!-- Header -->
<header class="header">
<div class="header-logo">
<h1>Logo here</h1>
</div>
<nav class="nav">
<ul class="nav-list">
<li class="nav-item">
<a href="" class="nav-link">Home</a>
</li>
<li class="nav-item">
<a href="" class="nav-link">About</a>
</li>
<li class="nav-item">
<a href="" class="nav-link">Services</a>
</li>
<li class="nav-item">
<a href="" class="nav-link">Pricing</a>
</li>
<li class="nav-item">
<a href="" class="nav-link">Contact</a>
</li>
</ul>
</nav>
<div class="nav-right">
<button
class="dark-mode
data-theme-toggle
aria-label="Change to light theme"">
<img src="src/img/moon.svg" alt="" class="dark-mode-icon">
</button>
<div class="hamburger">
<span class="hamburger-bar"></span>
<span class="hamburger-bar"></span>
<span class="hamburger-bar"></span>
</div>
</div>

</header>

<!-- CTA -->


<script type="application/javascript" src="src/js/script.js"></script>
</body>
</html>
</header>

<!-- CTA -->


<script type="application/javascript" src="src/js/script.js"></script>
</body>
</html>
// Sticky Nav
window.onscroll = function() {stickyNav()};

const sticky = header.offsetTop;

function stickyNav() {
if (window.scrollY >= sticky) {
header.classList.add("sticky");
} else {
header.classList.remove("sticky");
}
}





function calculateSettingAsThemeString({ localStorageTheme, systemSettingDark }) {
if (localStorageTheme !== null) {
return localStorageTheme;
}

if (systemSettingDark.matches) {
return "dark";
}

return "light";
}

/**
* Utility function to update the button text and aria-label.
*/
function updateButton({ buttonEl, isDark }) {
const newCta = isDark ? "Change to light theme" : "Change to dark theme";
buttonEl.setAttribute("aria-label", newCta);
buttonEl.innerText = newCta;
}

/**
* Utility function to update the theme setting on the html tag
*/
function updateThemeOnHtmlEl({ theme }) {
document.querySelector("html").setAttribute("data-theme", theme);
}


/**
* On page load:
*/

/**
* 1. Grab what we need from the DOM and system settings on page load
*/
const button = document.querySelector("[data-theme-toggle]");
const localStorageTheme = localStorage.getItem("theme");
const systemSettingDark = window.matchMedia("(prefers-color-scheme: dark)");

/**
* 2. Work out the current site settings
*/
let currentThemeSetting = calculateSettingAsThemeString({ localStorageTheme, systemSettingDark });

/**
* 3. Update the theme setting and button text accoridng to current settings
*/
// Sticky Nav
window.onscroll = function() {stickyNav()};

const sticky = header.offsetTop;

function stickyNav() {
if (window.scrollY >= sticky) {
header.classList.add("sticky");
} else {
header.classList.remove("sticky");
}
}





function calculateSettingAsThemeString({ localStorageTheme, systemSettingDark }) {
if (localStorageTheme !== null) {
return localStorageTheme;
}

if (systemSettingDark.matches) {
return "dark";
}

return "light";
}

/**
* Utility function to update the button text and aria-label.
*/
function updateButton({ buttonEl, isDark }) {
const newCta = isDark ? "Change to light theme" : "Change to dark theme";
buttonEl.setAttribute("aria-label", newCta);
buttonEl.innerText = newCta;
}

/**
* Utility function to update the theme setting on the html tag
*/
function updateThemeOnHtmlEl({ theme }) {
document.querySelector("html").setAttribute("data-theme", theme);
}


/**
* On page load:
*/

/**
* 1. Grab what we need from the DOM and system settings on page load
*/
const button = document.querySelector("[data-theme-toggle]");
const localStorageTheme = localStorage.getItem("theme");
const systemSettingDark = window.matchMedia("(prefers-color-scheme: dark)");

/**
* 2. Work out the current site settings
*/
let currentThemeSetting = calculateSettingAsThemeString({ localStorageTheme, systemSettingDark });

/**
* 3. Update the theme setting and button text accoridng to current settings
*/
dev tools is freaking out about this line: buttonEl.setAttribute("aria-label", newCta); ```
glutonium
glutonium3mo ago
console.log(buttonEl) apparently buttonEl = null according to the error check where u r calling updateButton()
ἔρως
ἔρως3mo ago
buttonEl doesnt exist also, the code you have to make the nav sticky well, that's 2 lines of css:
position: sticky;
top: 0px;
position: sticky;
top: 0px;