注意:这个问题与Knockout.js无关,而是与selectedOptions
元素的<select>
属性相关。这是参考:
我认为这对Javascript开发人员来说是个不错的功能。支持非常有限,但无论如何都在增长。 Chrome,Opera和Safari应该已经支持它了。
问题在于我无法弄清楚它是如何工作的。行为应该非常简单,产生所选选项的实时集合,但结果并非如此。您可以想象每次用户选择一个选项时selectedOptions
都会发生变化,对吗?错误。我准备了一个测试用例:
在此示例中,Opera 11.64 始终返回所选的第一个值,无论您执行什么操作,而Chrome 21 dev和19 stable都有奇怪的行为。执行以下步骤:
然而,如果您注释掉console.log
行,则始终会获得正确的输出。如果交换两条指令,或者将值存储在单独的字符串中,您可以在控制台和输出中获得预期的行为,如下所示:
那么,我错过了selectedOptions
的一些内容吗?依赖这个属性是否为时尚早,可能有一个错误的实现? console.log
是否在Chrome中造成了问题?关于HTMLCollection
s,有什么我不知道的事情吗?
我没有安装Safari,有人可以检查一下它的行为吗?
更新日期18/2/2013 :我不知道什么时候发生了变化,但Chrome 24.0.1312.57和Opera 12.14现在似乎都运行良好。 Firefox 18.0.2和Internet Explorer 10仍然需要实现该属性。
更新2013/3/13 :Firefox 24和IE 11预览版仍需支持该属性。这是Firefox和IE8-11的简单解决方法:
Object.defineProperty(HTMLSelectElement.prototype, "selectedOptions", {
get: (function() {
try {
document.querySelector(":checked");
return function() {
return this.querySelectorAll(":checked");
};
} catch (e) {
return function() {
if (!this.multiple) {
return this.selectedIndex >= 0
? [this.options[this.selectedIndex]] : [];
}
for (var i = 0, a = []; i < this.options.length; i++)
if (this.options[i].selected) a.push(this.options[i]);
return a;
};
}
})()
});
对于IE8,它只返回Array
而不是NodeList
。
更新28/5/2014 :从r25开始,Firefox似乎开始实施selectedOptions
。
答案 0 :(得分:8)
似乎问题比一个简单的bug要深一点。 WebKit和Presto都无法正确支持selectedOptions
的事实让我们暗示它依赖于该属性应该是HTMLCollection
的事实。
现在,HTMLCollection
具有它们的实时行为,因为当DOM发生某些事情(类的更改,节点的删除等)时,渲染引擎会使它们失效。但是选项的selected
属性不会触发集合的失效,从而使其完全不可靠。
我想这里的问题是以新的方式使实时集合失效,并且它可能不是很简单,因为它可能会影响解释和处理DOM的整个方式。
目前,Chrome 21.0.1180.4已删除该属性。