web-dev-qa-db-fra.com

Obtenir la liste des attributs data- * en utilisant javascript/jQuery

É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.

mettre à jour

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;
}

mise à jour 2

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.

139
Shawn Chin

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/

92
Yi Jiang

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;

jsfiddle.net/3KFYf/33

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]);
});

jsfiddle.net/3KFYf/34

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));
75
gilly3

Regardez ici :

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 et setAttribute 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.

18
Felix Kling

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 .

5
Sergio

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();

3
PHPst

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

2
lychi

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;

}
0
Jmorel88

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);
    });
0
Andrew