jQuery clone() 复制数据...有时...?

Posted

技术标签:

【中文标题】jQuery clone() 复制数据...有时...?【英文标题】:jQuery clone() copies data...sometimes...? 【发布时间】:2012-12-01 16:35:53 【问题描述】:

使用下面的示例,我复制了一个 tr。它包含一个 jQuery autocomplete。第一次克隆时,自动完成功能不起作用,因为附加的data("items") 为空。第二次单击“添加”按钮时,自动完成功能起作用。此后,再次单击“添加”会产生不起作用的自动完成功能。

makeAutoComplete 函数内添加断点表明items 始终为空,除非在第二次单击添加时!

谁能解释这种奇怪的行为?

HTML/JS(此处为小提琴:http://jsfiddle.net/SDvF4/12/)

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <title>Test!</title>
        <style type="text/css">
            tr.Template
            
                display: none;
            
        </style>
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
        <script type="text/javascript" src="http://code.jquery.com/ui/1.8.18/jquery-ui.js"></script>
        <script type="text/javascript">
            $(document).ready(function ()
            
                var textbox = $(".AutoComplete");

                makeAutoComplete(textbox);

                $("#addButton").click(function ()
                
                    var attrRegex = /\d+/;
                    var template = $("tr.Template");
                    var newRow = template.clone(false);
                    var newRowIndex = (template.siblings().length + 1);

                    newRow.removeClass("Template");
                    newRow.find("*[id]").each(function ()
                    
                        var element = $(this);

                        element.attr("id", element.attr("id").replace(attrRegex, newRowIndex));
                    );
                    newRow.find("*[name]").each(function ()
                    
                        var element = $(this);

                        element.attr("name", element.attr("name").replace(attrRegex, newRowIndex));
                    );
                    newRow.insertBefore(template);
                    newRow.find(".AutoComplete").each(function ()
                    
                        makeAutoComplete($(this));
                    );
                );
            );

            function makeAutoComplete(textbox)
            
                var items = textbox.data("items");
                var test = textbox.data("test");

                if (items == null)
                
                    if (test == "JSM")
                        alert("ERROR: data.items not copied but data.test was!");
                    else
                        alert("ERROR: data.items not copied nor was data.test!");
                

                textbox.autocomplete(
                
                    minLength: 0,
                    source: items
                );
            
        </script>
    </head>
    <body>
        <table>
            <tbody>
                <tr class="Template">
                    <td>
                        <input id="test_0" name="test_0" class="AutoComplete" type="text"/>
                        <script type="text/javascript">
                            var testData = [ label: "One", value: 1 ,  label: "Two", value: 2 ];

                            $("#test_0").data("items", testData);
                            $("#test_0").data("test", "JSM");
                        </script>
                    </td>
                </tr>
            </tbody>
        </table>
        <br/><br/>

        <button id="addButton">Add</button>​
    </body>
</html>

【问题讨论】:

您使用了错误的 ID。它们以-1 开头,也变成0,这就是模板ID。使用+ 1 而不是- 1 来表示newRowIndex。不过,不知道为什么 .clone() 会因此暴露出不同的行为。 谢谢,很好的发现。这就解释了为什么第二个克隆可以工作而其他克隆没有 - 它与模板具有相同的 ID,但出现在它之前。 这两个数据属性都不会被复制 - 您正在使用 .clone(false) - 来自文档,它指出 A Boolean indicating whether event handlers and data should be copied along with the elements. 这似乎是一个错误。我将其归结为以下内容:jsfiddle.net/SDvF4/5。点击按钮,看到insertBefore之后的数据就神奇的可用了。此外,如果您将&lt;script&gt; 块移出&lt;td&gt;(这应该没有任何副作用),这不会发生。如果您选择jQuery (edge),则问题将完全消失,因此已在此期间修复。 @pimvdb - 有趣...尝试一下... 【参考方案1】:

我必须解决多个问题才能使其正常工作。

首先由@pimvdb 指出 - 我没有正确标识元素,因此第二个新行的 ID 与模板行相同。

其次,您不能简单地在已经是 autocomplete 的小部件上调用 autocomplete - 首先您必须销毁它:

textbox.autocomplete("destroy");
textbox.removeData("autocomplete");

第 12 版正常工作:http://jsfiddle.net/SDvF4/12/

【讨论】:

以上是关于jQuery clone() 复制数据...有时...?的主要内容,如果未能解决你的问题,请参考以下文章

jQuery-2.DOM---节点的复制与替换

jQuery-DOM操作之复制替换包裹节点

jQuery clone( ) 方法

JavaScript中的对象复制(Object Clone)

jquery里怎么用clone给表格增加一行

Jquery浅克隆与深克隆