Javascript 将新创建的元素追加到父窗口时保留.data()值

Javascript 将新创建的元素追加到父窗口时保留.data()值,javascript,jquery,json,ajax,append,Javascript,Jquery,Json,Ajax,Append,我在弹出窗口中运行了一段jQuery代码,它解析来自AJAX请求的JSON响应。作为这项工作的一部分,它动态创建一系列元素及其内容,包括使用.data()函数为其分配数据属性的锚元素,以更新父窗口中的表 此代码按预期工作。使用正确的内容创建行,然后将其添加到主窗口中的表中。只有一个小问题——附加到锚元素的数据消失了 JSON响应如下所示(相关部分是locationList数组): Javascript如下所示: var $locations = opener.$('#document-conte

我在弹出窗口中运行了一段jQuery代码,它解析来自AJAX请求的JSON响应。作为这项工作的一部分,它动态创建一系列
元素及其内容,包括使用
.data()
函数为其分配数据属性的锚元素,以更新父窗口中的表

此代码按预期工作。使用正确的内容创建行,然后将其添加到主窗口中的表中。只有一个小问题——附加到锚元素的数据消失了

JSON响应如下所示(相关部分是
locationList
数组):

Javascript如下所示:

var $locations = opener.$('#document-content-locations');
$locations.empty();
for(var i = 0; i < data.locationList.length; i++) {
    var location = data.locationList[i];
    var rowClass = (i % 2 == 0) ? "odd" : "even";
    var row = $('<tr/>').addClass(rowClass);
    row.append($('<td/>').text(location.name));
    var link = $('<a/>').attr('href', '#').data({locid: location.locid, countryid: location.countryid, imtid: location.imtid}).text('remove').addClass('removelocation');
    console.log(link.data());
    row.append($('<td/>').append(link));
    console.log(row.find('a').data());
    $locations.append(row);
    console.log($locations.find('a').data());
}
认为所发生的事情是调用
.append()
,而不是简单地将元素附加到主窗口中的表中,克隆元素(减去数据和事件信息),然后将其添加到主窗口中的表中。我尝试显式克隆元素(传递true以保留数据和事件),然后附加该元素,但问题仍然存在

我可以通过在锚的HTML中使用HTML5
data-*
属性来解决这个问题,而不是使用
.data()
函数。现在还可以,因为只有少数,但它不容易扩展

因此,我有几个问题:

  • 我的想法/假设可能是正确的吗?正在呼叫
    .append()
    ,从弹出窗口添加新创建的元素以添加到 父窗口中的元素是否可能克隆该元素(即使似乎没有理由这样做)
  • 除了进入并修改jQuery源代码之外,还有其他方法可以告诉我们吗
    .append()
    (和类似函数)以保留数据和事件 它在执行过程中创建的任何克隆的信息(我认为默认情况下不会这样做)
  • 我是否在上述代码中做了导致问题的固有错误
  • 它看起来像.append()有时移动,有时克隆

    我在使用.append()时也看到了同样的情况。在我的例子中,我以编程方式创建锚并将事件处理程序绑定到锚。然后I.append()将锚对象添加到DOM中的其他位置,它们会丢失事件处理程序。

    我花了一段时间(大约一年——我第一次发现时忘了回来回答这个问题)才意识到这里发生了什么,并导致了我遇到的问题。当我问这个问题时,我并没有真正了解数据是如何存储在DOM节点上的,但我对调用
    .data()
    来设置和获取值时内部发生的情况有了更好的(如果不是完全的话)了解

    对于DOM节点,jQuery有一个全局缓存,用于存储所有数据。然后为每个节点分配一个唯一的ID,该ID用作密钥,以便稍后从缓存中检索该特定节点的数据


    这都是相对简单的,那么为什么它不能在浏览器窗口之间工作呢?答案(现在)非常明显:每个单独的窗口都有自己的全局缓存,在子窗口(弹出窗口)中设置数据时生成的唯一ID与父窗口的全局缓存中的条目不匹配(如果它甚至被传输)。

    我知道它在调用
    .append()时进行克隆
    在包含多个元素的jQuery对象上,但在我的情况下,它应该只包含一个元素(因为我使用的是ID选择器),因此只需移动元素。啊,我想我没有足够清楚地阅读您的问题。可能.append()只会跨浏览器窗口进行克隆。作为折衷方案,您可以序列化数据对象:link.attr('data-json',json.stringify(data)),并在以后需要使用时反序列化:json.parse(link.attr('data-json'))
    var $locations = opener.$('#document-content-locations');
    $locations.empty();
    for(var i = 0; i < data.locationList.length; i++) {
        var location = data.locationList[i];
        var rowClass = (i % 2 == 0) ? "odd" : "even";
        var row = $('<tr/>').addClass(rowClass);
        row.append($('<td/>').text(location.name));
        var link = $('<a/>').attr('href', '#').data({locid: location.locid, countryid: location.countryid, imtid: location.imtid}).text('remove').addClass('removelocation');
        console.log(link.data());
        row.append($('<td/>').append(link));
        console.log(row.find('a').data());
        $locations.append(row);
        console.log($locations.find('a').data());
    }
    
    Object { locid="-1", countryid="-1", imtid="-1"}
    Object { locid="-1", countryid="-1", imtid="-1"}
    Object {}