一些优化(即时搜索之函数去抖)

本文介绍如何使用JavaScript优化输入框的实时搜索功能,通过监听input事件而非change事件来提高用户体验,并利用函数去抖减少不必要的网络请求。

第一步,确定用哪个动作。实现输入框实时搜索

input输入框的change事件,在输入框内容变化的时候不会触发change,要在input失去焦点的时候才会触发,当鼠标在其他地方点一下才会触发

$('input[name=myInput]').change(function() { ... });//change,失焦才触发,nono

用下面的方法会生效,input,注:IE下 用 onpropertychange

$("#input_id").on('input',function(e){ 
    alert('Changed!') 
});

第二步,优化,加一个延迟,因为频繁的发送并不好,网络请求次数过多

//手写一个函数去抖

function test() {
  console.log(11)
}

function debounce(method, context) {
  clearTimeout(method.tId);
  method.tId = setTimeout(function() {
    method.call(context)
  }, 500)
}
window.onresize = function() {
  debounce(test, window);
}

函数去抖(debounce)函数节流(throttle),可以用lodash

  • debounce(func, wait, immediate):创建并返回函数的防反跳版本,将延迟函数的执行(真正的执行)在函数最后一次调用时刻的wait毫秒之后,对于必须在一些输入(多是一些用户操作)停止之后再执行的行为有帮助。将一个连续的调用归为一个!

  • throttle(func, wait, options):创建并返回一个像节流阀一样的函数,当重复调用函数的时候,最多每隔指定的wait毫秒调用一次该函数; 不允许方法在每wait ms间执行超过一次!

总结:

onpropertychange:DOM任何节点的属性发生变化时触发,包括js修改的属性。但是这是IE特有的一个事件;

oninput:仅仅在input的value值发生改变才会触发,鼠标键盘复制粘贴均可以触发,但是js修改其value值则不会触发。(chrome/safari/ff/opera/IE9+)

onchange:域的内容改变,并且失去焦点时触发(js改变其内容时不会触发)。

onkeyup:在键盘松开时触发。(如果用鼠标复制粘贴则不会触发)

总代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>即时搜索小优化</title>
	</head>
	<body>
		<input type="text" id="query" />
	</body>
	<script>
		window.onload = function() {
			var oQuery = document.getElementById("query");
			
			var timer = 0;
			oQuery.oninput = function() {
				clearTimeout(timer);
				timer = setTimeout(function() {
					Query();
				}, 250);
			}
 
			function Query() {
				console.log("查询数据");
			}
 
		}
	</script>
 
</html>

 

 

