jQuery克隆问题

时间:2010-05-05 12:52:16

标签: jquery internet-explorer clone

我正在尝试克隆div并更改此div中输入字段的名称。 它适用于大多数浏览器,但IE 7不会更改输入字段的name属性。

演示:http://jsbin.com/iduro/7

HTML

<body>
  <pre></pre>
  <div><input value="Hello World" name="test"></div>
</body>

JS

var lastRow = $("body div:last"),
    newRow  = lastRow.clone(true)
              .show()
              .insertAfter(lastRow);

newRow.find('input').attr("name","test2");

$("pre").text( newRow[0].innerHTML );

结果:

Firefox :(有效)  <input value="Hello World" name="test2">

IE8(正常) <INPUT value="Hello World" name=test2 jQuery1273063250500="4">

IE7(错误): <INPUT value="Hello World" name=test jQuery1273063303968="4">

如您所见,IE7的名称未更改为test2。

有没有明显的理由或解决方法?

4 个答案:

答案 0 :(得分:2)

我现在可以解决它。 只要输入字段未附加到dom,您就可以更改名称,并且单选按钮可以再次正常工作。

// Old Code
 $("div:last").clone(true).children("input").attr("name","newName");

// New Code
 $("div:last").clone(true).children("input").fixCloneBug ("newName");

为了降低执行时间,只复制jQuery Events,className和type属性。

fixCloneBug方法:

(function( $ )
{


    if ( ! $.browser.msie || parseInt( $.browser.version ) > 7 )
        // NO FIX FOR IE 7+ FF WEBKIT
        $.fn.fixCloneBug = function( newName ){ return this.attr( "name", newName ) };
    else
        // FIX IE 5-7
        $.fn.fixCloneBug = function( newName )
        {
            var $cloned = $();

            this.each(function( )
            {
                    /* -._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._

                       Create a new element with className and jQuery events of the buggy element

                    */          

                    var     $elem    = $(this),

                            $newElem = $(document.createElement( $elem.attr('tagName') ));

                            // USE SAME TYPE

                    $newElem.attr('type', $elem.attr('type') );


                            // SET NAME
                    $newElem.attr('name', this.name );
                    $newElem.attr('name', newName );

                            // ADD TO DOM

                    $newElem.insertBefore( $elem );

                            // CLONE EVENTS
                    $newElem.data( "events", $elem.data("events") );

                            // CLASS NAME
                    $newElem.attr('className', this.className );

                    /* -._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._

                       Delete buggy element 

                    */

                    $elem.remove();


                    // Add to result
                    $cloned.push($newElem);
            })

            return $cloned;

        }

}(jQuery));

也许您认为$newElem.attr('name', this.name );无用,但它允许我使用jQuery 1.4功能:

.fixCloneBug (function(i,oldname){ return oldname+"_new" })

答案 1 :(得分:1)

试试这个(原始代码)

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

检查 i = 50 然后中断/退出

更好的方法:将名称用作name=picture[]

之类的数组

Refernece

答案 2 :(得分:0)

如果您在发布表单时平移访问这些作为一个集合,则无需更改名称 - 只是不要在括号中放置一个值,当您在服务器上获取阵列时它将为您增加侧:

<input name="test[]" />

如果您需要能够通过js的索引访问每个,您可以在选择器返回的相应集合上使用get。或者,您可以指定test_1等ID属性。

答案 3 :(得分:0)

单选按钮的简单解决方案是:

$("div:last").find("radio").each(function(){
     var name="someNewName";
     var id="someNewId";
    if (!$.browser.msie || parseInt($.browser.version) > 7) {
      this.name = name;
      this.id=id;
    }
    else {
      (this).attr("outerHTML", "<input type=radio id=" + id + " name=" + name + " />");  
    }
});

这将改变元素的 outerHTML ,以便覆盖元素的HTML(单选按钮)。同样的解决方案也适用于:其他控件的find(“input”)/ find(“checkbox”)。