用<form>包裹搜索框和按钮并监听submit事件,统一触发performSearch();历史存localStorage并加try...catch容错;所有入口归一化、去重截取10条、支持键盘操作。
回车和按钮必须触发同一段逻辑,否则历史记录容易不同步。常见错误是给 <input> 单独监听 keydown,但没阻止表单默认行为,导致页面刷新清空历史。
<form> 包裹搜索框和按钮,监听 submit 事件——这是最稳的方式,天然兼容回车、点击、甚至语音输入等触发源event.preventDefault(),否则表单会跳转或刷新inputElement.value.trim(),避免空格干扰后续去重和存储sessionStorage 刷新就丢,cookie 太小且随请求发出去,IndexedDB 对零起点太重。localStorage 简单、持久、容量够(通常 5–10MB),但要注意它只存字符串。
JSON.stringify() 把数组存进 localStorage.setItem('searchHistory', ...)
JSON.parse(),且要包裹 try...catch——用户可能手动删过 localStorage,或数据损坏historyArray.filter(item => item !== newQuery) 去重,再用 slice(-10) 截取直接给每个历史项绑 click 事件没问题,但容易点两次——比如手快连击,或点击后又按回车。关键不是防抖,而是统一入口。
performSearch(query)
query 为空或与当前输入框值一致,直接 return
input.value 并聚焦,方便用户编辑或再次提交没有动画、没清空按钮、历史列表不滚动——这些都会让用户觉得“卡”或“不响应”。零起点不必做复杂 UI,但几个关键点不能省。
autocomplete="off",否则浏览器下拉会和你的历史记录打架<ul> + <li>,每项加 tabindex="0" 和 role="button",支持键盘操作