IndexedDB在添加包含元素引用的对象时失败



我正在为Google Chrome编写一个应用程序(目标受众是内部团队),该应用程序允许用户从iframe中操作元素。用户可以使用鼠标选择DOM元素并对其执行各种操作,例如更改颜色、字体等。

我使用nodeIterator方法只选择具有ID或类名的元素。然后,对于这些元素中的每一个,我将一些特定于元素的属性添加到对象中,并将该对象推送到数组中。然后,我打开一个IndexedDB数据库,并将数组中的每个对象添加到数据库中。

我的问题是:只要我不在对象中包含对元素的引用,一切都很好。

// Works fine
array.push({
width : currentNode.offsetWidth,
height : currentNode.offsetHeight,
top : currentNode.style.top;
left : currentNode.style.left;
});
// Doesn't work
array.push({
elem : currentNode,
width : currentNode.offsetWidth,
height : currentNode.offsetHeight,
top : currentNode.style.top;
left : currentNode.style.left;
});

在尝试将第一个元素添加到IndexedDB存储后,Google chrome会无声地失败(控制台中什么都没有)。

我的问题是:其他人经历过这种行为吗?这是浏览器特有的错误吗?

明天我将把我的代码提取到JSfiddle中。提前谢谢。

IndexedDB存储对象的结构化克隆。基本上,您的数据将转换为JSON对象,这些对象不包括Element或Node数据类型。

然而,默默地失败并不是一种意料之中的行为。根据结构化克隆算法,它应该抛出DataCloneError。

是否需要保存DOM元素?您可以只保存DOM元素的ID并根据其ID检索元素吗?

indexeddb只能存储没有循环引用的数据。也许有一件事你可以试试。不久前,我写了一篇关于如何将函数序列化和反序列化为JSON的博客文章。也许这可以帮助你,但我建议你不要存储完整的元素,除非没有其他选择。这将向数据库中添加大量不必要的数据,并且在序列化为JSON时可能会丢失信息。

您应该在chrome中从put()本身获得一个异常(我刚刚在Chrome23上尝试过),这意味着如果您有一个oneror处理程序,它将不会被调用,因为异常首先被调用:

即,如果您有

req = db.transaction("foo", "readwrite").objectStore("foo").put({...data with dom nodes })
req.onsuccess = ...
req.onerror = ...

异常将由第一行引发。