我正在开发一个项目,其中包含一个如下所示的搜索表单:
这是 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 键,该函数将返回
并且其下面的代码(关闭图标可见性的切换和表单的提交)将不会被执行?如果我注释掉这一行,我也没有注意到行为有任何差异。
最佳答案
1. 不,它们并不等同。
如果条件为真,您建议的代码将切换(从现有状态更改为其他状态),如果不满足条件,则不会执行任何更改。
您现在的代码是:隐藏 if 条件,显示 if not。
传递条件进行切换,如果为真则显示,否则隐藏。所以这是等价的:
function setSearchClearVisibility(el) {
$('[data-behavior="search-clear"]').toggle(el.val() !== '');
}
2. $(parent).on(event, child,callback)
与 $(child).on(event, callback) 不同)
这非常重要。
第一个仅在满足 child
选择器的所有现有或 future 子级的父级上绑定(bind)一次。 (child
选择器的评估)在事件发生时完成。
第二个每个 child 绑定(bind)一次。因此,如果您有 1k 个子级,那么您就有 1k 个绑定(bind),而不是一个。选择器的评估是在绑定(bind)时完成的,而不是在事件时完成的。因此,如果您在绑定(bind)后添加更多子级,它们将不会在 event
上绑定(bind) callback
。
3. setTimeout(callback, delay)
是在最迟以下时间之间对 callback
的执行进行排队:
- 当前执行队列的末尾
- 当前时间 + 延迟
参见this answer了解详情。 setTimeout(callback)
是将callback
的执行排在执行队列末尾的典型方法。它确保当前函数/作用域/线程在回调
运行之前完成执行。
4. if (e.keyCode !== 27) return;
表示:
如果按下的键不是escape
,则退出函数。否则,继续运行我后面的内容(直到函数结束)。请注意,此函数仅在 #search
上的 keydown
事件上执行。因此,要测试它,您必须聚焦/激活/选择#search
并按下一个键。如果按下的键是escape
,则条件后面的代码将被执行。如果是任何其他键,则不会。
关于javascript - 了解搜索表单的 jQuery 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50182789/