如何填充RadioNodeList?

发布于 2024-12-28 02:20:55 字数 2634 浏览 3 评论 0原文

背景

根据 WHATWG< /a> someForm.elements 应该返回一个 HTMLFormElementsCollection

HTMLFormElementsCollection 返回一个 RadioNodeList

RadioNodeList 有特殊的 value 语义,它返回节点列表中第一个检查的单选列表的值。

这将允许如果实施的话以下答案可以工作

天真地尝试了一个polyfill这是基于行为良好的主机对象(根据 WebIDL),但它们显然不是。

问题

在我们等待浏览器兼容 RadioNodeList 或 WebIDL 的同时,这个 polyfill 的替代有效实现是什么?

示例 参考代码

<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;   
            }
        }    
    }
}());

Background

As per the WHATWG someForm.elements should return a HTMLFormElementsCollection.

A HTMLFormElementsCollection returns a RadioNodeList if multiple elements share the same name.

The RadioNodeList has special value semantics where it returns the value of the first checked radio list in the nodelist.

This would allow the following answer to work if it were implemented

I naively attempted a polyfill that is based on host objects being well behaved (as per WebIDL), which they are clearly not.

Question

What is an alternative efficient implementation for this polyfill whilst we wait for browsers to become either RadioNodeList or WebIDL compliant?

Example Reference code

<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;

Naive attempt reference code

(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;   
            }
        }    
    }
}());

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

濫情▎り 2025-01-04 02:20:55

如果您可以接受将 value getter 固定到 NodeList 上,那么以下内容应该可以工作

RadioNodeList polyfill

感谢@@Esailija

您也可以将 .value 添加到 NodeList 原型

If you can accept bolting the value getter onto NodeList then the following should work

RadioNodeList polyfill

Credit to @@Esailija

you could also just add .value to NodeList prototype

娇纵 2025-01-04 02:20:55

为什么?您知道,在当今网络上的常用浏览器中,要求 ES5 和 WebIDL 会失败。您的代码需要新功能,无论是 ES5 )Object.getOwnPropertyDescriptorget/set),并且正如您提到的 WebIDL 接口对象很好 -表现良好。

HTML5 polyfill 旨在泛化,但在实现上通常会失败。这是一种有害的趋势。

不要修改其他对象。特别是宿主对象。
如果与 HTML5 定义有任何差异(确实存在),那么当第二功能测试脚本尝试检测某个对象上是否有 value 属性时,就会出现问题无线电组,然后假设标准支持。这与 HTML5 中的两步算法相去甚远。

仅当 elements.length > 时,您的代码才会进行填充。 0 并且也会影响复选框(请记住,单选按钮并不是唯一具有 checked 属性的元素)。您的设置器更改第一个检查的无线电的值。设置该值不应该检查具有该值的该名称的第一个未经检查的无线电吗?

相反,只需编写您需要的通用函数即可。

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

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

Why? You know that requiring ES5 and WebIDL will fail in common-use browsers on the web today. Your code requires new features, both in ES5 )Object.getOwnPropertyDescriptor, get/set), and as you mentioned WebIDL interface objects being well-behaved.

The HTML5 polyfill aims at generalization and generally fails at implementation. It is a harmful trend.

Don't modify other objects. Especially host objects.
If there is any variance from the HTML5 definition (and there is) there will be problems when a second feature-testing script tries to detect if there is a value property on a group of radios, and then assumes standard support.It's way off from the 2-step algorithm in HTML5.

Your code polyfills only if elements.length > 0 and affects checkboxes, too (keep in mind that radios aren't the only element with a checked property). Your setter changes the value of the first checked radio. Shouldn't setting the value check the first unchecked radio of that name, having that value?

Instead, write functions that are only as general as you need them to be.

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

function setRadioValue(form, radioName, value) {
  // Delete comment, write code.
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文