HTML select标签onchange第二次触发为何抛出TypeError?
问题:下拉菜单首次触发正常,后续无法调用函数
我第一次搭建网站,目前网站接近完成,但下拉菜单触发函数时,第一次正常工作,后续却无法触发。
预期结果
select菜单值变更时,更新iframe「list」和p标签「randomItem」
实际结果
首次值变更符合预期,但后续每次触发都会在控制台抛出以下错误:
Uncaught TypeError: list is not a function at HTMLSelectElement.onchange ((index):23:50) onchange @ (index):23
我的HTML代码
<select onchange="list();" id="listSelect"> <option disabled selected value> -- Select a list -- </option> <option value="list1">Item 1</option> <option value="list2">Item 2</option> </select> <p id="randomItem">(choose a list first)</p> <iframe id="list" src="(REDACTED)"></iframe>
我的JavaScript代码
async function list() { list = document.getElementById("listSelect").value; if (list.length == 0) { alert("You need to choose a list first!"); return; } document.getElementById('list').src="(REDACTED)" + list; randomItem(); } async function randomItem() { list = document.getElementById("listSelect").value; if (list.length == 0) { alert("You need to choose a list first!"); return; } const response = await fetch("(REDACTED)" + list, { method: 'GET', mode: 'cors', cache: 'no-cache', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, redirect: 'follow', // manual, *follow, error referrerPolicy: 'no-referrer', }); const json = await response.json(); var item = json[Math.floor(Math.random()*json.length)]; document.getElementById("randomItem").innerHTML = item; }
解决方案
问题根源:你在list()函数里直接使用了未声明的变量list,这个变量会被挂载到全局作用域,第一次调用函数时,它会覆盖掉同名的list函数。之后list就变成了字符串类型,再调用list()自然会报错“不是函数”。
修正方法:给变量添加const/let声明,同时更换变量名避免和函数名冲突,比如改成selectedList:
async function list() { const selectedList = document.getElementById("listSelect").value; if (selectedList.length == 0) { alert("你需要先选择一个列表!"); return; } document.getElementById('list').src="(REDACTED)" + selectedList; randomItem(); } async function randomItem() { const selectedList = document.getElementById("listSelect").value; if (selectedList.length == 0) { alert("你需要先选择一个列表!"); return; } const response = await fetch("(REDACTED)" + selectedList, { method: 'GET', mode: 'cors', cache: 'no-cache', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, redirect: 'follow', referrerPolicy: 'no-referrer', }); const json = await response.json(); const item = json[Math.floor(Math.random()*json.length)]; document.getElementById("randomItem").innerHTML = item; }
关键注意点:
- 始终用
const/let声明变量,避免污染全局作用域 - 变量名不要和函数名、DOM元素ID重名,防止意外覆盖
内容的提问来源于stack exchange,提问作者DiffuseHyperion
相关产品推荐
相关产品推荐

