it-swarm.com.ru

Получить список атрибутов data- *, используя javascript/jQuery

Имея произвольный элемент HTML с нулевым или большим количеством атрибутов data-*, как можно получить список пар ключ-значение для данных.

Например. учитывая это:

<div id='prod' data-id='10' data-cat='toy' data-cid='42'>blah</div>

Я хотел бы иметь возможность программно получить это:

{ "id":10, "cat":"toy", "cid":42 }

Используя jQuery (v1.4.3), получить доступ к отдельным битам данных с помощью $.data() просто, если ключи известны заранее, но не очевидно, как это можно сделать с произвольными наборами данных.

Я ищу «простое» решение jQuery, если оно существует, но в противном случае не возражает против подхода более низкого уровня. Я попытался разобрать $('#prod').attributes, но отсутствие javascript-fu подводит меня.

Обновление

customdata делает то, что мне нужно. Тем не менее, включение плагина jQuery только для небольшой части его функциональности показалось излишним. 

Изучение исходного кода помогло мне исправить мой собственный код (и улучшил мой javascript-fu).

Вот решение, которое я придумал:

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

обновление 2

Как показано в принятом ответе, решение тривиально с jQuery (> = 1.4.4). $('#prod').data() вернет требуемые данные dict.

139
Shawn Chin

На самом деле, если вы работаете с JQuery, начиная с версии 1.4.3 1.4.4 (из-за ошибки, упомянутой в комментариях ниже), атрибуты data-* поддерживаются через .data()

Начиная с jQuery 1.4.3 HTML 5 data- атрибуты будут автоматически втянул в объект данных jQuery.

Обратите внимание, что строки остаются нетронутыми в то время как значения JavaScript конвертируются к их связанному значению (это включает логические значения, числа, объекты, массивы и ноль). data- атрибуты вытягиваются в первый время доступа к свойству данных и тогда больше не доступны и не видоизменены (все значения данных затем сохраняются внутри в jQuery).

Функция jQuery.fn.data будет возвращать все атрибуты data- внутри объекта в виде пар ключ-значение, причем ключ является частью имени атрибута после data-, а значение является значением этого атрибута после преобразования в соответствии с правилами, указанными выше. 

Я также создал простую демонстрацию, если это не убедит вас: http://jsfiddle.net/yijiang/WVfSg/

92
Yi Jiang

Также должно быть предложено чистое решение JavaScript, поскольку решение не сложное:

var a = [].filter.call(el.attributes, function(at) { return /^data-/.test(at.name); });

Это дает массив объектов атрибутов, которые имеют свойства name и value:

if (a.length) {
    var firstAttributeName = a[0].name;
    var firstAttributeValue = a[0].value;
}

Edit: Чтобы продвинуться дальше, вы можете получить словарь, перебирая атрибуты и заполняя объект данных:

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

Затем вы можете получить доступ к значению, например, data-my-value="2" как data.myValue;

jsfiddle.net/3KFYf/33

Edit: Если вы хотите программно установить атрибуты данных для вашего элемента из объекта, вы можете:

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: Если вы используете babel или TypeScript или кодируете только для браузеров es6, это хорошее место, чтобы использовать функции стрелок es6 и немного сократить код:

var a = [].filter.call(el.attributes, at => /^data-/.test(at.name));
75
gilly3

Посмотрите здесь :

Если браузер также поддерживает HTML5 JavaScript API, вы сможете получить данные с помощью:

var attributes = element.dataset

или же

var cat = element.dataset.cat

О, но я также читаю:

К сожалению, новое свойство набора данных еще не реализовано ни в одном браузере, поэтому в настоящее время лучше использовать getAttribute и setAttribute, как показано ранее.

Это с мая 2010 года.


Если вы все равно используете jQuery, возможно, вы захотите взглянуть на customdata plugin. У меня нет опыта с этим, хотя.

18
Felix Kling

Как упомянуто выше современные браузеры имеют HTMLElement.dataset API.
Этот API предоставляет вам DOMStringMap , и вы можете получить список атрибутов data-*, просто выполнив:

var dataset = el.dataset; // as you asked in the question

вы также можете получить массив с именами ключей свойства data-, такими как

var data = Object.keys(el.dataset);

или сопоставьте его значения

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

и таким образом вы можете выполнять их итерацию и использовать их без необходимости фильтрации между всеми атрибутами элемента как мы должны были это сделать раньше .

5
Sergio

или преобразовать отличный ответ gilly3 в метод 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;
}

Использование: $('.foo').info();

3
PHPst

Вы должны получить данные через атрибуты набора данных

var data = element.dataset;

набор данных полезный инструмент для получения атрибута данных

2
lychi

Один из способов найти все атрибуты данных - использовать element.attributes . Используя .attributes, вы можете перебрать все атрибуты элемента, отфильтровывая элементы, которые включают строку «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

Вы можете просто перебрать атрибуты данных, как и любой другой объект, чтобы получить ключи и значения, вот как это сделать с $.each:

    $.each($('#myEl').data(), function(key, value) {
        console.log(key);
        console.log(value);
    });
0
Andrew