2012-05-23 2 views
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.6 всегда возвращает первое значение не выбран, независимо от того, что вы делаете после того, в то время как Chrome 21 DEV и 19 стабильны имеют странное поведение , Выполните следующие шаги:

  1. Выберите «Один». Как на выходе, так и на консоли вы получаете «Один», как и ожидалось.
  2. Выберите «Два», используя Ctrl. В консоли вы получаете «Один, Два», в выводе он по-прежнему «Один».
  3. Выберите «Три». В консоли это «Один, Два, Три», на выходе это «Один, Два».
  4. Теперь выберите только «Два». В консоли вы получаете «Два», на выходе «Два» (обратите внимание на две запятые).

Однако, если вы закомментировать console.log линии, вы всегда получите правильный выход. Вы можете получить ожидаемое поведение как в консоли и выходе, если нужно поменять местами две команды, или если вы храните значения в строке разделенной, как и в этом:

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

Так, я что-то отсутствует о selectedOptions ? Слишком рано полагаться на это свойство, возможно, есть ошибка? Является console.log, создавая проблему в Chrome? Есть ли что-то, что я не знаю о HTMLCollection?

У меня нет установленного Safari, может кто-нибудь проверить его поведение?

ОБНОВЛЕНИЕ 18/2/2013: Я не знаю, когда все изменилось, но как Chrome 24.0.1312.57, так и Opera 12.14, похоже, сейчас работают нормально. Firefox 18.0.2 и Internet Explorer 10 все еще должны реализовать свойство.

ОБНОВЛЕНИЕ 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 и не NodeList, хотя.

UPDATE 28/5/201: Похоже, что Firefox начал внедрять selectedOptions с r25.

+1

Из моих исследований да, он сломан, и [даже не реализован в firefox] (https://bugzilla.mozilla.org/show_bug.cgi?id=596681). Я мог бы написать это как ответ, но вы, наверное, все это знаете ... – gdoron

+1

Да, я прочитал эту страницу с ошибкой даже до публикации этого вопроса, но я надеялся, что, поскольку 'selectedOption' * is * определен на'