Почему изменения jQuery $ .fn.data () не обновляют соответствующие атрибуты html 5 data- *? - PullRequest
33 голосов
/ 01 апреля 2011

Вот простой пример, иллюстрирующий поведение:

Учитывая эту HTML-разметку:

<div data-company="Microsoft"></div>

и этот код jQuery (с использованием jQuery 1.5.1):

// read the data
alert($("div").data("company"));
// returns Microsoft <<< OK!

// set the data
$("div").data("company","Apple");
alert($("div").data("company"));
// returns Apple <<< OK!

// attribute selector
alert($("div[data-company='Apple']").length);
// returns 0  <<< WHY???

// attribute selector again
alert($("div[data-company='Microsoft']").length);
// returns 1  <<< WHY???

// set the attribute directly
$("div").attr("data-company","Apple");
alert($("div[data-company='Apple']").length);
// now returns 1 <<< OK!

Поскольку jQuery автоматически импортирует данные HTML5 * в объект данных jQuery, разве атрибуты не должны обновляться также при изменении данных?

Ответы [ 3 ]

51 голосов
/ 01 апреля 2011

Обычно нет необходимости в циклическом перевороте .data(), если вы последовательны в использовании .data () для доступа / установки / изменения данных в элементах DOM. По этой причине имеет смысл избегать снижения производительности при обращении к DOM для каждой .data() операции установки / изменения (.data() хранит свои значения в jQuery.cache внутри).

Если вы хотите сами принудительно настроить поведение туда и обратно, вы можете подписаться на события «setData» или «changeData», а затем отправить обновление .data() в этих событиях через соответствующий элемент DOM через .attr().

17 голосов
/ 01 апреля 2011

Это правильное поведение в соответствии с документами:

Атрибуты данных извлекаются при первом обращении к свойству данных, а затем более не доступны или не изменены (все значения данных затем сохраняются внутри jQuery).

(от: http://api.jquery.com/data)

0 голосов
/ 19 февраля 2019

Селектор запросов [data-company] проверяет атрибуты, а .data не обновляет их.

Вы можете изменить код для использования только .attr('data-, избегайте .data полностью.

Вы можете установить собственную функцию, которая обновляет как данные, так и атрибуты:

// update both data and corresponding attribute 'data-x'
$.fn.attrdata = function (a, b)
{
    if (arguments.length > 1)
        this.attr('data-' + a, b);
    else if (typeof a === 'object')
        this.attr(Object.keys(a).reduce(function (obj, key)
        {
            obj['data-' + key] = a[key];
            return obj;
        }, {}));
    return this.data.apply(this, arguments);
};

Используйте вот так:

$("div").attrdata("company", "Apple");
$("div").attrdata({company: "Apple"}); // also possible
console.log($("div").data("company")); // Apple
console.log($("div").attr("data-company")); // Apple
console.log($("div[data-company='Apple']").length); // 1

Если вы не используете селекторы CSS, вы можете создать свой собственный селектор jQuery:

$.expr[':'].data = function(elem, index, match) {
  var split = match[3].split('=');
  return $(elem).data(split[0]) == split[1];
};

Используйте вот так:

$("div").attr("data-company", "Microsoft");
$("div").data("company", "Apple");
console.log($('div:data(company=Apple)').length); // 1
console.log($('div[data-company="Apple"]').length); // 0

https://jsfiddle.net/oriadam/a14jvqcw/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...