使用HTML5数据集API管理自定义数据

长期以来,Web开发人员需要将数据存储在DOM元素上。 最常见的方法之一是将数据添加为类名。 像我这样的纯粹主义者在这样做时总是感到不对劲,因为那不是存放数据的地方。 另一种方法是将自定义属性添加到感兴趣的元素。 这种做法会导致无效的标记,因为规范不支持自定义属性。 因此,您最终牺牲了验证以实现自己的目标。 这种情况非常令人沮丧。 幸运的是,HTML5修复了它。 实际上,HTML5不仅引入了通过数据属性添加自定义属性的可能性,而且公开了一个称为数据集API的API来与它们一起使用。 在本文中,我们将发现此API的工作原理以及它可以为我们做些什么。

什么是数据集API?

在所有新元素(例如articlesectionheaderfooter )和新API(例如High Resolution TimeUser TiminggetUserMediaPage Visility )中,HTML5还引入了数据属性和数据集API。 在深入讨论数据集API之前,我想让您快速回顾一下什么是数据属性。

数据属性从data-前缀获取名称。 这也解释了为什么有时将它们称为data-*属性。 下面显示了使用数据属性的元素示例。

<span id="element" data-level="1" data-points="100" data-opponent="Dragon"></span>

您可以选择的名称不仅限于一个单词。 名称也可以包含多个单词,并用连字符( - )分隔。 因此,假设您要将opponent属性更改为final opponent 。 您将如下例所示编写元素。

<span id="element" data-level="1" data-points="100" data-final-opponent="Dragon"></span>

现在,您应该对什么是数据属性有了一个清晰的认识,让我们开始讨论API。 数据集API为我们提供了一种处理数据属性的简单方法。 该API允许我们设置,获取甚至删除数据属性值。 数据集API公开了名为dataset的DOM元素属性,其中包含DOMStringMap对象。 该对象的键是不带data-前缀的数据属性的名称。 相应的值是数据属性的值。 如果属性的名称由连字号分隔的多个单词组成,则将其转换为camelCase。 让我们看下面的例子:

var obj = document.getElementById("element").dataset

前一个语句将变量obj中的后一个obj

{
  level: "1",
  points: "100",
  finalOpponent: "Dragon"
}

可以使用setAttribute()getAttribute()removeAttribute()方法访问单个数据属性。 但是,数据集API为您提供了一种方便直接的方法来访问自定义数据。 如果不支持该API,则应检索所有属性,然后过滤那些不是以data-开头的属性。 而且,尽管数据集API更简单,但它也比前面提到的方法(如JSperf所证明的) 。 但是,除非您每秒访问数千个属性,否则您不会注意到任何区别。

现在,我们已经讨论了数据集API,现在该看看如何使用它了。

设定值

想象一下,我们想将data-media属性添加到元素中,并将其值设置为song 。 要执行此任务,我们可以编写以下代码。 请注意,如果已经定义了属性,则其值将被覆盖。

document.getElementById("element").dataset.media = "song";

获得价值

如果我们无法检索属性,则创建属性完全没有用。 假设我们想将data-final-opponent属性的值打印到控制台。 这样做的代码如下所示:

console.log(document.getElementById("element").dataset.finalOpponent);
// prints "Dragon"

删除属性

要删除一个值,只需使用空字符串覆盖它即可。 但是,要实际删除属性,我们可以使用JavaScript delete运算符。 下面显示了删除data-final-opponent属性的示例。

delete document.getElementById("element").dataset.finalOpponent;

执行上一条语句后,尝试检索属性的值将产生undefined

浏览器兼容性

除了Internet Explorer(仅在IE11中实现API)之外,台式机和移动浏览器还广泛支持数据集API。 此外,有些较旧的移动浏览器不支持该浏览器,但总的来说支持非常好。 对于不支持该API的浏览器,可以使用名为HTML 5数据集支持的polyfill。 如果您不想为这种简单的API添加polyfill,则可以使用setAttribute()getAttribute()removeAttribute() (如前所述)。

演示版

学习一些新东西是很棒的,但是如果我们可以尝试它,那就更好了。 因此,我们将构建一个小示例,使我们能够查看数据集API的工作方式。 一般的想法是要有一个元素,我们可以在该元素上获取,设置和删除数据属性。 为了查看发生了什么并关注元素的当前状态,我们将有一个小窗口,其中记录了所做的更改。 此外,我们将在一个区域中显示表示其当前状态的元素的原始HTML代码。

为了发挥其数据属性,我们需要两个输入框:键和值。 前者允许我们设置要存储的属性的名称,而后者则是我们写入属性值的位置。 因为我们要允许三个不同的动作(获取,设置和删除),所以我们还需要三个按钮,向它们添加处理程序。 与往常一样,我们还将测试浏览器的支持,如果测试失败,我们将显示消息“不支持API”。

