【问题标题】:Proper Place to Bind Object to Element将对象绑定到元素的适当位置
【发布时间】:2019-08-21 09:16:45
【问题描述】:

Data Attributes 是将字符串存储到 DOM 元素中的安​​全位置,因为可以保证您的属性命名永远不会与添加到 DOM 规范中的未来属性发生冲突。

但是,如果您想将非 JSON javascript 对象作为属性绑定到 DOM 元素怎么办?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Bind Custom Object to DOM Element</title>
    <style>
            div{ border: solid #333333 1vmin; padding:1vmin; 
                display:inline-block; font-size:4vmin}
    </style>
    <script type="text/javascript">
        function main()
        {
            let obj = {}
            obj.name = "Lonnie";

            let div = document.createElement("div");
            div.textContent = "Click Me";
            div.myCustomObject = obj;
            div.addEventListener('click',function()
            {
                alert(this.myCustomObject.name);
            });
            document.body.appendChild(div);
        }
        window.addEventListener('load', main);
    </script>
</head>
<body>
</body>
</html>

数据属性旨在保存字符串,而不是对象。是否可以将它们用于非 JSON 对象属性,或者规范是否建议使用不同的位置将对象属性添加到 DOM 节点?

【问题讨论】:

  • 我不认为 HTMLElements 应该保持你的状态。为什么不创建一个 Map 的元素 ID 和您的自定义对象。在您的事件处理程序中,您可以通过元素 id 检索状态。
  • 这不是数据属性,而是expando。而且……我还是不知道这个问题的答案! (但是,是的,如果您可以依赖 WeakMap 支持,它是等价的。)
  • @Reijo 我知道这可以通过地图来完成。我的问题仍然存在。
  • @LonnieBest 那你是在请求许可吗?当然,您可以使用自己的属性扩展元素,但如果您可以使用 Map 或 WeakMap 或任何已证明可以解决问题的状态管理解决方案,您为什么要这样做。
  • 我主要希望有人能指导我到一个地方,在规范中,当您实际向 DOM 节点添加对象属性时,正式解决“未来命名冲突”的避免(就像data attributes 为添加到 DOM 节点的基于字符串的属性解决这个问题一样)。这样做的能力不会消失,所以我希望有一种更正式的方式来避免未来的命名冲突,而不是“不太可能的未来属性”命名。

标签: javascript dom ecmascript-next


【解决方案1】:

数据属性旨在保存字符串,而不是对象。

但是你没有使用属性。因此,您可以将所需的所有内容存储在常规属性下。

是否可以将它们用于非 JSON 对象属性,

当然。

或者规范是否推荐了一个不同的位置来将对象属性添加到 DOM 节点?

不,它没有。 DOM 规范是语言中立的,因此它并没有真正描述 JS 中实现该规范的对象的行为方式。

【讨论】:

  • 我意识到我没有在我的示例中使用数据属性,但我想知道的是:数据属性是否也针对我的示例中所示的情况缩进。如果没有,规范是否正式解决了如何避免未来 DOM 节点上的自定义对象属性的命名冲突。我从未在规范中看到过这个确切的主题。
  • 数据属性只能包含字符串。肯定会有碰撞。
【解决方案2】:

我会使用 ES6 的 WeakMap 解决方案:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Bind Custom Object to DOM Element</title>
    <style>
            div{ border: solid #333333 1vmin; padding:1vmin; 
                display:inline-block; font-size:4vmin}
    </style>
    <script type="text/javascript">
        async function main()
        {
            let obj = {}
            obj.name = "Lonnie";
            let obj2 = {}
            obj2.name = "Mark"

            let div = document.createElement("div");
            div.textContent = "Click Me";
            div.myCustomObject = obj;

            const wm = new WeakMap();

            wm.set(div, obj);
            wm.set(div, obj2);
            console.log(wm.get(div)); // "my value"

            div.addEventListener('click',function()
            {
                alert(wm.get(div).name);
            });
            document.body.appendChild(div);
        }
        window.addEventListener('load', main);
    </script>
</head>
<body>
</body>
</html>

此方法可确保属性名称之间没有冲突。

我个人认为将其绑定到属性没有任何问题,但似乎也没有任何建议反对这样做,数据属性意味着包含字符串

【讨论】:

    猜你喜欢
    • 2012-03-23
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2021-11-09
    • 2018-07-13
    • 2016-06-26
    相关资源
    最近更新 更多