在jQuery中更改克隆输入元素的名称attr在IE6 / 7中不起作用

时间:2010-01-19 15:34:38

标签: jquery internet-explorer-7 internet-explorer-6 clone

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>

Copy'n'paste'n'run,单击Add按钮几次。每次点击,您都会看到<ul>中显示的<pre id="showsource">的HTML代码,预计代码大致应为:

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

googled了一下,找到了this very similar problem,他修复了它并发布了一个代码片段,它应该是什么样子。不幸的是,这正是我已经做过的,所以我怀疑他只是在IE8中测试,而不是在IE6 / 7中。除了那个特定主题,谷歌没有透露太多。

任何见解?或者我真的要回到document.createElement

注意:我知道我可以为每个输入元素使用相同的名称并将它们作为数组检索,但上面只是一个基本的例子,实际上我真的需要更改name属性,因为它不仅包含索引,还包含其他信息,如parentindex,order等。它已被用于添加/重新排列/删除(子)菜单项。

编辑:这与this bug有关,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库应该涵盖这个特殊问题?

6 个答案:

答案 0 :(得分:9)

这是一个在所有浏览器中设置元素名称的函数,甚至是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);
  }
}

我发现在不同版本的IE中使用replaceElement和outerHTML并不可靠。但上面的mergeAttributes技巧完美无缺!

答案 1 :(得分:4)

我为这个问题创建了一个部分解决方案,我在这里描述: 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);
});

肯定很糟糕但绝对有效。

答案 2 :(得分:3)

我想知道你是否遇到了 this bug in IE (即使使用jQuery)?

基本上在IE中你不能改变元素的名称属性(常规或克隆)(然后通过javascript按名称重新访问它们),尽管你可以提交它们(例如输入元素)并让它们成功提交。 / p>

答案 3 :(得分:2)

不是答案,是对问题的分析:

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

所以我可以分析它,唯一的方法是使用createElement创建一个新的li或用$(...)创建对象

答案 4 :(得分:2)

这篇文章也是关于这个主题的,这让我对这个问题有所了解。

Weird behaviour of iframe `name` attribute set by jQuery in IE

答案 5 :(得分:1)

我知道这已经过时了,但是因为我并没有真正找到任何对我有用的东西,所以我提出了一个非常简单的解决方案,但这是一个丑陋的解决方案:

使用jquery将html转换为文本, 然后使用js字符串函数来执行它 并使用jquery将字符串作为html插入。

只为那些仍然遇到这种情况的人,比如我自己:)