如何在Javascript中动态创建在所有浏览器中都可以使用的单选按钮?

时间:2020-03-06 14:34:36  来源:igfitidea点击:

使用例如动态创建单选按钮

var radioInput = document.createElement('input');
radioInput.setAttribute('type', 'radio');
radioInput.setAttribute('name', name);

在Firefox中有效,但在IE中无效。为什么不?

解决方案

根据这篇文章及其评论:
http://cf-bill.blogspot.com/2006/03/another-ie-gotcha-dynamiclly-created.html

以下作品。显然问题是我们无法在IE中动态设置name属性。我还发现我们也不能动态设置checked属性。

function createRadioElement( name, checked ) {
    var radioInput;
    try {
        var radioHtml = '<input type="radio" name="' + name + '"';
        if ( checked ) {
            radioHtml += ' checked="checked"';
        }
        radioHtml += '/>';
        radioInput = document.createElement(radioHtml);
    } catch( err ) {
        radioInput = document.createElement('input');
        radioInput.setAttribute('type', 'radio');
        radioInput.setAttribute('name', name);
        if ( checked ) {
            radioInput.setAttribute('checked', 'checked');
        }
    }

    return radioInput;
}

我的建议是不要使用document.Create()。更好的解决方案是构造将来的控件的实际HTML,然后将其像innerHTML一样分配给某个占位符,它允许浏览器呈现它自己,这比任何JS DOM操作都快得多。

干杯。

帕特里克(Patrick)的答案有效,或者我们也可以设置" defaultChecked"属性(这将在IE中用于单选或者复选框元素,并且不会在其他浏览器中引起错误。

PS这里列出了我们无法在IE中设置的属性的完整列表:

http://webbugtrack.blogspot.com/2007/08/bug-242-setattribute-doesnt-always-work.html

从Patrick的建议中走出一步,使用临时节点,我们可以摆脱try / catch的问题:

function createRadioElement(name, checked) {
    var radioHtml = '<input type="radio" name="' + name + '"';
    if ( checked ) {
        radioHtml += ' checked="checked"';
    }
    radioHtml += '/>';

    var radioFragment = document.createElement('div');
    radioFragment.innerHTML = radioHtml;

    return radioFragment.firstChild;
}

这是一个更通用的解决方案示例,它可以预先检测IE并处理从DOMBuilder中提取的IE也存在问题的其他属性:

var createElement = (function()
{
    // Detect IE using conditional compilation
    if (/*@cc_on @*//*@if (@_win32)!/*@end @*/false)
    {
        // Translations for attribute names which IE would otherwise choke on
        var attrTranslations =
        {
            "class": "className",
            "for": "htmlFor"
        };

        var setAttribute = function(element, attr, value)
        {
            if (attrTranslations.hasOwnProperty(attr))
            {
                element[attrTranslations[attr]] = value;
            }
            else if (attr == "style")
            {
                element.style.cssText = value;
            }
            else
            {
                element.setAttribute(attr, value);
            }
        };

        return function(tagName, attributes)
        {
            attributes = attributes || {};

            // See http://channel9.msdn.com/Wiki/InternetExplorerProgrammingBugs
            if (attributes.hasOwnProperty("name") ||
                attributes.hasOwnProperty("checked") ||
                attributes.hasOwnProperty("multiple"))
            {
                var tagParts = ["<" + tagName];
                if (attributes.hasOwnProperty("name"))
                {
                    tagParts[tagParts.length] =
                        ' name="' + attributes.name + '"';
                    delete attributes.name;
                }
                if (attributes.hasOwnProperty("checked") &&
                    "" + attributes.checked == "true")
                {
                    tagParts[tagParts.length] = " checked";
                    delete attributes.checked;
                }
                if (attributes.hasOwnProperty("multiple") &&
                    "" + attributes.multiple == "true")
                {
                    tagParts[tagParts.length] = " multiple";
                    delete attributes.multiple;
                }
                tagParts[tagParts.length] = ">";

                var element =
                    document.createElement(tagParts.join(""));
            }
            else
            {
                var element = document.createElement(tagName);
            }

            for (var attr in attributes)
            {
                if (attributes.hasOwnProperty(attr))
                {
                    setAttribute(element, attr, attributes[attr]);
                }
            }

            return element;
        };
    }
    // All other browsers
    else
    {
        return function(tagName, attributes)
        {
            attributes = attributes || {};
            var element = document.createElement(tagName);
            for (var attr in attributes)
            {
                if (attributes.hasOwnProperty(attr))
                {
                    element.setAttribute(attr, attributes[attr]);
                }
            }
            return element;
        };
    }
})();

// Usage
var rb = createElement("input", {type: "radio", checked: true});

完整的DOMBuilder版本还处理事件侦听器注册和子节点规范。

为什么不创建输入,请将样式设置为显示:无,然后在需要时更改显示
这样,我们还可以更好地处理用户,而不是js。

我个人不会自己创建节点。我们已经注意到,存在太多针对浏览器的问题。通常我使用script.aculo.us中的Builder.node。使用它,代码将变成这样:

Builder.node('input', {type: 'radio', name: name})

快速回复旧帖子:

Roundcrisis的上述帖子很好,如果并且仅如果我们知道,我们将事先使用单选框/复选框控件的数量。在某些情况下,通过"动态创建单选按钮"这一主题解决了用户所需的控件数量未知。此外,我不建议"跳过"" try-catch"错误陷阱,因为这样可以方便地捕获将来可能不符合当前标准的浏览器实现。在这些解决方案中,我建议使用Patrick Wilkes在回答自己的问题时提出的解决方案。

为了避免混淆,在此重复此步骤:

function createRadioElement( name, checked ) {
   var radioInput;
   try {
        var radioHtml = '<input type="radio" name="' + name + '"';
        if ( checked ) {
            radioHtml += ' checked="checked"';
        }
        radioHtml += '/>';
        radioInput = document.createElement(radioHtml);
    } catch( err ) {
        radioInput = document.createElement('input');
        radioInput.setAttribute('type', 'radio');
        radioInput.setAttribute('name', name);
        if ( checked ) {
            radioInput.setAttribute('checked', 'checked');
        }
    }
    return radioInput;}