我正在尝试使用 bootstraps typeahead 作为用户的灵活选择。因此,如果该项目是已知的,他们会选择它,如果不是,则会打开一个对话框,允许他们输入新项目。
我通过观察输入上的更改事件来做到这一点,如果输入 val 不在源数组中(对于提前输入),则会向用户显示“添加项目”对话框。问题是如果用户单击其中一个选项,则在 typeahead 有机会设置 val 之前发送更改事件。这是因为点击会导致文本模糊。
我想检查事件元素来解决这个问题,所以在更改事件中查看 document.activeElement 并查看它是否是预先输入选项之一,这没有用并返回了整个 body 元素。
这是代码的精简版:
HTML
<div id="contactModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Unknown Contact</h3>
</div>
<div class="modal-body">
<p>The contact you have entered is unknown. Press cancel to enter a different contact or fill out the details below to create a new contact</p>
<label>Name</label>
<input id="modal_contact" type="text" placeholder="dealership contact" value=""/>
<label>Email</label>
<input id="modal_contact_email" type="text" placeholder="dealership contact" value=""/>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<button id="save" class="btn btn-primary">Save changes</button>
</div>
</div>
Javascript
var contacts = ['pete','geoff'];
$('.typeahead').typeahead({source:contacts, updater : function(item){
console.log('updater fired'); //fires after first change event
return item;
}});
$('input').change(function(ev){
console.log($(ev.target).val());
if ($.inArray($(ev.target).val(), contacts) < 0)
$('#contactModal').modal();
})
还有一个 JSFiddle 版本 http://jsfiddle.net/k39vM/
有谁知道我如何测试用户是否点击了预输入以查明这是否导致了更改事件?
最佳答案
我之前的建议实际上并没有奏效,因为正如您提到的,有一些意外的 blur
事件触发了 change
before 事件点击
菜单。我曾假设它与 Typeahead.prototype.select
方法中的 this.hide()
调用有关。
然而,经过反复试验,我确实认为我可能找到了 workaround .这实际上不是导致问题的 select
方法中的 this.hide()
调用。知道用户可以通过两种方式触发选择有助于理解希望工作的解决方法(我只在 Chrome 中测试过):使用键盘,例如按回车键或单击项目。结果,我知道点击是两者的问题之子,我注意到当用户将鼠标悬停在下拉菜单上时,mousedover
事件会保持。
因此,可以在 change
事件中手动忽略奇怪的行为。为了简化确定导致 next change
事件的过程,我使用了一个名为“selected
”的不同(自定义)事件来表示用户更改了值而不是标准的 change
。不幸的是,当 mousedover
属性为 true
时,您仍然必须手动忽略 change
事件:
简化的 HTML(我使用了 p
标签,因为我发现 Chrome 在调试 JSFiddle 的 JavaScript 时遇到了麻烦,并且与控制台结合导致了糟糕的时间):
<input class="typeahead " type="text" placeholder="contact" value="Peter skillet"></input>
<input type="text"></input>
<p id="text" />
JavaScript(感兴趣的可以用console.log
替换文本):
var contacts = ['pete', 'geoffrey'];
var $text = $("#text");
var typeahead = $('.typeahead').typeahead({source: contacts}).data('typeahead');
typeahead.select = function () {
var val = this.$menu.find('.active').attr('data-value');
this.$element.val(this.updater(val))
.trigger('selected'); // <- unique event
return this.hide()
};
$('input.typeahead').on('change', function (e) {
var $target = $(e.target);
if (typeahead.mousedover) {
$text.html($text.html() + "mousedover [ignored selection]<br />");
}
else if ($.inArray($target.val(), contacts) < 0) {
$text.html($text.html() + "show add<br/>");
}
}).on('selected', function () {
$text.html($text.html() + "selected<br />");
});
作为引用,这是默认的 select
方法:
select: function () {
var val = this.$menu.find('.active').attr('data-value')
this.$element
.val(this.updater(val))
.change()
return this.hide()
}
关于javascript - 如何在输入更改事件之前获取 Bootstrap typeahead 点击结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15777398/