如何解决前端开发中的TypeError: form.addEventListener is not a function错误
解决TypeError: form.addEventListener is not a function及代码中的其他问题
一、为啥会出现form.addEventListener is not a function?
这个错误的本质是你代码里的form变量是null——也就是说document.getElementById("form")没找到页面上的表单元素,所以没法调用addEventListener方法。常见两种情况:
1. JS代码执行过早,DOM还没加载完成
浏览器是从上到下解析HTML的,如果你的<script>标签放在页面<head>里,或者放在表单元素前面,那执行document.getElementById("form")的时候,表单还没被渲染到页面上,自然拿不到元素。
解决办法:
- 把你的
<script>标签挪到HTML的</body>标签前面,等所有DOM元素都加载完再执行JS; - 或者给JS套个DOM加载监听,确保DOM就绪后再执行代码:
document.addEventListener('DOMContentLoaded', function() { // 所有获取DOM、绑定事件的代码都放这里面 });
2. HTML里的表单ID不匹配
检查你的HTML表单,必须有id="form",比如:
<form id="form"> <input type="text" id="query"> <button type="submit">搜索电影</button> </form>
如果表单ID是search-form或者Form(大小写错误),那getElementById肯定找不到目标元素。
二、你代码里还有其他致命拼写错误
看你的returnMovies函数,所有document.creatEelement都是拼写错误!正确写法是document.createElement(是小写的e,不是大写E)。另外你还多次把属性加错了对象,比如:
const div_row = document.creatEelement('div'); div_card.setAttribute('class','row'); // 这里应该给div_row加class,不是div_card
这些错误会导致你创建不出DOM元素,影片卡片根本渲染不出来。
三、修复后的完整代码
const APILINK = 'https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=a51be54af06c91b914fc566261c23fd3&page=1'; const IMG_PATH='https://image.tmdb.org/t/p/w1280'; const SEARCHAPI = "https://api.themoviedb.org/3/search/movie?&api_key=a51be54af06c91b914fc566261c23fd3&query="; // 等DOM加载完毕再执行代码 document.addEventListener('DOMContentLoaded', function() { const main = document.getElementById("section"); const form = document.getElementById("form"); const search = document.getElementById("query") returnMovies(APILINK); function returnMovies(url){ fetch(url).then(res=>res.json()).then(function(data){ console.log(data.results); main.innerHTML = ''; // 先清空原有内容 data.results.forEach(element=>{ const div_card = document.createElement('div'); div_card.setAttribute('class','card'); const div_row = document.createElement('div'); div_row.setAttribute('class','row'); const div_column = document.createElement('div'); div_column.setAttribute('class','column'); const image = document.createElement('img'); image.setAttribute('class','thumbnail'); // 处理没有海报的情况,避免图片加载报错 image.src = element.poster_path ? IMG_PATH + element.poster_path : 'https://via.placeholder.com/1280x1920?text=无海报'; const title = document.createElement('h3'); title.textContent = element.title; // 用textContent比innerHTML更安全,避免XSS风险 const center = document.createElement('center'); center.appendChild(image); div_card.appendChild(center); div_card.appendChild(title); div_column.appendChild(div_card); div_row.appendChild(div_column); main.appendChild(div_row); }); }); } form.addEventListener("submit",(e) => { e.preventDefault(); main.innerHTML =''; const searchItem = search.value.trim(); // 去掉输入的首尾空格,避免无效搜索 if (searchItem){ returnMovies(SEARCHAPI + encodeURIComponent(searchItem)); // 编码搜索词,处理特殊字符 search.value =""; } }); });
额外优化了几个细节:
- 用
textContent设置标题,比innerHTML更安全; - 给搜索词加
encodeURIComponent,处理包含空格、特殊字符的搜索内容; - 处理影片没有海报的情况,替换为占位图。
内容的提问来源于stack exchange,提问作者TheLostChild
相关产品推荐
相关产品推荐

