我有一个搜索框,我想在立即输入时显示搜索结果;但是在快速打字时我遇到了问题。
JavaScript的:
function CreateXmlHttp() {
var xmlhttp;
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("your browser doesn't support ajax");
return false;
}
}
}
return xmlhttp;
}
function searchfunc(value) {
if (value!='') {
var xmlhttp = CreateXmlHttp();
xmlhttp.open('GET','http://example.com/ajax/instant_search.php?q='+value,true);
xmlhttp.send(null);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById('search_result').innerHTML = xmlhttp.responseText+'<li><a href="http://example.com/search.php?q='+value+'">full search for <strong>'+value+'</strong></a></li>';
}
}
} else document.getElementById('search_result').innerHTML = '';
}
HTML:
<input id="search_box" type="text" placeholder="type to search..." onkeyup="searchfunc(this.value)">
<ul id="search_result"></ul>
如何在新的按键上中止以前的XMLHttpRequest?
答案 0 :(得分:0)
如果您要中止该请求,您可能会在发现用户仍在键入时首先阻止该请求被发送。
var timeout, timer = 150;
function searchfunc(value) {
clearTimeout(timeout);
setTimeout(function () {
if (value!='') {
var xmlhttp = CreateXmlHttp();
xmlhttp.open('GET','http://example.com/ajax/instant_search.php?q='+value,true);
xmlhttp.send(null);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById('search_result').innerHTML = xmlhttp.responseText+'<li><a href="http://example.com/search.php?q='+value+'">full search for <strong>'+value+'</strong></a></li>';
}
}
} else document.getElementById('search_result').innerHTML = '';
}, timer);
}
这将做的是当用户按下一个键时,启动一个等待150ms的setTimeout。如果在150ms内再次触发该功能,则清除并重新启动该间隔。一旦间隔最终完成,就会发出ajax请求。
这与使用中止相同,除了服务器没有被ajax请求轰炸的事实,无论如何你都会中止,并且请求会增加150ms的延迟。
有些库可以更好地处理这个问题,例如http://benalman.com/projects/jquery-throttle-debounce-plugin/(它不需要jQuery)
使用该插件,您可以每timer
ms发送不超过1个请求,导致第一个密钥始终发送请求,而另一个密钥在timer
ms过去之前未发送,给你一个更实时的结果。
答案 1 :(得分:0)
在这里,我将分享我在stencilsjs项目中为实现这种情况所做的一些概述,
首先,我为项目创建了单独的xmlApi.ts
通用文件,并在其中编写了以下代码
// common XMLHttpRequest for handling fetch request
// currently using this XMLHttpRequest in search component to fetch the data
let xmlApi
// Create the XHR request
const request = new XMLHttpRequest()
const fetchRequest = (url: string, params: any) => {
// Return it as a Promise
return new Promise((resolve, reject) => {
// Setup our listener to process compeleted requests
request.onreadystatechange = () => {
// Only run if the request is complete
if (request.readyState !== 4) { return }
// Process the response
if (request.status >= 200 && request.status < 300) {
// If successful
resolve(request)
} else {
// If failed
reject({
status: request.status,
statusText: request.statusText
})
}
}
// If error
request.onerror = () => {
reject({
status: request.status,
statusText: request.statusText
})
}
// Setup our HTTP request
request.open(params.method, url, true)
// Setup our HTTP request headers
if (params.headers) {
Object.keys(params.headers).forEach(key => {
request.setRequestHeader(key, params.headers[key])
})
}
// Send the request
request.send(params.body)
})
}
xmlApi = {
// exporting XMLHttpRequest object to use in search component to abort the previous fetch calls
request,
fetchRequest
}
export default xmlApi
第二,我已经通过onTextInput方法传递了 event 对象,以使用event.target.value
HTMl:
<input id="search_box" type="text" placeholder="type to search..."
onInput={event => { this.onTextInput(event) }}/>
示例HTML进行建议:
这里基于showSuggestionListFlag
,我已经显示了搜索建议列表,还使用了CSS来正确对齐div并正确输入标签
<div class={'search-result ' + (this.showSuggestionListFlag ? 'show' : '')}>
<ul class="dropdown-list">
{this.responseData && this.responseData.map((item, index) => (
<li class="list-element">{item} </li>
))}
</ul>
</div>
在我的ts代码中,我导入了我的xmlApi
这里我刚刚从代码中编写了一些逻辑代码,我还使用了async
和await
来处理项目代码中的承诺/拒绝,根据您的代码,您可以处理自己的承诺/拒绝
代码:
import xmlApi from './xmlApi'
onTextInput (event) { // first created bodydata here using `event.target.value`
const opts = {
method: 'POST',
body: bodyData,
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
}
}
try {
// aborting the previous xhr request call
if (xmlApi.request) {
xmlApi.request.abort()
}
const responseData = xmlApi.fetchRequest(endPointUrl, opts)
.then(data => {
consolep.log(`xhr request success`)
return JSON.parse(data['response'])
})
.catch(error => {
console.log.debug(`xhr request cancelled/failed : ${JSON.stringify(error)}`)
}) //use responseData
if(responseData){this.showSuggestionListFlag = true}
} catch (e) {
console.log(`fetch failed`, e)
}
}
这是我对堆栈溢出的第一个答案。 谢谢!