jQuery:动态点击事件仅在第二次点击

时间:2018-03-18 07:56:16

标签: javascript jquery html

我创建了一个自定义表单,允许用户按名称查找特定选项,而不是在冗长的列表中搜索 - 对于媒体浏览器。代码执行我想要的一个例外。点击动态添加的建议不会在您第一次点击时触发点击事件。

点击屏幕上的任何其他位置似乎重置了这一点,然后让我能够点击我的选项并选择它。我不完全确定为什么会发生这种情况,但基于控制台输出,似乎我的代码在某个地方被卡住了才能继续。

$(document).ready(function() {
  // Custom select form
  $('select.custom_select').each(function(i) {
    var select = $(this);
    var custom_input = select.next().children('input');
    var delete_selection = custom_input.next();
    var suggestion_list = delete_selection.next();

    // Set defaults in the custom form
    var selected = select.find(":selected");
    if (selected.index() != 0) {
      select.val(selected.val()).change();
      custom_input.val(selected.text())
      custom_input.attr('readonly', true);
      delete_selection.addClass('option_selected');
    }

    // User is typing in the custom form
    custom_input.on("change keyup paste", function() {
      suggestion_list.empty();
      console.log('suggestions cleared');
      suggestion_list.css('visibility', 'hidden');
      custom_input.removeClass('no_matches');

      var user_input = custom_input.val();
      if (user_input != '') {

        // Show options to the user
        select.children('option').each(function(i) {
          let option = $(this);
          var text = option.text();
          if (text.toLowerCase().includes(user_input.toLowerCase())) {
            var re = new RegExp('(' + user_input + ')', 'gi');
            suggestion_list.append(`<li data-value="${option.val()}" data-name="${text}">${text.replace(re, '<span>$1</span>')}</li>`);
            console.log('suggestion added');
          }
        });

        if (suggestion_list.children().length == 0) {
          custom_input.addClass('no_matches');
        } else if (!custom_input.attr('readonly')) {
          suggestion_list.css('visibility', 'visible');
          suggestion_list.focus();
        }
      }
    });

    // Choose an option
    suggestion_list.on('click', 'li', function() {
      select.val(parseInt($(this).attr('data-value'))).change();
      custom_input.val($(this).attr('data-name'))
      custom_input.attr('readonly', true);
      delete_selection.addClass('option_selected');
      suggestion_list.css('visibility', 'hidden');
    });

    // Reset the custom form
    delete_selection.on('click', function() {
      select.val('').change();
      custom_input.attr('readonly', false);
      delete_selection.removeClass('option_selected');
      suggestion_list.css('visibility', 'visible');
      custom_input.focus();
    });
  });
});
.delete_selection {
    display: none;
}

.option_selected {
    display: initial;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>Type in the input to get suggestions. Click on a list item to select it.</p>
<select class="custom_select" id="id_file" name="file">
    <option value="" selected="selected">---------</option>
    <option value="1">image.svg</option>
    <option value="2">video.mp4</option>
    <option value="3">game.iso</option>
</select>
<div class="custom_select_form">
  <input type="text" spellcheck="false">
  <i class="delete_selection" aria-hidden="true">X</i>
    <ul>
    </ul>
</div>

1 个答案:

答案 0 :(得分:1)

尝试更换:

custom_input.on("change keyup paste", function() { ... });

只是:

custom_input.on("keyup paste", function() { ... });

说明:绑定change也会在您离开过滤器输入时触发事件(当焦点不再在其上时)。由于相应的处理程序使用/修改了建议列表,因此您的点击事件可能会受到影响。

另请注意,input propertychange是建议检查实际用户输入的两个事件,而不是key*事件。当用户粘贴某些东西时它也会触发。所以你应该这样做:

custom_input.on('input propertychange', function() { ... });