| (function () { | |
| var forEach = [].forEach, | |
| regex = /^data-(.+)/, | |
| dashChar = /\-([a-z])/ig, | |
| el = document.createElement('div'), | |
| mutationSupported = false, | |
| match | |
| ; | |
| function detectMutation() { | |
| mutationSupported = true; | |
| this.removeEventListener('DOMAttrModified', detectMutation, false); | |
| } | |
| function toCamelCase(s) { | |
| return s.replace(dashChar, function (m,l) { return l.toUpperCase(); }); | |
| } | |
| function updateDataset() { | |
| var dataset = {}; | |
| forEach.call(this.attributes, function(attr) { | |
| if (match = attr.name.match(regex)) | |
| dataset[toCamelCase(match[1])] = attr.value; | |
| }); | |
| return dataset; | |
| } | |
| // only add support if the browser doesn't support data-* natively | |
| if (el.dataset != undefined) return; | |
| el.addEventListener('DOMAttrModified', detectMutation, false); | |
| el.setAttribute('foo', 'bar'); | |
| Element.prototype.__defineGetter__('dataset', mutationSupported | |
| ? function () { | |
| if (!this._datasetCache) { | |
| this._datasetCache = updateDataset.call(this); | |
| } | |
| return this._datasetCache; | |
| } | |
| : updateDataset | |
| ); | |
| document.addEventListener('DOMAttrModified', function (event) { | |
| delete event.target._datasetCache; | |
| }, false); | |
| })(); |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset=utf-8 /> | |
| <title>test data-*</title> | |
| <script src="data.js"></script> | |
| </head> | |
| <body> | |
| <p data-id="ok" data-name="remy" data-screen-name="rem" id="hello">Hello World</p> | |
| <script> | |
| var el = document.getElementById('hello'), dl = el.dataset, a = [], key; | |
| for (key in dl) a.push(key + ': ' + dl[key]); | |
| alert(a.join('\n')); | |
| a.length = 0; | |
| el.setAttribute('data-foo', 'bar'); | |
| if (el._datasetCache) alert('Houston: we have a problem!'); | |
| dl = el.dataset; | |
| for (key in dl) a.push(key + ': ' + dl[key]); | |
| alert(a.join('\n')); | |
| </script> | |
| </body> | |
| </html> |
Owner
remy
commented
miksago
commented
Is there any reason not to just use setAttribute and getAttribute (or $.attr through jQuery) ?
Owner
remy
commented
There's no reason not to, I was just coding a proof of concept to show how the final implementation would feel - though in retrospect I realised it's not a complete implementation because I don't handle el.dataset.foo = 'bar', which would then execute el.setAttribute('data-foo', 'bar').
miksago
commented
hmm, okay, well, for now I'll stick with just using setAttribute / $.attr, as that works. Not to mention
I don't see any benefit from using el.dataset.*, are there any benefits?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note that setting doesn't work - you have to set this manually on the element via setAttribute. I've not found a way yet that I can define a setter on an unknown property on an object. When the el.dataset object has a property change or updated, it should create a new attribute on the element, but we can't catch that particular update, so it's a no go.