Sephr
12-22-2008, 04:21 AM
I have made an implementation of HTML 5 dataset (data-* attributes) support that almost conforms to the HTML 5 spec* and works in Firefox 1.5+, Opera 9.5+, Safari, and Google Chrome. It uses getters to simulate a psuedo-native HTML 5 dataset API. The code is licensed CC GNU LGPL. The script includes these extra functions: HTMLElement.removeDataAttribute(name), HTMLElement.setDataAttribute(name, value), and HTMLElement.setDataAttributes() (all explained below).
*You cannot set new items the standard way like HTMLElement.dataset.name = value (already existing items can though). You either have to add new items by doing HTMLElement.setDataAttribute(name, value) for single additions and HTMLElement.setDataAttributes(object full of {name, value:String} pairs) to add multiple items at once. HTMLElement.removeDataAttribute(name) removes data-name.
The script:
/* License
HTML 5 dataset Support - v1.0.0 - http://code.eligrey.com/html5/dataset/
Author: Elijah Grey - www.eligrey.com
Creative Commons GNU Lesser General Public License
http://creativecommons.org/licenses/LGPL/2.1/
*/
HTMLElement.prototype.setDataAttribute = function(name, value) {
if ( typeof(name) == 'undefined' || typeof(value) == 'undefined' ) throw new Error('NOT_ENOUGH_ARGS');
return this.setAttribute('data-'+name, value);
};
HTMLElement.prototype.removeDataAttribute = function(name) {
if ( typeof(name) == 'undefined' ) throw new Error('NOT_ENOUGH_ARGS');
return this.removeAttribute('data-'+name);
};
HTMLElement.prototype.setDataAttributes = function(items) {
if ( items instanceof Object ) {
for (i in items) {
this.setDataAttribute(i, items[i]);
}
}
};
if ( typeof(document.documentElement.dataset) == 'undefined' ) {
HTMLElement.prototype.__defineGetter__("dataset", function() {
var HTML5_dataset = {};
function returnValFunc(val) { return function(){return val} };
function dataSetterFunc(ref_el, attrName) { return function(x){ return ref_el.setDataAttribute(attrName, x) } };
for ( attr in this.attributes ) {
if ( this.attributes[attr].name && /^data-[a-z_\-\d]*$/i.test(this.attributes[attr].name) ) {
var attrName = this.attributes[attr].name.substr(5);
HTML5_dataset.__defineGetter__(attrName, returnValFunc(this.attributes[attr].value || '') );
HTML5_dataset.__defineSetter__(attrName, dataSetterFunc(this, attrName) );
}
}
return HTML5_dataset;
});
}
Example of use:
var foo = document.createElement('div');
foo.setDataAttributes({'bar':'blah', 'lorem':'Lorem ipsum.'});
foo.dataset.bar == 'blah';
foo.dataset.bar = 'Sephr';
foo.dataset.bar == 'Sephr';
foo.setDataAttribute('foobar', foo.dataset.lorem);
foo.dataset.foobar == 'Lorem ipsum.'
*You cannot set new items the standard way like HTMLElement.dataset.name = value (already existing items can though). You either have to add new items by doing HTMLElement.setDataAttribute(name, value) for single additions and HTMLElement.setDataAttributes(object full of {name, value:String} pairs) to add multiple items at once. HTMLElement.removeDataAttribute(name) removes data-name.
The script:
/* License
HTML 5 dataset Support - v1.0.0 - http://code.eligrey.com/html5/dataset/
Author: Elijah Grey - www.eligrey.com
Creative Commons GNU Lesser General Public License
http://creativecommons.org/licenses/LGPL/2.1/
*/
HTMLElement.prototype.setDataAttribute = function(name, value) {
if ( typeof(name) == 'undefined' || typeof(value) == 'undefined' ) throw new Error('NOT_ENOUGH_ARGS');
return this.setAttribute('data-'+name, value);
};
HTMLElement.prototype.removeDataAttribute = function(name) {
if ( typeof(name) == 'undefined' ) throw new Error('NOT_ENOUGH_ARGS');
return this.removeAttribute('data-'+name);
};
HTMLElement.prototype.setDataAttributes = function(items) {
if ( items instanceof Object ) {
for (i in items) {
this.setDataAttribute(i, items[i]);
}
}
};
if ( typeof(document.documentElement.dataset) == 'undefined' ) {
HTMLElement.prototype.__defineGetter__("dataset", function() {
var HTML5_dataset = {};
function returnValFunc(val) { return function(){return val} };
function dataSetterFunc(ref_el, attrName) { return function(x){ return ref_el.setDataAttribute(attrName, x) } };
for ( attr in this.attributes ) {
if ( this.attributes[attr].name && /^data-[a-z_\-\d]*$/i.test(this.attributes[attr].name) ) {
var attrName = this.attributes[attr].name.substr(5);
HTML5_dataset.__defineGetter__(attrName, returnValFunc(this.attributes[attr].value || '') );
HTML5_dataset.__defineSetter__(attrName, dataSetterFunc(this, attrName) );
}
}
return HTML5_dataset;
});
}
Example of use:
var foo = document.createElement('div');
foo.setDataAttributes({'bar':'blah', 'lorem':'Lorem ipsum.'});
foo.dataset.bar == 'blah';
foo.dataset.bar = 'Sephr';
foo.dataset.bar == 'Sephr';
foo.setDataAttribute('foobar', foo.dataset.lorem);
foo.dataset.foobar == 'Lorem ipsum.'