被选中的选项被破坏还是......?

Max*_*Art 23 javascript

注意:这个问题与Knockout.js无关,但它取决于元素的selectedOptions属性<select>.这是参考:

http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#dom-select-selectedoptions

我认为这是Javascript开发人员的一个很好的功能.支持非常有限,但无论如何都在增长.Chrome,Opera和Safari应该已经支持它了.

问题是我无法弄清楚它是如何工作的.行为应该非常简单,产生所选选项的实时集合,但结果并非如此.您可以想象selectedOptions每次用户选择一个选项时都会进行更改,对吗?错误.我准备了一个测试用例:

http://jsfiddle.net/f39cC/5/

在这个例子中,Opera 11.64 总是返回所选择的第一个值,无论你做什么,而Chrome 21 dev和19 stable有一个奇怪的行为.执行以下步骤:

  1. 选择"一个".在输出和控制台中,您可以获得"One",如预期的那样.
  2. 使用Ctrl也选择"Two".在控制台中你得到"一,二",在输出中它仍然是"一".
  3. 也选择'三'.在控制台中它是"一,二,三",在输出中它是"一,二".
  4. 现在只选择"两个".在控制台中,你得到"Two",输出"Two ,,"(注意两个逗号).

但是,如果您注释掉该console.log行,则始终可以获得正确的输出.你可以在控制台和产量预期的行为,如果你换了两个指令,或者如果你的值存储在一个分隔的字符串,如本:

http://jsfiddle.net/f39cC/2/

那么,我错过了什么selectedOptions吗?依赖这个属性是否为时尚早,可能有一个错误的实现?是否console.log在Chrome中创建了该问题?有什么我不知道HTMLCollection的吗?

我没有安装Safari,有人可以检查一下它的行为吗?

UPDATE 18/2/2013:当事情发生了变化,我不知道,但两者的Chrome 24.0.1312.57和Opera 12.14,似乎现在的工作很好.Firefox 18.0.2和Internet Explorer 10仍然必须实现该属性.

更新2013年 9月17日: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;
            };
        }
    })()
});
Run Code Online (Sandbox Code Playgroud)

对于IE8,它只返回a Array而不是a NodeList.

更新28/5/2014:看起来Firefox selectedOptions从r25 开始实施.

Max*_*Art 8

看起来这个问题比一个简单的bug要深一点.WebKit和Presto都无法selectedOptions正确支持的事实让我们暗示它取决于该属性应该是一个事实HTMLCollection.

现在,HTMLCollections有它们的实时行为,因为当DOM发生某些事情(类的更改,节点的删除等)时,渲染引擎会使它们失效.但是selected选项的属性不会触发集合的失效,从而使其完全不可靠.

我想这里的问题是以一种新的方式使实时集合失效,并且它可能不是很简单,因为它可能影响解释和处理DOM的整个方式.

目前,Chrome 21.0.1180.4已删除该属性.