Изменение имени attr клонированного входного элемента в jQuery не работает в IE6/7
Этот SSCCE говорит все:
<!doctype html>
<html lang="en">
<head>
<title>Test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#add').click(function() {
var ul = $('#ul');
var liclone = ul.find('li:last').clone(true);
var input = liclone.find('input');
input.attr('name', input.attr('name').replace(/(foo\[)(\d+)(\])/, function(f, p1, p2, p3) {
return p1 + (parseInt(p2) + 1) + p3;
}));
liclone.appendTo(ul);
$('#showsource').text(ul.html());
});
});
</script>
</head>
<body>
<ul id="ul">
<li><input type="text" name="foo[0]"></li>
</ul>
<button id="add">Add</button>
<pre id="showsource"></pre>
</body>
</html>
Скопируйте'paste'n'run, нажмите кнопку Add
несколько раз. На каждом клике вы должны увидеть код HTML <ul>
для отображения в <pre id="showsource">
, а ожидаемый код должен быть примерно:
<li><input name="foo[0]" type="text"></li>
<li><input name="foo[1]" type="text"></li>
<li><input name="foo[2]" type="text"></li>
<li><input name="foo[3]" type="text"></li>
Это работает как в FF, Chrome, Safari, Opera, так и в IE8.
Однако IE6/7 не удается изменить атрибут name
и производит, например:
<li><input name="foo[0]" type="text">
<li><input name="foo[0]" type="text">
<li><input name="foo[0]" type="text">
<li><input name="foo[0]" type="text"></li>
I немного искал и нашел эту очень похожую проблему, он исправил его и опубликовал фрагмент кода, как он должен выглядеть. К сожалению, это именно то, что я уже сделал, поэтому я подозреваю, что он тестировал только в IE8, а не в IE6/7. Помимо этой конкретной темы, Google не показал много.
Любые идеи? Или мне действительно нужно вернуться к document.createElement
?
Примечание. Я знаю, что я могу использовать одно и то же имя для каждого элемента ввода и извлекать их как массив, но приведенное выше просто базовый пример. В действительности мне действительно нужно изменить атрибут имени, потому что он не содержит только индекс, но также другую информацию, такую как parentindex, порядок и т.д. Он использовался для добавления/переупорядочения/удаления (под) пунктов меню.
Изменить: это связано с эта ошибка, jQuery (я использую 1.3.2) таким образом, кажется, не создает входные данные таким образом? Следующее работает:
$('#add').click(function() {
var ul = $('#ul');
var liclone = ul.find('li:last').clone(true);
var oldinput = liclone.find('input');
var name = oldinput.attr('name').replace(/(foo\[)(\d+)(\])/, function(f, p1, p2, p3) {
return p1 + (parseInt(p2) + 1) + p3;
});
var newinput = $('<input name="' + name + '">');
oldinput.replaceWith(newinput);
liclone.appendTo(ul);
$('#showsource').text(ul.html());
});
Но я не могу себе представить, что я единственный, кто столкнулся с этой проблемой с jQuery. Даже простой $('<input>').attr('name', 'foo')
не работает в IE6/7. Разве jQuery не является библиотекой crossbrowser, которая должна охватывать эту конкретную проблему под капотами?
Ответы
Ответ 1
Вот функция, которая будет устанавливать имя элемента во всех браузерах, даже IE6 и IE7. Он адаптирован из кода http://matts411.com/post/setting_the_name_attribute_in_ie_dom.
function setElementName(elems, name) {
if ($.browser.msie === true){
$(elems).each(function() {
this.mergeAttributes(document.createElement("<input name='" + name + "'/>"), false);
});
} else {
$(elems).attr('name', name);
}
}
Я обнаружил, что использование replaceElement и outerHTML не было надежным в разных версиях IE. Но трюк mergeAttributes выше работает отлично!
Ответ 2
Я создал частичное решение этой проблемы, которое я описываю здесь:
http://www.danconnor.com/dynamic-name-input-attributes-with-ie-and-jquery-clones.html
В принципе:
$(some_cloned_element).each(function(i, elem){
var newName = "yay_i_love_my_new_name";
if ($.browser.msie === true){ // evil browser sniffing *cries*
$(elem).replaceWith(document.createElement(
this.outerHTML.replace(/name=\w+/ig, 'name='+newName+'_'+i)
));
} else {
$(elem).attr('name',newName+'_'+i);
}
$("body").append(some_cloned_element);
});
Определенно отстой, но определенно работает.
Ответ 3
Интересно, если вы работаете в эта ошибка в IE (даже с jQuery)?
По существу в IE вы не можете изменить атрибут имени элементов (регулярный или клонированный) (а затем повторно обращаться к ним через javascript по имени), хотя вы можете отправить их (например, элементы ввода) и успешно отправить их.
Ответ 4
не ответ, это анализ заданного вопроса:
<!doctype html>
<html lang="en">
<head>
<title>Test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#add').click(function() {
var ul = $('#ul');
var liclone1 = ul.find('li:last').clone(true);
var liclone2 = ul.find('li:last')[0].cloneNode(true);
var liclone3 = $( ul.find('li:last')[0].cloneNode(true) );
var liclone4 = $( '<li><input type="text" name="foo[88]"></li>' );
var linew = document.createElement("li");
linew.innerHTML = '<input type="text" name="foo[99]">';
$('#showsource').text("");
$('#showsource').text($('#showsource').text() + $(liclone1)[0].outerHTML);
$('#showsource').text($('#showsource').text() + $(liclone2)[0].outerHTML);
$('#showsource').text($('#showsource').text() + $(liclone3)[0].outerHTML);
$('#showsource').text($('#showsource').text() + $(liclone4)[0].outerHTML);
$('#showsource').text($('#showsource').text() + $(linew)[0].outerHTML);
$('#showsource').text($('#showsource').text() + $(ul)[0].outerHTML);
$('#showsource').text($('#showsource').text() + $(ul)[0].innerHTML);
});
});
</script>
</head>
<body>
<ul id="ul">
<li><input type="text" name="foo[0]"></li>
<li><input type="text" name="foo[1]"></li>
</ul>
<button id="add">Add</button>
<pre id="showsource"></pre>
</body>
</html>
Результат:
<LI><INPUT name=foo[1]>
<LI><INPUT name=foo[1]>
<LI><INPUT name=foo[1]>
<LI><INPUT name=foo[88]></LI>
<LI><INPUT name=foo[99]></LI>
<UL id=ul><LI><INPUT name=foo[0]>
<LI><INPUT name=foo[1]> </LI></UL><LI><INPUT name=foo[0]>
<LI><INPUT name=foo[1]> </LI>
поэтому я могу проанализировать его, единственный способ - создать новый li с createElement или создать объект с помощью $(...)
Ответ 5
Этот пост также посвящен этому вопросу, который дал мне представление об этой проблеме.
Странное поведение атрибута iframe` name`, заданного jQuery в IE
Ответ 6
Я знаю, что это старо, но так как я действительно не нашел ничего, что сработало для меня, я сделал довольно простое решение, хотя и уродливое:
конвертировать html в текст с помощью jquery,
затем используйте функции js string, чтобы делать то, что вам нужно.
и вставьте строку как html с помощью jquery.
только для тех, кто все еще сталкивается с этим, как и я:)