修改HTML搜索框 实现搜索预览+点击查答案的次数限制功能
问答库搜索框功能优化实现
现存缺陷
- 原逻辑用户按下Enter键即扣除1次问答查看额度,无论输入问题是否存在于库中,返回无答案结果也会计费,规则不合理
- 无实时搜索预览能力,用户无法提前确认目标问题是否被收录
优化后逻辑
- 用户在搜索框输入内容时,实时模糊匹配库内已有问题,下拉展示匹配结果列表,该预览过程不扣除任何额度
- 移除原Enter键直接触发搜索扣额的逻辑,用户确认下拉列表中存在目标问题后,点击对应问题项查看答案时才扣除1次额度
- 单用户累计10次查看额度的规则保持不变,额度耗尽后弹出提示
核心修改点
- 将原Enter键触发的搜索逻辑拆分:输入事件绑定实时过滤函数,仅做列表匹配展示,不做次数统计
- 为下拉列表的每个问题项绑定点击事件,点击时先校验剩余额度,额度充足则提取对应答案展示、扣除1次次数,额度不足直接拦截提示
- 修复原代码中列表标签未闭合、失焦隐藏逻辑冲突的问题,调整交互避免点击列表时意外触发失焦隐藏
- 模糊匹配仅针对问题文本部分,不将答案内容纳入匹配范围,减少无关结果
完整修改后代码
<meta name="viewport" content="width=device-width, initial-scale=1"> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { padding: 20px; max-width: 800px; margin: 0 auto; } #myInput { width: 100%; font-size: 16px; padding: 12px 20px; border: 1px solid #ddd; margin-bottom: 12px; border-radius: 4px; } #myUL { list-style-type: none; padding: 0; margin: 0; position: relative; } #myUL li a { border: 1px solid #ddd; margin-top: -1px; background-color: #0a2351; padding: 12px; text-decoration: none; font-size: 18px; color: white; display: block; cursor: pointer; } #myUL li a:hover { background-color: #1a3a7a; } #answerBox { margin-top: 20px; padding: 16px; border: 1px solid #e0e0e0; border-radius: 4px; background-color: #f8f9fa; display: none; } #answerBox h4 { margin-bottom: 8px; color: #0a2351; } .tip { color: #666; font-size: 14px; margin-bottom: 8px; } </style> <body> <h2>DrNapester - 题库系统</h2> <p class="tip">剩余查看额度:<span id="countTip">10</span>/10</p> <input type="text" id="myInput" placeholder="输入问题关键词搜索..." title="搜索问题"> <ul id="myUL" style="display: none;"> <li style="display: none;"><a href="javascript:void(0)">问题1 - (((答案1)))</a></li> <li style="display: none;"><a href="javascript:void(0)">问题2 - (((答案2)))</a></li> <li style="display: none;"><a href="javascript:void(0)">问题3 - (((答案3)))</a></li> <li style="display: none;"><a href="javascript:void(0)">问题4 - (((答案4)))</a></li> <li style="display: none;"><a href="javascript:void(0)">问题5 - (((答案5)))</a></li> </ul> <div id="answerBox"></div> <script> // 已使用次数 var guesses = 0 var totalLimit = 10 var input = document.getElementById("myInput"); var UL = document.getElementById("myUL"); var answerBox = document.getElementById("answerBox"); var countTip = document.getElementById("countTip"); var allLi = UL.getElementsByTagName("li"); // 输入时实时触发匹配,不扣额度 input.addEventListener("input", function() { answerBox.style.display = "none"; var filter = input.value.trim().toUpperCase(); if(filter.length < 1) { UL.style.display = "none"; return false; } UL.style.display = "block"; var hasMatch = false; for (var i = 0; i < allLi.length; i++) { var a = allLi[i].getElementsByTagName("a")[0]; var fullText = a.innerHTML; // 提取问题部分(- 之前的内容)做匹配 var questionPart = fullText.split("- (((")[0].toUpperCase(); if (questionPart.indexOf(filter) > -1) { allLi[i].style.display = ""; hasMatch = true; } else { allLi[i].style.display = "none"; } } // 无匹配结果时隐藏列表 if(!hasMatch) UL.style.display = "none"; }); // 输入框聚焦时,有内容就展示匹配列表 input.addEventListener("focus", function(){ if(input.value.trim().length > 0) { input.dispatchEvent(new Event('input')); } }); // 点击列表项时才扣额度、展示答案 UL.addEventListener("click", function(e) { e.preventDefault(); if(e.target.tagName === 'A') { // 校验额度 if (guesses >= totalLimit) { alert("您的10次查看额度已用完。"); UL.style.display = "none"; return } // 提取问题和答案 var fullText = e.target.innerHTML; var question = fullText.split(" - (((")[0]; var answer = fullText.split("(((")[1].replace(")))", ""); // 展示答案 answerBox.innerHTML = `<h4>${question}</h4><p>${answer}</p>`; answerBox.style.display = "block"; // 扣除次数 guesses++; countTip.innerHTML = totalLimit - guesses; // 隐藏下拉列表 UL.style.display = "none"; } }); // 点击页面其他区域隐藏下拉列表 document.addEventListener("click", function(e) { if(e.target !== input && e.target.tagName !== 'A') { UL.style.display = "none"; } }) </script> </body> </html>
代码说明
- 页面顶部新增剩余额度实时展示,用户可直观看到剩余次数
- 下拉项点击采用事件委托实现,后续新增问题项无需重复绑定事件
- 模糊匹配仅匹配问题部分,不会因为答案包含关键词出现无关结果
- 移除了原逻辑中所有外部资源、外链跳转,所有交互均在当前页面完成
- 点击列表项后答案直接展示在页面下方,无需弹窗阻塞操作
内容的提问来源于stack exchange,提问作者Dr.Jaber ALShemmari
相关产品推荐
相关产品推荐

