Étant donné un élément HTML arbitraire avec zéro ou plus d'attributs data-*
, comment peut-on extraire une liste de paires clé-valeur pour les données.
Par exemple. étant donné ceci:
<div id='prod' data-id='10' data-cat='toy' data-cid='42'>blah</div>
J'aimerais pouvoir récupérer ceci par programme:
{ "id":10, "cat":"toy", "cid":42 }
Avec jQuery (v1.4.3), accéder aux bits de données individuels à l’aide de $.data()
est simple si les clés sont connues à l’avance, mais il n’est pas évident de pouvoir le faire avec des ensembles de données arbitraires.
Je cherche une solution «simple» jQuery s'il en existe une, mais je ne verrais pas d'inconvénient à une approche de niveau inférieur. J'essayais d'analyser $('#prod').attributes
mais mon manque de javascript-fu me laisse tomber.
customdata fait ce dont j'ai besoin. Cependant, inclure un plugin jQuery juste pour une fraction de ses fonctionnalités semblait être une overkill.
La source oculaire m'a aidé à réparer mon propre code (et à améliorer mon javascript-fu).
Voici la solution que j'ai trouvée:
function getDataAttributes(node) {
var d = {},
re_dataAttr = /^data\-(.+)$/;
$.each(node.get(0).attributes, function(index, attr) {
if (re_dataAttr.test(attr.nodeName)) {
var key = attr.nodeName.match(re_dataAttr)[1];
d[key] = attr.nodeValue;
}
});
return d;
}
Comme démontré dans la réponse acceptée, la solution est triviale avec jQuery (> = 1.4.4). $('#prod').data()
renverrait le fichier de données requis.
En fait, si vous travaillez avec jQuery, à partir de la version 1.4.3 1.4.4 (à cause du bogue mentionné dans les commentaires ci-dessous), les attributs data-*
sont supportés via .data()
:
À partir de jQuery 1.4.3 HTML 5
data-
les attributs seront automatiquement tiré dans l'objet de données de jQuery.Notez que les chaînes sont laissées intactes alors que les valeurs JavaScript sont converties à leur valeur associée (ceci inclut les booléens, les nombres, les objets, les tableaux et null). Le
data-
les attributs sont tirés dans le premier l'heure à laquelle la propriété data est accédée et alors ne sont plus accédés ni mutés (Toutes les valeurs de données sont ensuite stockées en interne dans jQuery).
La fonction jQuery.fn.data
renverra l'intégralité de l'attribut data-
à l'intérieur d'un objet sous forme de paires clé-valeur, la clé étant la partie du nom d'attribut après data-
et la valeur étant la valeur de cet attribut après avoir été convertie conformément aux règles énoncées ci-dessus.
J'ai également créé une simple démo si cela ne vous convainc pas: http://jsfiddle.net/yijiang/WVfSg/
Une solution JavaScript pure devrait également être proposée, car la solution n’est pas difficile:
var a = [].filter.call(el.attributes, function(at) { return /^data-/.test(at.name); });
Cela donne un tableau d'objets d'attributs, qui ont les propriétés name
et value
:
if (a.length) {
var firstAttributeName = a[0].name;
var firstAttributeValue = a[0].value;
}
Edit: Pour aller plus loin, vous pouvez obtenir un dictionnaire en itérant les attributs et en renseignant un objet de données:
var data = {};
[].forEach.call(el.attributes, function(attr) {
if (/^data-/.test(attr.name)) {
var camelCaseName = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) {
return $1.toUpperCase();
});
data[camelCaseName] = attr.value;
}
});
Vous pouvez ensuite accéder à la valeur de, par exemple, data-my-value="2"
sous la forme data.myValue
;
Edit: Si vous souhaitez définir des attributs de données sur votre élément par programmation à partir d'un objet, vous pouvez:
Object.keys(data).forEach(function(key) {
var attrName = "data-" + key.replace(/[A-Z]/g, function($0) {
return "-" + $0.toLowerCase();
});
el.setAttribute(attrName, data[key]);
});
EDIT: Si vous utilisez babel ou TypeScript, ou codez uniquement pour les navigateurs es6, c’est un bon endroit pour utiliser les fonctions fléchées es6 et raccourcir un peu le code:
var a = [].filter.call(el.attributes, at => /^data-/.test(at.name));
Si le navigateur prend également en charge l’API JavaScript HTML5, vous devriez pouvoir obtenir les données avec:
var attributes = element.dataset
ou
var cat = element.dataset.cat
Oh, mais j'ai aussi lu:
Malheureusement, la nouvelle propriété dataset n’a encore été implémentée dans aucun navigateur. Par conséquent, il est préférable d’utiliser
getAttribute
etsetAttribute
comme indiqué précédemment.
C'est à partir de mai 2010.
Si vous utilisez quand même jQuery, vous voudrez peut-être jeter un coup d'œil au customdata plugin. Je n'ai aucune expérience avec cela cependant.
Comme mentionné ci-dessus les navigateurs modernes ont le The HTMLElement.dataset API.
Cette API vous donne un DOMStringMap , et vous pouvez récupérer la liste des attributs data-*
simplement en faisant:
var dataset = el.dataset; // as you asked in the question
vous pouvez également récupérer un tableau avec les noms de clé de la propriété data-
comme
var data = Object.keys(el.dataset);
ou cartographier ses valeurs par
Object.keys(el.dataset).map(function(key){ return el.dataset[key];});
// or the ES6 way: Object.keys(el.dataset).map(key=>{ return el.dataset[key];});
et comme cela, vous pouvez les parcourir et les utiliser sans avoir besoin de filtrer tous les attributs de l'élément comme nous devions le faire auparavant .
ou convertissez l'excellente réponse de gilly3
en méthode jQuery:
$.fn.info = function () {
var data = {};
[].forEach.call(this.get(0).attributes, function (attr) {
if (/^data-/.test(attr.name)) {
var camelCaseName = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) {
return $1.toUpperCase();
});
data[camelCaseName] = attr.value;
}
});
return data;
}
Utilisation de: $('.foo').info()
;
Vous devriez obtenir les données via les attributs du jeu de données
var data = element.dataset;
dataset est un outil utile pour obtenir l'attribut data
Un moyen de trouver tous les attributs de données consiste à utiliser element.attributes
. En utilisant .attributes
, vous pouvez parcourir tous les attributs d'élément en filtrant les éléments contenant la chaîne "data-".
let element = document.getElementById("element");
function getDataAttributes(element){
let elementAttributes = {},
i = 0;
while(i < element.attributes.length){
if(element.attributes[i].name.includes("data-")){
elementAttributes[element.attributes[i].name] = element.attributes[i].value
}
i++;
}
return elementAttributes;
}
Vous pouvez simplement parcourir les attributs de données comme n'importe quel autre objet pour obtenir des clés et des valeurs, voici comment procéder avec $.each
:
$.each($('#myEl').data(), function(key, value) {
console.log(key);
console.log(value);
});