Как polyfill RadioNodeList?

Фон

В соответствии с WHATWG someForm.elements должен возвращать HTMLFormElementsCollection.

A HTMLFormElementsCollection возвращает RadioNodeList, если несколько элементов имеют одно и то же имя.

RadioNodeList имеет специальную value семантику, где он возвращает значение первого проверенного списка радио в нодлисте.

Это позволит следующему ответу на работу, если он будет реализован

I наивно предпринял попытку polyfill, основанный на том, что хост-объекты хорошо себя ведут (согласно WebIDL), которые явно не,

Вопрос

Какова альтернативная эффективная реализация для этого polyfill, пока мы ожидаем, что браузеры станут либо RadioNodeList, либо совместимыми с WebIDL?

Пример ссылочного кода

<form name="myform">
    <input type="radio" name="foo" value="10" /> foo 
    <input type="radio" name="foo" value="30" /> bar 
</form>

var myform = document.forms.myform;

var radio = myform.elements.foo;
var price = radio.value;

Код рекомендации наивной попытки

(function () {
    var pd = Object.getOwnPropertyDescriptor(HTMLFormElement.prototype, "elements"),
        getElements = pd.get;

    pd.get = get;

    Object.defineProperty(HTMLFormElement.prototype, "elements", pd);

    function get() {
        var elements = getElements.call(this);

        if (elements.length) {
            Object.defineProperty(elements, "value", {
                get: getRadioNodeListValue,
                set: setRadioNodeListValue,
                configurable: true
            });
        }

        return elements;
    }

    function getRadioNodeListValue() {
        for (var i = 0, len = this.length; i < len; i++) {
            var el = this[i];
            if (el.checked) {
                return el.value;   
            }
        }
    }

    function setRadioNodeListValue(value) {
        for (var i = 0, len = this.length; i < len; i++) {
            var el = this[i];
            if (el.checked) {
                el.value = value;
                return;   
            }
        }    
    }
}());

Ответ 1

Если вы можете принять болт value getter на NodeList, то следующее должно работать

RadioNodeList polyfill

Кредит @@Esailija

вы также можете просто добавить .value в прототип NodeList

Ответ 2

Почему? Вы знаете, что требования ES5 и WebIDL не будут работать в обычных браузерах в Интернете сегодня. Для вашего кода требуются новые функции, как в ES5) Object.getOwnPropertyDescriptor, get/set), так и вы указали, что объекты интерфейса WebIDL хорошо себя ведут.

HTML5 polyfill имеет целью обобщение и вообще не выполняется при реализации. Это вредная тенденция.

Не изменяйте другие объекты. Особенно объекты-хосты.
Если есть какая-либо разница в определении HTML5 (и есть), возникнут проблемы, когда второе тестирование функции script пытается определить, есть ли свойство value в группе радиостанций, а затем принимает стандартную поддержку. Это далеко от двухэтапного алгоритма в HTML5.

Ваш код заполняется только в том случае, если elements.length > 0 и влияет на флажки также (помните, что радио не являются единственным элементом с свойством checked). Ваш сеттер изменяет значение первой проверенной радиостанции. Не следует ли устанавливать значение для проверки первого непроверенного радио этого имени, имеющего это значение?

Вместо этого напишите функции, которые являются только такими общими, какими они вам нужны.

function getRadioValue(form, radioName) {
  // Delete comment, write code.
}

function setRadioValue(form, radioName, value) {
  // Delete comment, write code.
}