单击搜索结果div时停止焦点

时间:2015-02-11 20:54:08

标签: javascript jquery html

这是参考这个小提琴的代码: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;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

这里有一些有问题的代码和需要修复的多项内容。如果您检查#search(输入框),则会看到输入的每个字符的搜索结果都是附加的。也就是说,您最终会得到多个id="search-results"元素。

针对此单个错误的一个非常简单的在线解决方案是将$('#search-results').remove();添加到您的performSearch处理程序函数中:

performSearch: function (elem, e) {
    $('#search-results').remove();
    // ...
}

我创建了一个updated JSFiddle来展示它的功能以及这引入的其他不便和错误,其中之一就是当您单击#search-results下拉列表时缺少正确的事件处理。

我建议您尝试使用开发者工具或Javascript调试器在搜索代码中跟踪错误来源,因为您的代码中有许多部分需要修复或重新思考;一个答案太多了。