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.
forEach
. (Although supporting IE6 would be fairly odd these days! ButforEach
is missing on IE8, too...) IE6 isn't bothered bydata-*
attributes (as far as I'm aware, no browser is).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.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.)