41

Since HTML data attribute allows adding any custom data, I wonder if it is a good idea to include a set of JSON list as a data attribute? Then, the corresponding JSON can be easily accessed by JavaScript events with getAttribute("data-x").

In fact, my question is that: Is it standard, efficient, and reasonable to add a large set of data to an HTML attribute?

For example

<div data-x="A LARGE SET OF JSON DATA" id="x">

Or a large set of JSON data must be stored within <script> tag, and an HTML attribute is not a right place for a large set of data, even for data attribute.

7
  • 4
    You would be MUCH better off storing the data in a script tag. Storing it in a data-attribute, while technically possible, just seems like bad practice. Buf if you really wanted to, you could. HTML5 specifies no limit for attribute lengths. (You might have to encode it or something though.) Commented Apr 5, 2013 at 16:12
  • 2
    @GJK: That does depend on the use case: if the JSON object in question is a single global data object then you're probably right; if there are multiple similar objects, each associated with a particular DOM element, then that is exactly the sort of thing that data attributes are intended for, so using them wouldn't necessarily be bad practice at all (storing the whole thing as a string in a single attribute might be, of course, but there's also the option of storing individual properties in different data attributes). Commented Sep 30, 2015 at 13:13
  • 1
    @GJK I don't think it is considered bad practice storing huge data set in a data-attribute. The very reason for creating such a tag is meant for data storage. Commented Jun 19, 2017 at 5:55
  • 1
    @GJK Can you elaborate on why you think this is bad practice? Commented Mar 18, 2018 at 9:00
  • Looking back, I should have clarified that it entirely depends on your use case. If you're injecting data on page load it might be a good idea. But if you're using data attributes to maintain application state you might have state management problems. I personally would avoid putting large amounts of data in an attribute, but I would at least encourage people to think if that's a good place to put the data. Commented Mar 19, 2018 at 15:49

5 Answers 5

41

Instead of storing everything in the data attribute you could use an identifier to access the data.

So for example you could do this :

var myBigJsonObj = { 
                      data1 : { //lots of data}, 
                      data2 : { //lots of data}                   

                   };

and then you had some html like so :

<div data-dataId="data1" id="x">

You can use jquery to get the data now like so :

var dataId = $('#x').attr('data-dataId');

var myData = myBigJsonObj[dataId];

This is the best approach imho.

Sign up to request clarification or add additional context in comments.

3 Comments

This is a really smart solution! Thank you. With 'myBigJsonObj["property"] = value;' content can be created and fetched dynamically
this might not always work. Especially when you want to set data from server side.
@theusguy on the server you could output a script tag with the data variable.
3

Say you want to save the object var dataObj = { foo: 'something', bar: 'something else' }; to an html data attribute.

Consider first stringifying the object such that we have var stringifiedDataObj = JSON.stringify(dataObj);

Then you can use jQuery to set the stringifiedDataObj as the data attribute e.g. with the jQuery.data() API

Comments

2

While there's nothing to stop you embedding a long string of JSON in a data attribute, arguably the more "correct" way of doing it would be to add one data attribute per property of the JSON data. eg:

Javascript:

var dataObj = { foo: 'something', bar: 'something else' }

HTML:

<div data-foo="something" data-bar="something else"></div>

This way each piece of data in the JSON object corresponds to a separate, independently-accessible piece of data attached to the DOM element.

Bear in mind that either way you'll need to escape the values you're inserting into the HTML - otherwise stray " characters will break your page.

2 Comments

I believe if you use JSON.parse, characters are escaped if necessary
hi, this is great idea!! can you please share how do I achieve this format? does the JSON deserializer append / or give you this format data-foo="something" data-bar="something else"
2

Technically you can, and I have seen several sites do this, but another solution is to store your JSON in a <script> tag and put a reference to the script tag in the data attribute. This is a better solution than just storing the data as a JS object in an actual script if the data is rendered to the page server-side, but there are CSP restrictions on inline script tags, for example.

HTML

<div data-data-id="#MyScriptData" id="x"></div>

<script type="application/json" id="MyScriptData">
{
    "fruit": "apple",
    ...
}
</script>

JS

$(function () {
    var dataId = $("#x").data("data-id");
    var dataTag = $(dataId);
    var dataJson = dataTag.html(); // returns a string containing the JSON data
    var data = JSON.parse(dataJson);

    ...
});

1 Comment

Hello this is interesting how do I find all the <li> list/or div items with a certain data-car attribute value=Hybrid and just get those div or li items or Id's back
0

You could make use of Map. Where your element will be the key, and the value at that key could be an object in which you store wanted data. Something like this (not tested though):

(function(global) {

  const map = new Map();

  global.CustomData = {
    add(element, key, data) {
      if (!map.has(element)) {
        map.set(element, {});
      }

      map.get(element)[key] = data;

      return map.get(element);
    },

    get(element, key) {
      if (!map.has(element)) {
        return null;
      }

      if (key !== undefined) {
        return map.get(element)[key];
      }

      return map.get(element)
    },

    remove(element, key) {
      if (!map.has(element)) {
        return false;
      }

      delete map.get(element)[key];

      if (Object.keys(map.get(element)).length === 0) {
        map.delete(element);
      }

      return true;
    },

    clear(element) {

      if (!map.has(element)) {
        return false;
      }

      map.delete(element);

      return true;
    }
  }

})(window);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.