ajax实时搜索添加了按键上下功能



我希望有一个像谷歌一样的实时搜索框,我已经在后台实现了jquery ajax来获取结果,但我想启用当用户按下键时,我想像谷歌一样在ajax返回建议中添加一个类,当用户按下向上建议时,highlight将在用户按下enter时出现,它将进入href。以下是我的ajax返回html代码:

<ul id="suggestion" style="list-style-type: none;">
<li><a class="suggestion-link" href="http://eled.test/post/sunt-iure-nihil-deleniti-rerum"> Sunt Iure Nihil Deleniti Rerum.</a> 
</li>
<li><a class="suggestion-link" href="http://eled.test/post/porro-et-numquam-nihil-nesciunt-nesciunt"> Porro Et Numquam Nihil Nesciunt Nesciunt.</a> 
</li>
<li><a class="suggestion-link" href="http://eled.test/post/my-new-post-yeah"> My New Post Yeah !!</a> </li>
<li><a class="suggestion-link" href="http://eled.test/post/rerum-voluptatem-fuga-excepturi-provident-et-distinctio"> Rerum Voluptatem Fuga Excepturi Provident Et...</a> 
</li>
</ul>

下面是我的搜索表单

<form method="GET" action="{{route('home.search')}}" class="search-form" id="search-form" >
<div class="form-group">
<input type="text" name="keyword" id="search-input" placeholder="What are you looking for?" autocomplete="off">
<button type="submit" class="submit"><i class="fas fa-search"></i></button>
</div>

<ul id="suggestion" style="display: none;list-style-type: none; "></ul>
</form>

下面是我的ajax

$(document).ready(function() {
//sidebar search function ajax
$("#search-input").keyup(function() {
var keyword = $('#search-input').val();
var url = "{{route('home.ajax_search')}}";
if (keyword == "") {
$("#suggestion").html("");
$('#suggestion').hide();
}else {
$.ajax({
type: "GET",
url: url ,
data: {
keyword: keyword
},
success: function(data) {
$("#suggestion").html(data).show();
//console.log(data);
$('#search-input').on("keydown", function (e) {
var listItems = $('.suggestion-link');
switch(e.which) {
case 38:
console.log('up');
break;
case 40:
listItems.addClass('selected');
console.log('down');
break;
default: return;
}        
});
}
});

}
});
});

在ajax中,当按下和向上按键时,我可以让控制台日志正常工作。38/40但是我不能添加所选的类li元素,我遵循这个add keydown(键盘箭头向上/向下(对AJAX Live Search PHP的支持问题是我不能将类活动应用到返回元素,所以用户不会知道键向下/向上正在工作,这要归功于

首先,在渲染结果时,为每个li元素提供一个ID。ID可以是循环的索引。只需确保ID是连续的。然后你可以使用类似的东西:

let highlighted = 0;
$('#search-input').on('keydown', function(e) {

//check if pressed key is down or up
// 40 is a code for down arrow, 38 for up
if([38, 40].indexOf(e.which) < 0) 
return;
//remove highlighted class from all list elements here
$('#suggestion').find('li.highligted').removeClass('highligted');    
//handle down and up keypress here

hightlighted = e.which == 40 ? highlighted + 1 : highligted - 1;        

$('#suggestion-'+highlighted).addClass('highligted');
});

您不应该在success函数内绑定事件,因为对于每个请求,它都会添加一个新的侦听器,而您的旧侦听器仍处于连接状态,这可能会有问题。

从您的问题陈述中,我了解到您希望使用上下箭头键突出显示结果URL。这里有一个简短的工作示例,可能对您有所帮助。

const field = document.getElementById('search');
let focusIndex = -1;
// When field is focussed, you want to enable up and down navigation
field.onfocus = function () {
this.classList.add('allow-arrow-nav');
}
field.onblur = function () {
this.classList.remove('allow-arrow-nav');
}
// We will use event delegation to detect if "allow-arrow-nav" class is present
document.body.addEventListener('keydown', (e) => {
if (e.target.classList.contains('allow-arrow-nav')) {
// Key codes that we need to target are 38 (up) and 40 (down)
const allLis = document.querySelectorAll('#searchResults li');
const totalResults = allLis.length;
if (e.keyCode === 38 && focusIndex > 0) {
focusIndex--;
}
if (e.keyCode === 40 && focusIndex < totalResults - 1) {
focusIndex++;
}
[...allLis].forEach(liEl => liEl.classList.remove('is-focussed'));
const selectedLi = document.querySelector(`li[focus-index="${focusIndex}"]`);
if (selectedLi) {
selectedLi.classList.add('is-focussed');
const selectedInnerText = selectedLi.textContent;
e.target.value = selectedInnerText;
if (e.keyCode === 13) {
window.open(selectedLi.querySelector('a').getAttribute('href'), '_blank');
}
}
}
});
// Since we are delegating the events, you can make the list section dynamic and us a separate function to render it. You need to make sure that all relevant attributes, ids and classes are present to make it work.
#searchWrapper {
position: relative;
}
#searchResults {
list-style: none;
display: none;
margin: 0;
padding: 4px;
position: absolute;
border: 1px solid;
box-shadow: 0 1px 2px 2px #ccc;
top: 100%;
}
#searchResults a {
color: inherit;
text-decoration: none;
padding: 8px;
display: block;
}
#searchResults a:hover,
#searchResults li.is-focussed a {
background-color: #eee;
}
#search:focus ~ #searchResults {
display: block;
}
<div id="searchWrapper">
<input type="text" id="search" />
<ul id="searchResults">
<li focus-index="0"><a href="https://google.com" target="_blank">Result 1</a></li>
<li focus-index="1"><a href="https://google.com" target="_blank">Result 2</a></li>
</ul>
</div>

我希望这会有所帮助。

最新更新