将数据与HTML元素关联(不带jQuery)

Associate Data With HTML Element (without jQuery)

本文关键字:不带 jQuery 关联 元素 数据 HTML      更新时间:2024-02-21

我需要将一些数据与HTML元素关联起来,希望能避免任何内存泄漏。显然,一个简单的解决方案是在元素上抛出某种标识符,然后创建一个字典,将该标识符映射到我需要的数据。然而,这是在用户将添加到页面的javascript库中,因此我无法控制何时添加或删除元素。

我想做的是,当HTML元素在页面上时,将数据与它关联起来,同时允许在元素被删除时/如果元素被删除,则对该数据进行GC处理。有没有一种方法可以做到这一点,而不需要编写自己的定期GC来清理孤立数据?向HTML元素添加属性安全吗?

属性方法

可以使用自定义data-*属性将数据存储在元素中。

这有一个限制,即只能存储字符串,但可以使用JSON来存储普通对象或数组(不能通过引用)。

为了避免与其他代码发生冲突,最好在属性中包含库的名称。

它们可以直接在HTML:中设置

<div data-mylibrary-foo="bar"></div>

它们可以用JavaScript读取或写入:

element.getAttribute('data-mylibrary-foo');        // read  (old way)
element.setAttribute('data-mylibrary-foo', 'bar'); // write (old way)
element.dataset.mylibraryFoo;                      // read  (new way)
element.dataset.mylibraryFoo = 'bar';              // write (new way)

CSS也可以使用一些属性选择器来读取它们。

属性方法

这比属性方法灵活得多,允许在元素中存储任意数据。

为了避免与其他代码发生冲突,最好用库的名称将对象中的所有属性包装起来:

element.mylibrary = {};
element.mylibrary.foo = 'bar';

问题是,未来的HTML标准可能会将mylibrary定义为本机属性,因此可能会出现问题。

符号方法

ECMAScript 6引入了可以用作属性的符号。优点是每个符号都有一个唯一的标识,因此您不需要担心其他库或未来的标准使用与代码相同的属性。

var foo = Symbol("foo");
element[foo] = 'bar';

WeakMap方法

ECMAScript 6引入了WeakMaps,它允许您将数据与对象相关联,如果对象不再在其他地方被引用,它们将被垃圾收集。

与属性方法一样,它们允许您存储任意数据。

由于数据不存储在元素本身中,因此不存在冲突的风险。

var allData = new WeakMap();
var data1 = allData.get(element1) || {}; // read
data1.foo = "bar";
allData.set(element1, data1);            // write

JavaScript中的HTML元素只是一个JavaScript对象,所以你当然可以向它添加任意属性。JavaScript会很好地处理垃圾收集。

data-属性是另一个选项,如果您的属性是字符串,它可能是更好的选择;它们的值将在DOM中可见(这对调试来说可能是一件好事)。如果你的属性本身就是对象,那么你就必须对它们进行字符串化(并反转过程来检索它们的值)。