2013-04-08 98 views
4

在输入文本字段下方显示下拉菜单。当前配置为在文本输入字段失焦时隐藏此下拉菜单。问题是,用户需要能够点击下拉本身来显示另一个区域,但是在此过程中,下拉本身会在其他区域显示之前隐藏。注释掉Fiddle第15-17行以查看其他区域的正确显示。jQuery显示/隐藏焦点问题

 <!DOCTYPE html> 
     <html lang="en"> 
     <head> 
     <title>Dynamic show/hide</title> 
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
     <script src="http://code.jquery.com/jquery-1.9.1.js"></script> 
     <script> 
      $(function() { 

       $(".addressFill").hide(); 
       $(".dropdown").hide(); 

       function showElem() { 
        $(".addressFill").show(); 
       } 

       $(".addresspicker").click(function() { 
        $("ul.dropdown").toggle(); 
       }); 

       // Problem starts here 
       $(".addresspicker").focusout(function() { 
        $(".dropdown").hide(); 
       }); 
       // ends 

       $("ul.dropdown").on("click", "li", showElem); 
      }); 
     </script> 
     <style> 
     .dropdown { margin-left: 0.5em; padding: 0.5em; background: #fff; position: absolute; z-index: 999; border-top: 1px solid #B9B9B9; border-left: 1px solid #B9B9B9; border-right: 1px solid #7D7D7D; border-bottom: 1px solid #7D7D7D; } 
     ul { list-style-type: none; } 
     .dropdown li { padding: 0.5em; } 
     .dropdown li:hover { background-color: #eee; } 
     .dropdown li a:hover { text-decoration: none; } 
     p.addressFill { float: right; } 
     </style> 
     </head> 
     <body> 
    <form> 
<fieldset> 
     <div class="section"> 
      <label class="FieldLabel">Address:<span class="required">*</span></label> 
      <div class="autofill"> 
     <input name="" maxlength="38" size="38" id="" type="text" title="addresspicker" class="addresspicker" /> 
     <ul class="dropdown"> 
      <li><a href="#">Item 1</a></li> 
      <li><a href="#">Item 2</a></li> 
      <li><a href="#">Item 3</a></li> 
      <li><a href="#">Item 4</a></li> 
     </ul> 
     </div> 
    </div> 
     <p class="addressFill"> Show/hide section </p> 
     </fieldset> 
     </form> 
     </body> 
     </html> 

回答

2

我敢肯定有一个更好的办法,但你可以尝试利用setTimeout()具有延迟自动关闭菜单,当用户用它做和/或之后给定的时间已经过去了,类似这样的:

// stores the setTimeout result 
var timeOut; 

// closes the menu 
var closeMenu = function() { 
    $("ul.dropdown").hide(); 
}; 

// resets the timeout using the specified delay 
var resetTimeout = function(newDelay){ 
    if (timeOut > 0) { 
      clearTimeout(timeOut); 
     } 

     timeOut = setTimeout(function() { 
      closeMenu() 
     }, newDelay); 
}; 

$(function() { 
    // use to store timeout 
    var timeOut = null; 

    // ...removed unchanged code for readability 

    // Problem starts here 

    // reset timeout when focus is lost on input 
    $(".addresspicker").focusout(function() { 
     resetTimeout(1000); 
    }); 

    // reset the timeout when moving over or leaving the menu 
    $("ul.dropdown").on('mousemove mouseleave', function() { 
     resetTimeout(1000); 
    }) 
    // ends 

    // ...removed unchanged code for readability 
}); 

DEMO - 使用setTimeout()


这只是使用setTimeout()的众多变体之一。您可以非常细致地改进用户体验。
这可能是一种更有效的方法,可以一起完成整个过程。

+0

对此答案+1。:D – 2013-04-08 07:48:16

1

你可以使用.stopPropagation();

jsfiddle - 文档中基本上会点击隐藏下拉,除非你点击.addresspicker.dropdown

// Removed the focusout and added these... 
$(".addresspicker, .dropdown").click(function (e) { 
    e.stopPropagation(); 
}); 

$(document).click(function(e){ 
    $("ul.dropdown").hide(); 
}); 
+0

+1因为这是一个工作解决方案。只是要记住,当使用'.stopPropagation();'时,任何绑定到'.addresspicker'或'.dropdown'的父项的单击事件现在不会在点击这些元素时被触发。尽管在这种特定情况下,我怀疑这会导致任何问题,除非'div.autofill','div.section'或'form'在某个阶段会分配一个点击事件。 – Nope 2013-04-08 08:22:09