23

注意:这个问题与 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. 选择“一个”。正如预期的那样,在输出和控制台中,您都会得到“一”。
  2. 使用 Ctrl 也选择“两个”。在控制台中你得到“一,二”,在输出中它仍然是“一”。
  3. 也选择“三”。在控制台中是“一,二,三”,在输出中是“一,二”。
  4. 现在只选择“两个”。在控制台中,您在输出中获得“Two”,“Two,”(注意两个逗号)。

但是,如果您注释掉该console.log行,您总是会得到正确的输出。如果交换两条指令,或者将值存储在单独的字符串中,则可以在控制台和输出中获得预期的行为,如下所示:

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

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

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

2013 年 2 月 18 日更新:我不知道什么时候发生了变化,但 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;
            };
        }
    })()
});

但是,对于 IE8,它只返回 aArray而不是 a NodeList

28/5/2014 更新:看起来 FirefoxselectedOptions从 r25 开始实施。

4

1 回答 1

8

似乎这个问题比一个简单的错误要深一些。WebKit 和 Presto 都未能selectedOptions正确支持的事实给我们暗示,这取决于属性应该是HTMLCollection.

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

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

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

于 2012-06-23T11:38:22.207 回答