丢失父焦点时隐藏无序列表

时间:2016-01-29 10:02:58

标签: javascript jquery html

我有一个输入字段。当用户关注该输入时,该输入下方会出现无序列表。

当用户点击其中一个列表子项时,数据被插入到输入中,并且无序列表被隐藏。

当前问题

如果用户点击输入,但未选择任何选项,然后单击文档中的其他位置,则仍会显示无序列表。

如果我错过了某种我可以用来解决这个问题的事件,我不会这样做。

$('body').on('focus blur click', '.autocomplete input , .autocomplete ul,  .autocomplete li' , function() {

if (event.type === 'focus' && event.target.nodeName == 'INPUT') { 
  $(this).siblings('ul').show();
 } else if ((event.type === 'blur' || event.type === 'click' ) && event.target.nodeName == 'LI') {
  $(this).parent('ul').hide();
 }

});


$('body').on('click' ,'li' ,function() {
 
 $('#P1_FIRST_NAME').val($(this).attr('data-value'));

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<div class="input__container autocomplete">
    <div class="input__label__container">
        <label for="P1_FIRST_NAME" tabindex="999">Autocomplete</label>
    </div>
    <input type="text" id="P1_FIRST_NAME" class="text_field" autocomplete="off" value="">
    <ul for="P1_FIRST_NAME" style="display: none;">
        <li tabindex="1" data-value="MAD">Madder</li>
        <li tabindex="1" data-value="SAD">Sandy</li>
    </ul>
</div>

3 个答案:

答案 0 :(得分:2)

检查此fiddle

您需要在html绑定点击事件,并在inputul级别停止事件传播

$('body').on('focus blur click', '.autocomplete input , .autocomplete ul,  .autocomplete li' , function(e) {

if (event.type === 'focus' && event.target.nodeName == 'INPUT') { 
  $(this).siblings('ul').show();
 } else if ((event.type === 'blur' || event.type === 'click' ) && event.target.nodeName == 'LI') {
  $(this).parent('ul').hide();
 }
 e.stopPropagation();

});


$('body').on('click' ,'li' ,function(e) {

 $('#P1_FIRST_NAME').val($(this).attr('data-value'));
 e.stopPropagation();

});

$("html").click( function(e) {

 $('ul').hide();

});

答案 1 :(得分:1)

注释

  • 您可以使用.on()的对象传递多个事件处理程序。不要使用if / else在不同事件的不同行为之间切换。
  • 不要将要设置的元素的ID硬编码到JS代码中。使用data-属性(请参阅下面的targetSelector)。
  • 使用.closest()导航到正确的元素。
  • <ul>使用CSS定位,以便它不会压低下面的内容。

&#13;
&#13;
$('body')
    .on({
        'focus': function() {
            var $ul = $(this).closest('.autocomplete').find('ul');
            $ul.width( $(this).width() ).show();
        },
        'blur': function() {
            var $ul = $(this).closest('.autocomplete').find('ul');
            setTimeout(function () { $ul.fadeOut('fast'); }, 250);
        }
    }, '.autocomplete input')
    .on('click', '.autocomplete li', function() {
        var targetSelector = $(this).closest('ul').data('for');
        $(targetSelector).val( $(this).data('value') );
        $(this).closest('ul').fadeOut('fast');
    });
&#13;
.autocomplete {
  position: relative;
}
.autocomplete ul {
  display: none;
  position: absolute;
  margin: 0;
  padding: 0;
  list-style: none;
  background-color: white;
  box-shadow: 4px 4px 5px -2px rgba(0,0,0,0.59);
  border: 1px solid #efefef;
}
.autocomplete ul li {
  padding: 3px;
  cursor: pointer;
}
.autocomplete ul li:hover {
  background-color: #FCF3CF;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="input__container autocomplete">
    <div class="input__label__container">
        <label for="P1_FIRST_NAME" tabindex="999">Autocomplete</label>
    </div>
    <input type="text" id="P1_FIRST_NAME" class="text_field" autocomplete="off" value="">
    <ul data-for="#P1_FIRST_NAME">
        <li data-value="MAD">Madder</li>
        <li data-value="SAD">Sandy</li>
    </ul>
</div>
<p>content below content below content below content below content below</p>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

如果页面上有多个选择器,则需要使用“this”选择器,但是这里有一种方法可以单击该字段以显示ul列表并单击远离ul列表再次隐藏它:

$( ".text_field" ).click(function() {
  $('ul').show();
});

$(document).mouseup(function(e) {
    var container = $("ul");
    if (!container.is(e.target) && container.has(e.target).length === 0) {
        $('ul').hide();
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<div class="input__container autocomplete">
    <div class="input__label__container">
        <label for="P1_FIRST_NAME" tabindex="999">Autocomplete</label>
    </div>
    <input type="text" id="P1_FIRST_NAME" class="text_field" autocomplete="off" value="">
    <ul for="P1_FIRST_NAME" style="display: none;">
        <li tabindex="1" data-value="MAD">Madder</li>
        <li tabindex="1" data-value="SAD">Sandy</li>
    </ul>
</div>