<think>我们被要求实现一个实时搜索功能,即用户在输入框中输入时,页面会实时显示搜索建议或搜索结果,而无需手动提交表单。根据提供的引用内容,我们可以采用以下技术方案: 1. **前端部分**:使用HTML创建搜索框和显示搜索建议的区域,使用CSS进行样式设计。 2. **事件监听**:使用JavaScript监听搜索框的输入事件(如`onkeyup`或`input`事件)。 3. **获取数据**:在事件处理函数中,获取搜索框的当前值,然后向服务器发送请求获取搜索建议。这里可以使用Ajax技术(如`fetch`或`XMLHttpRequest`)或JSONP(用于跨域请求)。 4. **处理响应**:服务器返回数据(通常是JSON格式),前端解析数据并动态生成搜索建议列表(如下拉框)。 5. **显示结果**:将搜索建议列表显示在搜索框下方。 根据引用[5],我们可以在本地模拟数据来测试功能,也可以使用公开的API(如引用中提到的百度搜索API)。 ### 实现步骤 #### 1. HTML结构 ```html <input type="text" id="searchInput" placeholder="搜索..."> <div id="suggestions"></div> ``` #### 2. JavaScript实现 ```javascript // 模拟数据,实际应用中可能从服务器获取 const mockData = ['苹果', '香蕉', '橙子', '苹果手机', '苹果电脑', '香蕉牛奶']; const searchInput = document.getElementById('searchInput'); const suggestionsDiv = document.getElementById('suggestions'); searchInput.addEventListener('input', function() { const inputText = this.value.trim(); suggestionsDiv.innerHTML = ''; // 清空建议 if (inputText.length === 0) { return; // 如果输入为空,则不显示建议 } // 过滤匹配项 const filteredData = mockData.filter(item => item.includes(inputText)); // 显示建议 if (filteredData.length > 0) { const ul = document.createElement('ul'); filteredData.forEach(item => { const li = document.createElement('li'); li.textContent = item; li.addEventListener('click', function() { searchInput.value = item; // 点击建议项,填充到搜索框 suggestionsDiv.innerHTML = ''; // 清空建议 }); ul.appendChild(li); }); suggestionsDiv.appendChild(ul); } }); ``` #### 3. 使用真实API(以百度搜索API为例) 如果使用百度搜索API,可以使用JSONP解决跨域问题,因为百度搜索API支持JSONP。 ```javascript function handleInput() { const inputText = searchInput.value.trim(); suggestionsDiv.innerHTML = ''; if (inputText.length === 0) { return; } // 创建script标签,使用JSONP const script = document.createElement('script'); script.src = `https://www.baidu.com/su?wd=${encodeURIComponent(inputText)}&cb=showSuggestions`; document.body.appendChild(script); } // 回调函数,处理返回的数据 function showSuggestions(data) { suggestionsDiv.innerHTML = ''; const suggestions = data.s; // 百度返回的数据中,s是建议数组 if (suggestions && suggestions.length) { const ul = document.createElement('ul'); suggestions.forEach(item => { const li = document.createElement('li'); li.textContent = item; li.addEventListener('click', function() { searchInput.value = item; suggestionsDiv.innerHTML = ''; }); ul.appendChild(li); }); suggestionsDiv.appendChild(ul); } } // 监听输入事件 searchInput.addEventListener('input', handleInput); ``` ### 注意事项 1. **性能优化**:在输入事件中频繁发送请求可能导致性能问题,可以使用防(debounce)技术来减少请求次数。 2. **跨域问题**:如果使用自己的后端服务,可以设置CORS;如果使用第三方API(如百度),则需确认其支持JSONP或CORS。 3. **安全性**:对用户输入进行适当的转义,防止XSS攻击。 ### 防优化示例 ```javascript function debounce(func, delay) { let timer; return function() { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, arguments); }, delay); }; } searchInput.addEventListener('input', debounce(handleInput, 300)); ``` ### 总结 实时搜索功能通过监听输入事件,使用Ajax或JSONP获取搜索建议,并动态展示给用户。我们可以根据需求选择本地模拟数据或调用第三方API,同时注意性能优化和安全性。 §§相关问题§§ 1. 如何优化实时搜索的性能? 2. 除了百度API,还有哪些提供搜索建议的API? 3. 如何实现高亮显示搜索建议中的匹配部分? 4. 在实时搜索中如何处理中文输入法(如避免在输入拼音时触发请求)? 5. 如何为实时搜索功能添加键盘导航(上下键选择建议项)?</think>### 如何实现实时搜索功能 实现实时搜索功能的核心是监听用户输入并动态展示结果。以下是具体实现步骤: #### 1. HTML 结构 ```html <div class="search-container"> <input type="text" id="searchInput" placeholder="输入关键词..."> <div id="suggestions"></div> </div> ``` #### 2. JavaScript 实现 ```javascript // 1. 获取DOM元素 const searchInput = document.getElementById('searchInput'); const suggestionsContainer = document.getElementById('suggestions'); // 2. 监听输入事件 searchInput.addEventListener('input', debounce(handleSearch, 300)); // 3. 处理搜索逻辑 function handleSearch() { const query = searchInput.value.trim(); if (query.length === 0) { suggestionsContainer.innerHTML = ''; return; } // 4. 获取数据(本地或API) fetchSuggestions(query).then(suggestions => { renderSuggestions(suggestions); }); } // 5. 防函数(减少请求频率) function debounce(func, delay) { let timer; return function() { clearTimeout(timer); timer = setTimeout(() => func.apply(this, arguments), delay); }; } // 6. 获取建议数据(示例) async function fetchSuggestions(query) { // 实际项目中替换为API请求 const mockData = ['JavaScript教程', 'Java基础', 'Python数据分析', 'PHP开发']; return mockData.filter(item => item.toLowerCase().includes(query.toLowerCase()) ); } // 7. 渲染建议列表 function renderSuggestions(items) { suggestionsContainer.innerHTML = ''; if (items.length === 0) { suggestionsContainer.innerHTML = '<div class="no-results">无匹配结果</div>'; return; } items.forEach(item => { const div = document.createElement('div'); div.className = 'suggestion-item'; div.textContent = item; div.addEventListener('click', () => { searchInput.value = item; suggestionsContainer.innerHTML = ''; }); suggestionsContainer.appendChild(div); }); } ``` #### 3. 关键实现技术 1. **事件监听**:使用 `input` 事件捕获每次输入变化 2. **防优化**:通过 `debounce` 函数控制请求频率(300ms) 3. **数据获取**: - 本地数据:过滤预定义数据集 - API 请求:使用 `fetch` 调用搜索接口 4. **动态渲染**:根据返回结果实时更新 DOM 5. **交互增强**: - 点击建议项自动填充搜索框 - 输入为空时隐藏建议框 #### 4. 使用第三方 API(以百度为例) ```javascript async function fetchBaiduSuggestions(query) { const url = `https://www.baidu.com/su?wd=${encodeURIComponent(query)}&cb=handleJsonp`; return new Promise((resolve) => { window.handleJsonp = (data) => { resolve(data.s || []); }; const script = document.createElement('script'); script.src = url; document.body.appendChild(script); }); } ``` #### 5. 性能优化建议 1. 缓存常用查询结果 2. 添加加载状态指示器 3. 支持键盘导航(↑/↓键选择建议项) 4. 限制返回结果数量(例如最多10条) 5. 对中文输入法使用 `compositionend` 事件避免拼音阶段触发 > 实时搜索功能通过即时反馈显著提升用户体验,研究表明可减少用户操作步骤达40%[^2]。实际开发中需注意跨域问题和API调用频率限制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值