这是参考这个小提琴的代码:http://jsfiddle.net/x8whpx09/17/
我正在尝试创建一个搜索框,其中包含当用户输入内容时弹出的结果列表。我遇到的问题是当用户点击输入元素以外的任何地方时,搜索结果列表将关闭。我有一个附加到父DIV的焦点事件,但即使我将它附加到输入我得到相同的行为。我想要的是让用户能够选择列表上的滚动条而不是列表消失。如果他们点击输入外部或列表,则列表应该关闭。
现在它无论在哪里点击都会关闭,除非它在输入中。
编辑:performSearch函数体包装在一个AJAX请求中。
解决方案:我终于弄清楚发生了什么。您需要绑定到mousedown事件并返回false,以便允许在下拉列表中选择滚动条。这question终于给了我解决方案。
$target.on('mousedown',function (event) {
return false;
});
以下是小提琴的代码:
var search = {
closing: null,
performSearch: function(elem, e) {
var $this = $(elem);
var $target = $('#search-results');
if ($target.length === 0) {
$target = $('<div id="search-results" class="sb-list"></div>');
$target.insertAfter($this);
var p = $this.position();
$target.css('top', (p.top + $this.height() + 15) + 'px');
$target.css('width', ($this.width() + p.left + 10) + 'px');
$target.css('width', ($this.width() + 25) + 'px');
$target.css('left', (p.left) + 'px');
$target.slideDown('fast', function() {
$target.css('overflow', 'auto');
});
$target.on('mouseover', '.sb-row', function() {
$(elem).addClass('sb-active');
$('.sb-active').removeClass('sb-active');
});
$target.on('click', '.sb-row', search.click);
//$target.parent().on('focusin focusout', search.listFocus);
} else {
$target.empty();
$target.slideDown('fast', function() {
$target.css('overflow', 'auto');
});
}
for (i = 0; i < 40; i++) {
var html = [];
html.push('<div class="sb-row' + (i == 0 ? ' sb-active' : '') + '">');
html.push('<a href="#">test result' + i + '</a>');
html.push('</div>');
var $out = $(html.join(''));
$target.append($out);
}
},
delayClose: function(e) {
console.log('delayClose');
var self = this;
console.log('results focused: ' + $('#search-results').is(':focus'));
console.log('div focused: ' + $('#parent').is(':focus'));
search.closing = window.setTimeout(function() {
search.close.apply(self, arguments);
}, 1000);
},
listFocus: function(e) {
console.log(e.type);
var self = this;
window.clearTimeout(search.closing);
},
click: function(e) {
console.log('clicked');
},
close: function(e) {
console.log('closing');
window.clearTimeout(search.closing);
var $this = $(this);
$('#search-results').slideUp('fast');
}
};
$(document).ready(function() {
$searchBox = $('#search');
$searchBox.on('focus', function(e) {
this.value = '';
this.select();
e.stopPropagation();
return false;
});
$searchBox.on('keyup', function(e) {
search.performSearch($searchBox[0], e);
});
$searchBox.parent().on('focusout', search.delayClose);
});
&#13;
.sb-list {
position: absolute;
width: 250px;
top: 0;
left: 0;
height: 300px;
background: #FAFAFA;
border: solid 1px #999;
border-top: none;
display: none;
overflow: auto;
z-index: 92592;
-webkit-box-shadow: 0 2px 2px #999999;
-moz-box-shadow: 0 2px 2px #999999;
-ms-box-shadow: 0 2px 2px #999999;
box-shadow: 0 2px 2px #999999;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="parent">
<input type="text" id="search" />
</div>
&#13;
答案 0 :(得分:0)
这里有一些有问题的代码和需要修复的多项内容。如果您检查#search
(输入框),则会看到输入的每个字符的搜索结果都是附加的。也就是说,您最终会得到多个id="search-results"
元素。
针对此单个错误的一个非常简单的在线解决方案是将$('#search-results').remove();
添加到您的performSearch
处理程序函数中:
performSearch: function (elem, e) {
$('#search-results').remove();
// ...
}
我创建了一个updated JSFiddle来展示它的功能以及这引入的其他不便和错误,其中之一就是当您单击#search-results
下拉列表时缺少正确的事件处理。
我建议您尝试使用开发者工具或Javascript调试器在搜索代码中跟踪错误来源,因为您的代码中有许多部分需要修复或重新思考;一个答案太多了。