在向您展示演示代码之前,我想与您分享两个注意事项。 该演示假定您已经阅读了整篇文章。 因此,您知道要对用一个以上单词命名的数据属性执行操作,必须将名称转换为camelCase。 如果您想更改此行为并能够编写“ final-opponent”而不是“ finalOpponent”,那么我为您编写了两个实用程序函数。 要使用这些功能,您需要将它们添加到演示中并更改代码,以便在执行操作之前在处理程序中调用它们。 这些功能的源代码在下面列出。

function hyphenToCamelCase(string) {
  return string.replace(/-([a-z])/g, function(string) {
    return string[1].toUpperCase();
  });
}

function camelCaseToHyphen(string) {
  return string.replace(/([A-Z])/g, function(string) {
    return '-' + string.toLowerCase();
  });
}

要记住的第二件事是,到目前为止,我们已经使用点运算符访问了数据属性,因为我们提前知道了它的名称。 在演示中,我们没有此信息,因此要访问dataset的属性,我们将使用等效的方括号表示法。

现在,该向您展示源代码了。 像往常一样,可以在此处获得代码的实时演示。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Dataset API Demo</title>
    <style>
      body
      {
        max-width: 500px;
        margin: 2em auto;
        font-size: 20px;
      }

      h1
      {
        text-align: center;
      }

      .hidden
      {
        display: none;
      }

      #log
      {
        height: 200px;
        width: 100%;
        overflow-y: scroll;
        border: 1px solid #333333;
        line-height: 1.3em;
      }

      .buttons-demo-wrapper
      {
        text-align: center;
      }

      .button-demo
      {
        padding: 0.5em;
        margin: 1em;
      }

      .author
      {
        display: block;
        margin-top: 1em;
      }
    </style>
  </head>
  <body>
    <h1>Dataset API</h1>

    <h3>Live sample element</h3>
    <div id="showcase">
      &lt;span id="play-element" class="hidden" data-level="1" data-points="100" data-final-opponent="Dragon"&gt;&lt;/span&gt;
    </div>

    <h3>Play area</h3>
    <div>
      <label for="key">Key:</label>
      <input type="text" id="key"></input>
      <label for="value">Value:</label>
      <input type="text" id="value"></input>

      <div class="buttons-demo-wrapper">
        <button id="set-data" class="button-demo">Set data</button>
        <button id="get-data" class="button-demo">Get data</button>
        <button id="delete-data" class="button-demo">Delete data</button>
      </div>
    </div>

    <span id="d-unsupported" class="hidden">API not supported</span>

    <h3>Log</h3>
    <div id="log"></div>
    <button id="clear-log" class="button-demo">Clear log</button>

    <span id="play-element" class="hidden" data-level="1" data-points="100" data-final-opponent="Dragon"></span>

    <script>
      if (!"dataset" in document.createElement("span")) {
        document.getElementById("d-unsupported").classList.remove("hidden");
        ["set-data", "get-data", "delete-data"].forEach(function(elementId, index) {
          document.getElementById(elementId).setAttribute("disabled", "disabled");
        });
      } else {
        var playElement = document.getElementById("play-element");
        var key = document.getElementById("key");
        var value = document.getElementById("value");
        var log = document.getElementById("log");
        var showcase = document.getElementById("showcase");

        document.getElementById("clear-log").addEventListener("click", function() {
          log.innerHTML = "";
        });
        document.getElementById("set-data").addEventListener("click", function() {
          if (key.value.indexOf("-") !== -1) {
            log.innerHTML = "Warning! Hyphen not allowed. Use camelCase instead.\n" + log.innerHTML;
          } else {
            playElement.dataset[key.value] = value.value;
            showcase.textContent = playElement.outerHTML;
            log.innerHTML = "Set data-" + key.value + " attribute to '" + value.value + "'<br />" + log.innerHTML;
          }
        });
        document.getElementById("get-data").addEventListener("click", function() {
          if (key.value.indexOf("-") !== -1) {
            log.innerHTML = "Warning! Hyphen not allowed. Use camelCase instead.<br />" + log.innerHTML;
          } else {
            log.innerHTML = "Get data-" + key.value + " attribute. Value: '" + playElement.dataset[key.value] + "'<br />" + log.innerHTML;
          }
        });
        document.getElementById("delete-data").addEventListener("click", function() {
          if (key.value.indexOf("-") !== -1) {
            log.innerHTML = "Warning! Hyphen not allowed. Use camelCase instead.<br />" + log.innerHTML;
          } else {
            delete playElement.dataset[key.value];
            showcase.textContent = playElement.outerHTML;
            log.innerHTML = "Deleted data-" + key.value + " attribute<br />" + log.innerHTML;
          }
        });
      }
    </script>
  </body>
</html>

结论

在本文中,我们讨论了数据集API及其如何帮助我们在DOM元素上存储自定义属性。 如我们所见,API非常易于使用。 此外,它在桌面和移动浏览器中也得到广泛支持。 您可以在下一个项目中立即开始使用它。 如果您有任何疑问,建议您使用提供的演示或发布问题。

From: https://www.sitepoint.com/managing-custom-data-html5-dataset-api/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值