【问题标题】:jQuery clone problemjQuery克隆问题
【发布时间】:2010-05-05 12:52:15
【问题描述】:

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

演示: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:(有效) &lt;input value="Hello World" name="test2"&gt;

IE8(工作) &lt;INPUT value="Hello World" name=test2 jQuery1273063250500="4"&gt;

IE7(错误): &lt;INPUT value="Hello World" name=test jQuery1273063303968="4"&gt;

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

有什么明显的原因或解决方法吗?

【问题讨论】:

标签: jquery internet-explorer clone


【解决方案1】:

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

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

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

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

修复CloneBug方法:

(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" })

【讨论】:

    【解决方案2】:

    试试这个(原始代码)

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

    【讨论】:

      【解决方案3】:

      如果您在发布表单时将这些作为一组访问,则无需更改名称 - 只需不要在括号内输入值,当您抓取服务器上的数组时,它将为您递增侧面:

      &lt;input name="test[]" /&gt;

      如果您需要能够通过 js 中的索引访问每一个,您可以在选择器返回的适当集合上使用 get。或者您可以分配 ID 属性,例如 test_1

      【讨论】:

      • 我尝试克隆一排单选按钮。但是,由于更改名称不起作用,用户只能为两行选择一个单选按钮,而不是两个。
      • @prodigtalson +1。在遇到相同的解决方案时尝试了这个并解决了我的问题。我只使用了文本输入和选择语句,所以仍然可能会出现上面提到的无线电问题。
      • 有用的信息,但是 -1 因为这不能回答所提出的问题。
      【解决方案4】:

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

      $("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")。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-23
        • 1970-01-01
        • 2012-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多