Looping à travers les attributs de données de l'élément

Par,

Comment faire itérer à travers tous les attributs dans un élément HTML?

Vous obtenez la solution générale:

for (var i = 0; i < elem.attributes.length; i++) { var attrib = elem.attributes[i]; if (attrib.specified) { alert(attrib.name + " = " + attrib.value); } } 

Comment rendre cette solution générale plus spécifique pour alerter uniquement les valeurs de l'attribut data.

Dois-je regex attrib.name ou y a-t-il un moyen plus simple? Voici un exemple de HTML avec 2 attributs de données:

 <div id='universals' data-path='/zz/' data-load='1'></div> 

Dans de nombreux navigateurs modernes, nous avons accès à ces attributs spéciaux via le membre .dataset sur l'objet Node . Malheureusement, ce n'est pas encore une norme acceptée et, en tant que tel, nous ne voyons pas cela adopté dans tout le spectre. Heureusement, il existe un soutien partiel dans chaque navigateur principal en ce sens que ces attributs peuvent encore être consultés à l'aide de méthodes courantes comme getAttribute , ainsi que par cyclisme sur la liste .attributes .

Le code ci-dessous présente la deuxième méthode:

 // Reference to our element var element = document.getElementById("universals"), attr; // Cycle over each attribute on the element for (var i = 0; i < element.attributes.length; i++) { // Store reference to current attr attr = element.attributes[i]; // If attribute nodeName starts with 'data-' if (/^data-/.test(attr.nodeName)) { // Log its name (minus the 'data-' part), and its value console.log( "Key: " + attr.nodeName.replace(/^data-/, ''), "Val: " + attr.nodeValue ); } } 

Fiddle: http://jsfiddle.net/pGGqf/14/

Vous devriez trouver que cette approche fonctionnera dans tous les principaux navigateurs, même dès IE6. Ceci n'est pas nécessaire, encore une fois, dans les navigateurs qui prennent en charge le membre .dataset . Il y a un peu de fonctionnalités supplémentaires offertes sur l'objet .dataset , donc vous êtes libre de détecter les fonctionnalités si vous le souhaitez:

 if (element.dataset) { // Browser supports dataset member } else { // Browser does not support dataset member } 

Si vous ne souhaitez pas utiliser regex, vous pouvez essayer

 if attrib.name.startswith('data'): //do something 

dataset support de base de dataset est très bon si vous n'avez pas besoin d'IE ci-dessous la version 11

Une simple itération "for-in" sur la propriété du jeu de données:

 var data = document.querySelector('div').dataset; for( var i in data ) console.log(i, data[i]) 
 <div data-foo='1' data-bar='2'></div> 

J'ai un concept ici qui peut fonctionner pour vous.

 var el = document.getElementById("universals"); for(var i=0;i<el.attributes.length;i++){ if((el.attributes[i].nodeName+"").indexOf("data-")>-1){ var key=(el.attributes[i].nodeName+"").substring(5); var value=el.attributes[i].value; alert(key+": "+value); } } 

C'est l'idée de base que j'ai proposée qui semble fonctionner très bien. J'ai également créé une fonction qui renvoie l'objet Nom-Valeur-Paire hors des attributs "données" de HTMLElements en utilisant cette méthode ci-dessus.

 function data2Obj(id){ var obj={}; var el=document.getElementById(id); for(var i=0;i<el.attributes.length;i++){ if((el.attributes[i].nodeName+"").indexOf("data-")>-1){ var key=(el.attributes[i].nodeName+"").substring(5); var value=el.attributes[i].value; if(value.toLowerCase()=="true")value=true; else if(value.toLowerCase()=="false")value=false; else if((parseInt(value)+"")==value)value=parseInt(value); obj[key]=value; } } return obj; } 

Cela peut être facilement modifié pour accepter une classe ou toute autre méthode de sélection de HTMLElements.

Si vous prenez le retour de cette fonction et itérez à travers l'objet, vous devriez obtenir le résultat souhaité.

 var datas = data2Obj("universal"); for(var k in datas){ alert(k+": "+datas[k]); } 
 _dataToObject = function( dataset ) { return Object.keys( dataset ).reduce( function( object, key ) { object[ key ] = dataset[ key ]; return object; }, {}); }