Примечание: этот вопрос не имеет ничего общего с Knockout.js, но он относится к атрибуту selectedOptions
элементов <select>
. Это ссылка:
Я думаю, что это хорошая функция для разработчиков Javascript. Поддержка довольно ограничена, но она все равно растет. Chrome, Opera и Safari должны уже поддерживать его.
Проблема в том, что я не могу понять, как это работает. Поведение должно быть довольно простым, давая живую коллекцию выбранных опций, но это оказывается не так. Вы можете предположить, что selectedOptions
изменяется каждый раз, когда пользователь выбирает параметр, верно? Неправильно. Я подготовил тестовый пример:
В этом примере Opera 11.64 всегда возвращает первое выбранное значение, независимо от того, что вы делаете после этого, в то время как у Chrome 21 dev и 19 stable есть странное поведение. Выполните следующие действия:
- Выберите "Один" . Как на выходе, так и на консоли вы получаете "Один" , как и ожидалось.
- Выберите "Два", используя Ctrl. В консоли вы получаете "Один, Два", выводящий его "Один" .
- Выберите "Три". В консоли это "Один, Два, Три", выводят его "Один, Два".
- Теперь выберите "Два". В консоли вы получаете "Два", на выходе "Два" (обратите внимание на две запятые).
Однако, если вы закомментируете строку 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 все еще должны реализовать свойство.
ОБНОВЛЕНИЕ 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
.
ОБНОВЛЕНИЕ 28/5/2014. Похоже, Firefox начал внедрять selectedOptions
с r25.