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 安定版は奇妙な動作をします。次の手順を実行します。

  1. 一つ選択してください'。予想どおり、出力とコンソールの両方で「1」が得られます。
  2. Ctrl を使用して 'Two' も選択します。コンソールでは「One,Two」と表示されますが、出力では「One」のままです。
  3. こちらも「3」を選択。コンソールでは「One,Two,Three」、出力では「One,Two」です。
  4. 'Two' のみを選択します。コンソールでは「Two」、出力では「Two,,」が表示されます (2 つのコンマに注意してください)。

ただし、行をコメントアウトすると、console.log常に正しい出力が得られます。次のように、2 つの命令を入れ替えるか、別の文字列に値を格納すると、コンソールと出力の両方で期待される動作を得ることができます。

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

それで、私は何かが欠けていselectedOptionsますか?おそらくバグのある実装があるこのプロパティに依存するのは時期尚早ですか? console.logChrome で問題を作成していますか? sについて私が知らないことはありHTMLCollectionますか?

Safari をインストールしていません。誰かがその動作を確認できますか?

UPDATE 18/2/2013 : いつ変更されたかはわかりませんが、Chrome 24.0.1312.57 と Opera 12.14 の両方が正常に動作するようです。Firefox 18.0.2 と Internet Explorer 10 は、引き続きプロパティを実装する必要があります。

UPDATE 17/9/2013 : 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、 aNodeListではなく an のみを返します。

UPDATE 28/5/2014 : Firefox はselectedOptionsr25 から実装を開始したようです。

4

1 に答える 1

8

問題は単純なバグよりも少し深いようです。WebKit と Presto の両方がselectedOptions正しくサポートできなかったという事実は、プロパティがHTMLCollection.

HTMLCollectionDOM に何かが発生した場合 (クラスの変更、ノードの削除など)、レンダリング エンジンによって無効化されるため、 s はライブ動作を持ちます。ただし、selectedオプションのプロパティはコレクションの無効化をトリガーしないため、完全に信頼できなくなります。

ここでの問題は、ライブ コレクションを無効にする新しい方法を作成することだと思います。これは、DOM が解釈および処理される方法全体に影響を与える可能性があるため、それほど単純ではない可能性があります。

現時点では、Chrome 21.0.1180.4 ではプロパティが削除されています。

于 2012-06-23T11:38:22.207 に答える