Как динамически создать переключатель в Javascript, который работает во всех браузерах?
Динамическое создание переключателя с использованием, например,
var radioInput = document.createElement('input');
radioInput.setAttribute('type', 'radio');
radioInput.setAttribute('name', name);
работает в Firefox, но не в IE. Почему бы и нет?
11 ответов
Сделав шаг от того, что предлагает Патрик, используя временный узел, мы можем избавиться от 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;
}
На основе этого поста и его комментариев: http://cf-bill.blogspot.com/2006/03/another-ie-gotcha-dynamiclly-created.html
следующие работы. Очевидно, проблема в том, что вы не можете динамически установить свойство name в IE. Я также обнаружил, что вы также не можете динамически установить проверенный атрибут.
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;
}
Вот пример более общего решения, которое обнаруживает IE заранее и обрабатывает другие атрибуты, с которыми IE также имеет проблемы, извлеченные из DOMBuilder:
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 также обрабатывает регистрацию прослушивателя событий и спецификацию дочерних узлов.
Лично я бы не создавал узлы сам. Как вы заметили, проблем с браузером слишком много. Обычно я использую Builder.node из http://script.aculo.us/. Используя этот код, ваш код станет примерно таким:
Builder.node('input', {type: 'radio', name: name})
for(i=0;i<=10;i++){
var selecttag1=document.createElement("input");
selecttag1.setAttribute("type", "radio");
selecttag1.setAttribute("name", "irrSelectNo"+i);
selecttag1.setAttribute("value", "N");
selecttag1.setAttribute("id","irrSelectNo"+i);
var lbl1 = document.createElement("label");
lbl1.innerHTML = "YES";
cell3Div.appendChild(lbl);
cell3Div.appendChild(selecttag1);
}
Мое решение:
html
head
script(type='text/javascript')
function createRadioButton()
{
var newRadioButton
= document.createElement(input(type='radio',name='radio',value='1st'));
document.body.insertBefore(newRadioButton);
}
body
input(type='button',onclick='createRadioButton();',value='Create Radio Button')
Динамически создаваемый переключатель в JavaScript:
<%@ Page Language=”C#” AutoEventWireup=”true” CodeBehind=”RadioDemo.aspx.cs” Inherits=”JavascriptTutorial.RadioDemo” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head runat=”server”>
<title></title>
<script type=”text/javascript”>
/* Getting Id of Div in which radio button will be add*/
var containerDivClientId = “<%= containerDiv.ClientID %>”;
/*variable count uses for define unique Ids of radio buttons and group name*/
var count = 100;
/*This function call by button OnClientClick event and uses for create radio buttons*/
function dynamicRadioButton()
{
/* create a radio button */
var radioYes = document.createElement(“input”);
radioYes.setAttribute(“type”, “radio”);
/*Set id of new created radio button*/
radioYes.setAttribute(“id”, “radioYes” + count);
/*set unique group name for pair of Yes / No */
radioYes.setAttribute(“name”, “Boolean” + count);
/*creating label for Text to Radio button*/
var lblYes = document.createElement(“lable”);
/*create text node for label Text which display for Radio button*/
var textYes = document.createTextNode(“Yes”);
/*add text to new create lable*/
lblYes.appendChild(textYes);
/*add radio button to Div*/
containerDiv.appendChild(radioYes);
/*add label text for radio button to Div*/
containerDiv.appendChild(lblYes);
/*add space between two radio buttons*/
var space = document.createElement(“span”);
space.setAttribute(“innerHTML”, “  ”);
containerDiv.appendChild(space);
var radioNo = document.createElement(“input”);
radioNo.setAttribute(“type”, “radio”);
radioNo.setAttribute(“id”, “radioNo” + count);
radioNo.setAttribute(“name”, “Boolean” + count);
var lblNo = document.createElement(“label”);
lblNo.innerHTML = “No”;
containerDiv.appendChild(radioNo);
containerDiv.appendChild(lblNo);
/*add new line for new pair of radio buttons*/
var spaceBr= document.createElement(“br”);
containerDiv.appendChild(spaceBr);
count++;
return false;
}
</script>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>
<asp:Button ID=”btnCreate” runat=”server” Text=”Click Me” OnClientClick=”return dynamicRadioButton();” />
<div id=”containerDiv” runat=”server”></div>
</div>
</form>
</body>
</html>
( источник)
Быстрый ответ на старый пост:
Пост выше Roundcrisis - это хорошо, ЕСЛИ И ТОЛЬКО ЕСЛИ вы знаете количество радио / флажков, которые будут использоваться заранее. В некоторых ситуациях, рассматриваемых в этой теме "динамически создаваемых переключателей", количество элементов управления, которые потребуются пользователю, неизвестно. Кроме того, я не рекомендую "пропускать" перехват ошибок "try-catch", поскольку это облегчает отлов будущих реализаций браузера, которые могут не соответствовать действующим стандартам. Из этих решений я рекомендую использовать решение, предложенное Патриком Уилксом в своем ответе на свой вопрос.
Это повторяется здесь, чтобы избежать путаницы:
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;}
Почему бы не создать входные данные, установите стиль на dispaly: none и затем измените отображение, когда это необходимо, таким образом, вы также, вероятно, сможете лучше обрабатывать пользователей без js.
Ответ Патрика работает, или вы также можете установить атрибут "defaultChecked" (это будет работать в IE для элементов радио или флажков и не будет вызывать ошибки в других браузерах.
PS Полный список атрибутов, которые вы не можете установить в IE, приведен здесь:
http://webbugtrack.blogspot.com/2007/08/bug-242-setattribute-doesnt-always-work.html
Мое предложение не использовать document.Create(). Лучшее решение - создать реальный HTML будущего управления, а затем назначить его, как innerHTML, некоторому заполнителю - он позволяет браузеру отображать его сам, что намного быстрее, чем любые манипуляции с JS DOM.
Приветствия.