jQuery show/hide焦点问题

4

需要在输入文本字段下方显示下拉菜单。目前的配置是,如果文本输入字段失去焦点,隐藏此下拉菜单。问题是,用户需要能够点击下拉菜单本身来显示另一个区域,但在这样做时,下拉菜单本身会在其他区域显示之前隐藏。注释掉Fiddle的15-17行代码以查看其他区域的正确显示。

     <!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个回答

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
});

演示 - 使用 setTimeout()


这只是使用 setTimeout() 的众多变化之一。您可以进行精细的设置以改善用户体验。
当然,可能还有更有效的方法将所有内容组合在一起。


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();
});  

+1,因为这是一个可行的解决方案。但需要记住,当使用.stopPropagation();时,任何绑定到.addresspicker.dropdown父级的点击事件将不再触发,当这些元素被点击时。尽管在这种特定情况下,我怀疑这不会引起任何问题,除非在某个阶段为div.autofilldiv.sectionform分配了点击事件。 - Nope

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接