大数跨境

前端实战:用localStorage实现搜索历史功能

前端实战:用localStorage实现搜索历史功能 wordpress知识
2026-09-19
7

前端实战:基于 localStorage 实现无后端搜索历史

搜索历史记录是电商、文档检索等场景的基础功能。在未登录或无需后端介入的场景下,仅利用前端 localStorage 即可实现关键词自动记录、刷新不丢失、重复置顶、单条删除及一键清空等核心需求。

完整代码示例

以下是一个完整的 HTML/CSS/JS 实现方案:

<!DOCTYPE html><html lang="zh-CN"><head>  <meta charset="UTF-8">  <title>localStorage 搜索历史示例</title>  <style>    * {      box-sizing: border-box;    }    body {      font-family: system-ui, sans-serif;      max-width600px;      margin40px auto;      padding0 20px;    }    .search-wrap {      display: flex;      gap8px;      margin-bottom20px;    }    #searchInput {      flex1;      padding10px 12px;      font-size16px;      border1px solid #ccc;      border-radius6px;    }    button {      border: none;      border-radius6px;      cursor: pointer;      background#2563eb;      color#fff;    }    #searchBtn {      padding10px 16px;    }    button:hover {      background#1d4ed8;    }    .history-block {      display: none;    }    .history-block.show {      display: block;    }    .history-header {      display: flex;      justify-content: space-between;      align-items: center;    }    .history-header h4 {      margin0;      font-size15px;      font-weight600;    }    #clearBtn {      background: transparent;      color#666;      padding0;      font-size13px;    }    #clearBtn:hover {      background: transparent;      color#333;    }    #historyBox {      margin-top:14px;    }    .history-item {      display: inline-flex;      align-items: center;      background#f3f4f6;      padding4px 8px;      border-radius16px;      margin4px 6px 4px 0;    }    .history-item .word {      margin-right6px;      font-size14px;    }    .history-item .close {      background: transparent;      color#888;      width14px;      height14px;      padding0;      font-size12px;      line-height1;      display: inline-flex;      align-items: center;      justify-content: center;      cursor: pointer;    }    .history-item .close:hover {      background: transparent;      color#333;    }  </style></head><body>  <div class="search-wrap">    <input id="searchInput" type="text" placeholder="输入搜索词,回车或点击搜索">    <button id="searchBtn">搜索</button>  </div>  <div class="history-block" id="historyBlock">    <div class="history-header">      <h4>搜索历史</h4>      <button id="clearBtn">清空</button>    </div>    <div id="historyBox"></div>  </div>  <script>    const STORAGE_KEY = 'search_history'    const MAX_COUNT = 15    function escapeHtml(str) {      return str        .replace(/&/g'&amp;')        .replace(/</g'&lt;')        .replace(/>/g'&gt;')        .replace(/"g'&quot;')        .replace(/'/g'&#039;')    }    function getHistory() {      try {        const str = localStorage.getItem(STORAGE_KEY)        return str ? JSON.parse(str) : []      } catch (e) {        console.error('读取历史出错', e)        return []      }    }    function saveHistory(keyword) {      const kw = keyword.trim()      if (!kw) return      let list = getHistory()      list = list.filter(item => item !== kw)      list.unshift(kw)      if (list.length > MAX_COUNT) {        list = list.slice(0MAX_COUNT)      }      try {        localStorage.setItem(STORAGE_KEYJSON.stringify(list))      } catch (err) {        console.warn('localStorage 存储空间不足', err)      }      renderHistory()    }    function removeItem(word) {      let list = getHistory()      list = list.filter(item => item !== word)      localStorage.setItem(STORAGE_KEYJSON.stringify(list))      renderHistory()    }    function clearHistory() {      localStorage.removeItem(STORAGE_KEY)      renderHistory()    }    function renderHistory() {      const block = document.getElementById('historyBlock')      const box = document.getElementById('historyBox')      const list = getHistory()      if (list.length === 0) {        block.classList.remove('show')        box.innerHTML = ''        return      }      block.classList.add('show')      let html = ''      list.forEach(item => {        const safeWord = escapeHtml(item)        html += `          <div class="history-item">            <span class="word">${safeWord}</span>            <button class="close" data-word="${safeWord}" type="button">×</button>          </div>        `      })      box.innerHTML = html    }    document.getElementById('searchBtn').addEventListener('click'() => {      const input = document.getElementById('searchInput')      saveHistory(input.value)      input.value = ''    })    document.getElementById('searchInput').addEventListener('keydown'(e) => {      if (e.key === 'Enter') {        const input = document.getElementById('searchInput')        saveHistory(input.value)        input.value = ''      }    })    document.getElementById('clearBtn').addEventListener('click', clearHistory)    document.getElementById('historyBox').addEventListener('click'(e) => {      if (e.target.classList.contains('close')) {        removeItem(e.target.dataset.word)      }    })    window.addEventListener('storage'(e) => {      if (e.key === STORAGE_KEY) {        renderHistory()      }    })    renderHistory()  </script></body></html>

存储规则解析

由于 localStorage 仅支持字符串存储,本方案通过 JSON.stringify 和 JSON.parse 实现数组的序列化与反序列化。数据结构采用简单的字符串数组,轻量且高效:

["前端面试""localStorage 使用""JS 实战"]

核心业务逻辑

  • 无效过滤:搜索内容为空或纯空格时,直接拦截不存储。
  • 去重置顶若关键词已存在,先移除旧数据,再将新数据插入数组头部。
  • 数量限制:当记录数超过设定阈值(如 15 条)时,自动截断数组,仅保留最新的 N 条。
  • 视图同步:所有数据操作完成后,立即触发页面重新渲染,确保 UI 与数据状态一致。

搜索历史功能看似简单,但要实现健壮、优雅且无 Bug 的体验,需综合考量存储逻辑、去重算法、异常容错、XSS 安全防护及交互细节。本套基于 localStorage 的实现方案零成本、高可用,是前端开发者必备的基础技能。未来若需对接后端或多端同步,只需在此架构上增加接口请求与数据合并逻辑即可无缝拓展。

#搜索历史 #localStorage

【声明】内容源于网络
0
0
wordpress知识
各类跨境出海行业相关资讯
内容 354
粉丝 0
wordpress知识 各类跨境出海行业相关资讯
总阅读10.1k
粉丝0
内容354