如何修复自动补全搜索栏开发中的"Cannot read property 'addEventListener' of null"错误?
Let's break down exactly why you're seeing that error and how to fix it step by step:
1. You're Accessing DOM Elements Before They Exist
Your JavaScript file is loaded in the <head> section of your HTML, which runs before the browser finishes rendering the <input> and suggestions panel in the <body>. When your code tries to call addEventListener on searchInput, that variable doesn't point to any actual element yet—it's null.
2. You Never Selected the DOM Elements
Looking at your JS code, you're using searchInput and suggestionsPanel as if they're already linked to your HTML elements, but you never actually grabbed them from the DOM. Your HTML uses classes (search-input and suggestions), so you need to explicitly select these elements first.
Here's the Fixed Code
Updated HTML
Move your script tag to the end of the <body> so it runs after all DOM elements are loaded:
<html> <head> <link rel="icon" href="Geofflixlogo.png"> <title>Geofflix</title> <link rel="stylesheet" href="geofflix.css"> </head> <body> <div class="header"> <div class="logo"> <a href="index.html"> <img src="Logo.png" height="50"> </a> <div class="navi"> Watch what everyone's talking about. For Free! </div> <div class="searchbar"> <input class="search-input" type="text" placeholder="Search..."> <div class="suggestions"> </div> </div> <div class="nav"> <a href="index.html">Home</a> <a href="Movies.html">Movies</a> </div> </div> </div> <!-- Move script to end of body to ensure DOM is ready --> <script src="geofflix.js" type="text/javascript"></script> </body> </html>
Updated JavaScript
First select the elements, then add the event listener (plus a few other fixes for your autocomplete logic):
// Grab the elements from the DOM first const searchInput = document.querySelector('.search-input'); const suggestionsPanel = document.querySelector('.suggestions'); // Add a safety check to make sure elements exist before proceeding if (searchInput && suggestionsPanel) { searchInput.addEventListener('keyup', function() { const input = searchInput.value.toUpperCase(); // Match case with your filter logic suggestionsPanel.innerHTML = ''; const suggestions = movies.filter(function(movie) { return movie.name.toUpperCase().startsWith(input); }); suggestions.forEach(function(suggested){ const div = document.createElement('div'); div.textContent = suggested.name; // Access the movie's name property, use textContent for safety suggestionsPanel.appendChild(div); }); if (input === ''){ suggestionsPanel.innerHTML = ''; // Clear the panel's content, not the element itself } }); }
Extra Fixes & Notes
- Added
toUpperCase()to the input value so your filter matches correctly (you were converting movie names to uppercase but not the user's input). - Changed
div.innerHTML = suggestedtodiv.textContent = suggested.name—sincesuggestedis a movie object, you need to access itsnameproperty, andtextContentavoids potential security risks vsinnerHTML. - Fixed
suggestionsPanel=''tosuggestionsPanel.innerHTML = ''—you can't overwrite the DOM element itself with a string, you need to modify its inner content. - Added a check for
searchInput && suggestionsPanelto avoid errors even if elements are missing for some reason.
内容的提问来源于stack exchange,提问作者Geoffrey Ortiz

