【问题标题】:IndexedDB Fails when adding objects that contain element references添加包含元素引用的对象时,IndexedDB 失败
【发布时间】:2012-10-03 19:02:43
【问题描述】:

我正在为 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;
});

Google chrome 在尝试将第一个元素添加到 IndexedDB 存储区后静默失败(控制台中根本没有任何内容)。

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

我明天将把我的代码提炼到 JSfiddle。提前致谢。

【问题讨论】:

    标签: javascript html google-chrome dom indexeddb


    【解决方案1】:

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

    即如果你有

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

    异常会被第一行抛出。

    【讨论】:

    • 我使用的是相同版本的 Chrome,但我没有使用 put 事务。我正在通过 Chrome 的 onupgradeneeded 等效项中的 store.add 事务将数组数据添加到对象存储中。
    【解决方案2】:

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

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

    【讨论】:

    • 用户使用此应用程序更改元素的 CSS 样式。这些 CSS 样式是使用 ID 和 Class 名称来定位的,所以我害怕改变它们,因为它可能会产生意想不到的结果。我会想出一些变通办法。感谢您的回复!
    【解决方案3】:

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

    但是,静默失败并不是预期的行为。根据structured clone algorithm,它应该抛出DataCloneError。

    【讨论】:

    • 感谢您的回复。您对如何传递对元素的引用有任何想法吗?
    • 我宁愿避免引用指向元素的指针,因为可能存在内存泄漏。正如 Kristof 指出的那样,最好的选择是 ID,如果您可以唯一生成的话。第二好的是 NAME 属性,但我不知道如何以 x-browser 方式有效地检索。所以似乎人们正在使用 CLASS 名称。
    猜你喜欢
    • 1970-01-01
    • 2022-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 2022-01-08
    相关资源
    最近更新 更多