理解搜索表单的jQuery实现

时间:2018-05-04 20:42:14

标签: javascript jquery html

我正在开发一个包含搜索表单的项目,如下所示:

enter image description here

这是HTML(实际上是一个Django模板):

<form action="{% url action %}" method="get" class="left search col s6 hide-on-small-and-down" novalidate>
  <div class="input-field">
    <input id="search" placeholder="{{ placeholder }}"
        autocomplete="off" type="search" name="q"
        value="{{ search_form.q.value.strip|default:'' }}"
        data-query="{{ search_form.q.value.strip|default:'' }}">
    <label for="search" class="active"><i class="material-icons search-icon">search</i></label>
    <i data-behavior="search-clear"
        class="material-icons search-icon"
        {% if not search_form.q.value %}style="display: none;"{% endif %}>close</i>
  </div>
</form>

以下是伴随的jQuery代码:

  $(document).on('click', '[data-behavior="search-clear"]', function(e) {
    $('#search').val('').parents('form').submit();
  });

  $(function() {
    setSearchClearVisibility($('#search'));
  });

  $(document).on('keydown', '#search', function(e) {
    var $el = $(this);

    setTimeout(function() {
      setSearchClearVisibility($el);
    }, 10);
  });

  function setSearchClearVisibility(el) {
    if (el.val() === '') {
      $('[data-behavior="search-clear"]').hide();
    } else {
      $('[data-behavior="search-clear"]').show();
    }
  }

  $(document).on('keydown', '#search', function(e) {
    var $el = $(this);

    setTimeout(function() {
      if (e.keyCode !== 27) return;

      $('#search').val('').blur();
      setSearchClearVisibility($el);

      if ($el.data('query') !== '') {
        $('#search').parents('form').submit();
      }
    }, 10);
  });

我对jQuery代码有几个问题:

首先,似乎setSearchClearVisibility()函数可以重构如下:

  function setSearchClearVisibility(el) {
    if (el.val() === '') {
      $('[data-behavior="search-clear"]').toggle();
    }
  }

这确实等同吗?

其次,它似乎也是

$(document).on('keydown', '#search', function(e) {

可以替换为

$('#search').keydown(function(e) {
是不是?

第三,我不确定为什么在几个地方有一个10毫秒setTimeout。为什么不立即执行此操作?

第四,我对这条线感到困惑

if (e.keyCode !== 27) return;

密钥代码27对应Escape密钥;这不意味着如果按下的键不是Escape键,函数return和它下面的代码(关闭图标可见性和表单提交的切换)将不会被执行?如果我注释掉这一行,我也没有发现任何行为上的差异。

1 个答案:

答案 0 :(得分:4)

1。不,他们不等同。

如果条件为真,您建议的代码将切换(从现有状态更改为另一个),如果不满足条件,则不会执行任何更改。
你现在拥有的代码是:隐藏条件,如果没有则显示。

将条件传递给切换将显示是否为真,如果不是则隐藏。所以这是等价的:

function setSearchClearVisibility(el) {
  $('[data-behavior="search-clear"]').toggle(el.val() !== '');
}

2。 $(parent).on(event, child, callback)$(child).on(event, callback)

不同

非常重要 第一个仅绑定一次,在所有现有或 未来 子项的父级上与child选择器相遇。事件发生时(child选择器)的评估完成 第二个是每个孩子绑定一次。因此,如果你有1k个孩子,你有1k个绑定,而不是一个。选择器的评估是在绑定时完成的,而不是事件的。因此,如果您在绑定后添加更多子级,则callback上不会绑定event

3。 setTimeout(callback, delay)最迟将callback的执行排在队列之间:

  • 当前执行队列的结尾
  • 当前时间+延迟

有关详细信息,请参阅this answersetTimeout(callback)是在执行队列末尾对callback执行进行排队的典型方法。它确保当前函数/范围/线程在callback运行之前完成执行。

4. if (e.keyCode !== 27) return;表示:

如果按下的键不是escape,则退出功能。否则,继续并运行我之后的事情(直到功能结束)。请注意,此功能仅在keydown上的#search事件中执行。因此,要测试它,您必须有#search聚焦/活动/选择并按一个键。如果按下的键是escape,则条件之后的代码将被执行。如果它是任何其他键,则不会。