最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Blur issues on drop-down search box in jQuery - Stack Overflow

programmeradmin1浏览0评论

I've implemented a search box that acts as a filter. When a user clicks in the search area, a drop-down box is displayed showing all of the possible options. Typing in the search box filters the results. Clicking outside of the box hides the results.

It uses the following HTML/CSS heiarchy

<div class="search">
    <input type="text" name="search" value="search" placeholder="search"/>
    <div class="results">
        <div class="result">
            Result 1
        </div>
        <div class="result">
            Result 2
        </div>
        ...
    </div>
</div>

I use jQuery to show/hide the dropdown on focus/blur events

var searchBar = {
    init : function(){
        $('input[name=search]').focus(searchBar.openSearch);
        $('input[name=search]').blur(searchBar.closeSearch);
        $('div.result').each(function(e){
            $(this).click(draftboardDynamic.selectResult);
        }); 
    },
    openSearch : function(e){
        $('div.results').show();
    },
    closeSearch : function(e){
        $('div.results').hide();
    },
    selectResult : function(e){
        console.log($(this));
    },
}
$(document).ready(searchBar.init);

This works quite well and I can open, close, and search (JS removed for clarity) without issue. The only bit I'm having trouble with is selecting results. The blur event seems to trigger before result.click events and the handler is never called. I can correct this issue by removing the blur binding, however, I can't figure out how to close my drop-down box when the input loses focus.

Any ideas?

I've implemented a search box that acts as a filter. When a user clicks in the search area, a drop-down box is displayed showing all of the possible options. Typing in the search box filters the results. Clicking outside of the box hides the results.

It uses the following HTML/CSS heiarchy

<div class="search">
    <input type="text" name="search" value="search" placeholder="search"/>
    <div class="results">
        <div class="result">
            Result 1
        </div>
        <div class="result">
            Result 2
        </div>
        ...
    </div>
</div>

I use jQuery to show/hide the dropdown on focus/blur events

var searchBar = {
    init : function(){
        $('input[name=search]').focus(searchBar.openSearch);
        $('input[name=search]').blur(searchBar.closeSearch);
        $('div.result').each(function(e){
            $(this).click(draftboardDynamic.selectResult);
        }); 
    },
    openSearch : function(e){
        $('div.results').show();
    },
    closeSearch : function(e){
        $('div.results').hide();
    },
    selectResult : function(e){
        console.log($(this));
    },
}
$(document).ready(searchBar.init);

This works quite well and I can open, close, and search (JS removed for clarity) without issue. The only bit I'm having trouble with is selecting results. The blur event seems to trigger before result.click events and the handler is never called. I can correct this issue by removing the blur binding, however, I can't figure out how to close my drop-down box when the input loses focus.

Any ideas?

Share Improve this question edited Nov 9, 2015 at 12:34 Anders 8,60810 gold badges60 silver badges99 bronze badges asked May 16, 2012 at 22:20 Jason GeorgeJason George 7,0128 gold badges45 silver badges60 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

This is a tough one because the .blur event will always fire before the .click. There are two possible solutions, neither of which is particularly desirable:

  1. Unbind the .blur event when hovering over div.result. Rebind it on mouseout.
  2. Instead of doing this with .blur, bind a click event to the document and check that the target is not one of the search ponents.

Use "mousedown" event instead of "click":

$(".container")
  .on("blur focus", "input", function({type}) {
    $(this).next().toggle(type === "focusin");
  })
  .on("mousedown", "ul", function({target: {innerText}}) {
    $(this).prev().val(innerText);
  });

$(".container")
  .on("blur focus", "input", function({type}) {
    $(this).next().toggle(type === "focusin");
  })
  .on("mousedown", "ul", function({target: {innerText}}) {
    $(this).prev().val(innerText);
  });
.container {
  position: relative;
  display: inline-block;
}
  
input, ul {
  border: solid 1px black;
}

ul {
  list-style: none;
  position: absolute;
  left: 0;
  right: 0;
  z-index: -1;
  margin: -1px 0 0;
  padding: 0;
}
  
label, li {
  cursor: pointer;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  
<label for="_input"><b>Select value:</b></label>

<div class="container">
  <input id="_input">
  <ul style="display:none">
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
</div>

<a href="#_input">Picked a wrong value?</a>

Binding and unbinding the blur event on mouse over / mouse out works. For those interested i've created a fiddle to demonstrate this: https://jsfiddle/AdamKMorris/uoqvfy2L/

My example uses basic jquery and .bind/.unbind to toggle the search box:

$("#searchButton").click(function()
{
    $("#searchBar").slideToggle();
    $("#searchText").focus();
}).mouseover(function()                 
{
    $("#searchText").unbind('blur');
}).mouseout(function()
{
    $("#searchText").bind('blur', function()
    {
        $("#searchBar").slideToggle("fast");
    });
});
发布评论

评论列表(0)

  1. 暂无评论