0

I am new to javascript programming and i am stuck with data-attribute retrieval.

The below link is a bit useful for people using jQuery

store and retrieve javascript arrays into and from HTML5 data attributes

I would like to do the same with vanilla js. With the help of custom data-attributes i would like to create objects & array.

<div id="getAnimation"
data-r="564"
data-c="96" 
data-custom="x:0;y:0;z:0;rotationX:0;rotationY:0;rotationZ:0;scaleX:0.75;scaleY:0.75; skewX:0;skewY:0;opacity:0;transformPerspective:600;transformOrigin:50% 50%;"
data-s="700"
data-st="1400"
</div>

Do HTML5 custom data attributes “work” in IE 6?

The above link helps in getting data attributes very well but how can be filter the string in data-custom or straight create an object of data-custom.

If someone know a library to do this please let me know

5
  • 1
    Are you saying you want to support IE6?
    – Paul S.
    Commented Sep 5, 2014 at 12:57
  • @PaulS.: Doesn't really matter other than (in the case of my answer) using or not using forEach. (Although supporting IE6 would be fairly odd these days! But forEach is missing on IE8, too...) IE6 isn't bothered by data-* attributes (as far as I'm aware, no browser is). Commented Sep 5, 2014 at 13:02
  • I remember that xxx.getAttribute used to work with non-standard attributes in IE6, but I have no f*****g idea how to test a 14 years old outdated browser. Commented Sep 5, 2014 at 13:06
  • @sebcap26: It does indeed work, I used data-* attributes on a project that needed IE6 (!) support a few years ago. (And I keep a Windows 2000 virtual machine around for these things, although I haven't needed it in a long time, since IE6 finally did really die.) Commented Sep 5, 2014 at 13:07
  • Why not just put JSON in the data attribute? What would the object or array created from the OP look like? Why is this data being stored in an element and not in a data object?
    – RobG
    Commented Sep 5, 2014 at 13:13

2 Answers 2

1

Here are a couple quick functions which will let you store, retrieve and delete any JSON-able data to a data attribute

function setData(node, data_name, data_value) {
    node.dataset[data_name] = JSON.stringify(data_value);
}

function getData(node, data_name) {
    return JSON.parse(node.dataset[data_name]);
}

function delData(node, data_name) {
    return delete node.dataset[data_name];
}

Then to write an Array to #getAnimation in data-fizz

// variables to use
var elm = document.getElementById('getAnimation'),
    foo = [1, 2, 3, 'a', 'b', 'c'];
// store it
setData(elm, 'fizz', foo);
// retrieve it
var bar = getData(elm, 'fizz');
// look what we have
console.log(bar); // [1, 2, 3, "a", "b", "c"] 

Requires IE 11+ because I use node.dataset, if you change this to the methods node.setAttribute, node.getAttribute and node.removeAttribute as used, the requirement drops to IE 8+ because of the JSON.stringify and JSON.parse

1
  • The JSON methods are easily supported in older browsers using the stuff from JSON.org.
    – RobG
    Commented Sep 5, 2014 at 13:17
0

That particular example is quite straight forward: It's a series of name:value pairs separated with semicolons. So you can get an array of the pairs using split, and then get the name and valid separate using split again. If you want to create properties on an object using those names and values, you can do that with bracketed notation:

// Get the value
var val = theElement.getAttribute("data-custom");

// Split it into fields on `;` (with optional whitespace on either side)
var fields = val.split(/\s*;\s*/);

// Create a blank object
var obj = {};

// Loop through the fields, creating object properties:
fields.forEach(function(field) {
    // Split the field on :, again with optional whitespace either side
    var parts = field.split(/\s*:\s*/);

    // Create a property on the object using the name, and assigning the value
    obj[parts[0]] = parts[1];
});

I'm using String#split there, giving it a regular expression to tell it where the split up the string.

In the resulting object, with just the code above, the property values will all be strings. For instance, obj.scaleX will be the string "0.75". If you need them as numbers, you can convert them to numbers in any of several ways:

  • parseFloat, which will convert as many characters as it can but ignore trailing characters. so parseFloat("0.75foo") is 0.75, not an error.

  • Number, which will not be tolerant like parseFloat, Number("0.75foo") is NaN, not 0.75.

  • Applying any mathematical operator, the unary + is common: +"0.75" is 0.75.

So rather than just grabbing the values as strings, we could check to see if they look like they might be numbers and convert them if so:

// Loop through the fields, creating object properties:
fields.forEach(function(field) {
    // Split the field on :, again with optional whitespace either side
    var parts = field.split(/\s*:\s*/);

    // Does the value look like a number?
    if (/(?:^\d+$)|(?:^\d+\.\d+$)/.test(parts[1])) {
        // Yes
        obj[parts[0]] = +parts[1];
    }
    else {
        // No
        obj[parts[0]] = parts[1];
    }
});

That assumes . as the decimal separator, and assumes there won't be a thousands separator.


Side note: Above I've used Array#forEach, which is an ES5 feature not present on older browsers. forEach can be "shimmed" on older browsers, though. You can see all sorts of ways of looping through arrays in this answer here on SO.

1
  • this is almost what i was looking for. Really its just that i am getting a bit incapable of making it work. let me try a bit more and i think i will be able to get through.. else will get back. Commented Sep 5, 2014 at 19:00

Not the answer you're looking for? Browse other questions tagged or ask your own question.