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

时间:2012-10-12 22:26:36

标签: javascript html5 google-chrome dom 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。提前谢谢。

3 个答案:

答案 0 :(得分:4)

您对象的IndexedDB store structured clone。基本上您的数据将转换为JSON对象,这些不包括Element或Node数据类型。

然而,静默失败不是预期的行为。根据{{​​3}},它应该抛出DataCloneError。

答案 1 :(得分:1)

是否需要保存DOM元素?你能保存DOM元素的ID并通过它的ID检索元素吗?

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

答案 2 :(得分:0)

你应该从put()本身获得chrome(我刚试过Chrome 23)的异常,这意味着如果你有一个onerror处理程序,它将不会被调用,因为首先调用异常:

即。如果你有

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

第一行会抛出异常。