Javascript 敲除hasFocus绑定,数字输入在Firefox上不起作用
我有一个保存货币值的输入字段。当输入字段没有焦点时,我试图显示格式化的货币金额。输入字段类型设置为数字。而这在铬合金上效果很好;在firefox上,输入文本框在获取后立即失去焦点。下面是简化的JSFIDLE 除了数字字段外,这与示例2类似。如果我将输入类型从number改为text,问题就解决了(但也失去了所有优点)。 如有任何建议或解决办法,将不胜感激 HTML:Javascript 敲除hasFocus绑定,数字输入在Firefox上不起作用,javascript,firefox,knockout.js,Javascript,Firefox,Knockout.js,我有一个保存货币值的输入字段。当输入字段没有焦点时,我试图显示格式化的货币金额。输入字段类型设置为数字。而这在铬合金上效果很好;在firefox上,输入文本框在获取后立即失去焦点。下面是简化的JSFIDLE 除了数字字段外,这与示例2类似。如果我将输入类型从number改为text,问题就解决了(但也失去了所有优点)。 如有任何建议或解决办法,将不胜感激 HTML: hasFocus绑定使用Document.activeElement确定哪个元素处于焦点: 资料来源: 在您的小提琴中单步执行此
hasFocus
绑定使用Document.activeElement
确定哪个元素处于焦点:
资料来源:
在您的小提琴中单步执行此绑定时,我注意到它将body
元素返回为文档的activeElement
,从而使isFocused
变为false
在关于activeElement
的页面上,我读到:
注意:在Mac上,非文本输入元素的元素往往无法获得分配给它们的焦点
对我来说,这表明在number
输入中根本不支持这种绑定
我建议:
- 坚持文本输入,添加自定义的上下按钮和按键侦听器
- 创建基于事件侦听器的自定义绑定,而不是基于
document.activeElement
activeElement
方法。他们在评论中指出:
// Where possible, ignore which event was raised and determine focus state using activeElement,
// as this avoids phantom focus/blur events raised when changing tabs in modern browsers.
// However, not all KO-targeted browsers (Firefox 2) support activeElement. For those browsers,
// prevent a loss of focus when changing tabs/windows by setting a flag that prevents hasfocus
// from calling 'blur()' on the element when it loses focus.
// Discussion at https://github.com/SteveSanderson/knockout/pull/352
因此,选择第一个选项可能是明智的…通过使用一个额外的可观察对象来控制可见性,并在可观察对象上添加一个控制焦点的节流阀,使其正常工作。 看起来hasFocus绑定检查是在元素可见之前进行的 JS:
然而,由于得到了类似的诊断,他通过延迟hasFocus检查找到了解决办法。谢谢你的详细解释。有趣的发现。真的让我想知道在淘汰赛中到底发生了什么。我试图找出为什么
activeElement
没有及时设置,但无法重现问题。在本例中,数字输入工作正常。。。
function PersonViewModel(amount) {
// Data
this.amount = ko.observable(amount);
this.editing = ko.observable(false);
// Behaviors
this.edit = function() { this.editing(true) }
}
ko.applyBindings(new PersonViewModel(51.22));
var ownerDoc = element.ownerDocument;
if ("activeElement" in ownerDoc) {
var active;
try {
active = ownerDoc.activeElement;
} catch (e) {
// IE9 throws if you access activeElement during page load (see issue #703)
active = ownerDoc.body;
}
isFocused = (active === element);
}
// Where possible, ignore which event was raised and determine focus state using activeElement,
// as this avoids phantom focus/blur events raised when changing tabs in modern browsers.
// However, not all KO-targeted browsers (Firefox 2) support activeElement. For those browsers,
// prevent a loss of focus when changing tabs/windows by setting a flag that prevents hasfocus
// from calling 'blur()' on the element when it loses focus.
// Discussion at https://github.com/SteveSanderson/knockout/pull/352
<p>
Name:
<b data-bind="visible: !editingWrapper(), text: '$'+amount(), click: edit"> </b>
<input type="number" min="0" max="100" step="1" data-bind="visible: editingWrapper, value: amount, hasFocus: editing" />
</p>
<p><em>Click the amount to edit it; click elsewhere to apply changes.</em></p>
function PersonViewModel(amount) {
// Data
var self = this;
this.amount = ko.observable(amount);
this.editing = ko.observable(false).extend({throttle:200});
this.editingWrapper = ko.observable(false);
// Behaviors
this.edit = function() { self.editingWrapper(true);self.editing(true); }
this.editing.subscribe(function(newVal){
self.editingWrapper(newVal);
})
}
ko.applyBindings(new PersonViewModel(51.22));