jQuery.data () не работает, но.м() не


Простите меня за то, что я не был более конкретным по этому поводу. У меня такая странная ошибка. После загрузки документа я зацикливаю некоторые элементы, которые изначально имеют data-itemname="", и я устанавливаю эти значения с помощью .attr("data-itemname", "someValue").

вопрос: когда я петлю через эти элементы, если я делаю elem.data().itemname, Я "", но если я это сделаю elem.attr("data-itemname"), Я "someValue". Это как у jQuery .data() getter получает только элементы, которые изначально содержат некоторое значение, но если они изначально пусты, а затем установлены, то .data() не получает значение позже.

я пытался воссоздать эту ошибку, но не смог.

Edit

я воссоздал ошибку! http://jsbin.com/ihuhep/edit#javascript, html, live

кроме того, фрагменты из ссылки выше...

JS:

var theaters = [
    { name: "theater A", theaterId: 5 },
    { name: "theater B", theaterId: 17 }
];

$("#theaters").html(
    $("#theaterTmpl").render(theaters)
);

// DOES NOT WORK - .data("name", "val") does NOT set the val
var theaterA = $("[data-theaterid='5']");
theaterA.find(".someLink").data("tofilllater", "theater5link"); // this does NOT set data-tofilllater
$(".someLink[data-tofilllater='theater5link']").html("changed link text"); // never gets changed

// WORKS - .attr("data-name", "val") DOES set val
var theaterB = $("[data-theaterid='17']");
theaterB.find(".someLink").attr("data-tofilllater", "theater17link"); // this does set data-tofilllater
$(".someLink[data-tofilllater='theater17link']").html("changed link text");

HTML:

<body>
    <div id="theaters"></div>
</body>

<script id="theaterTmpl" type="text/x-jquery-tmpl">
    <div class="theater" data-theaterid="{{=theaterId}}">
        <h2>{{=name}}</h2>
        <a href="#" class="someLink" data-tofilllater="">need to change this text</a>
    </div>
</script>
6 86

6 ответов:

я столкнулся с подобной "ошибкой" несколько дней назад при работе с .data() и .attr('data-name') для атрибутов данных HTML5.

поведение, которое вы описываете, не является ошибкой, но по дизайну.

The .data() вызов является специальным-он не только извлекает атрибуты данных HTML5, но также пытается оценить/проанализировать атрибуты. Так что с атрибутом, как data-myjson='{"hello":"world"}' при извлечении через .data() возвращает Object во время получения через .attr() вернет строку. см. Пример jsfiddle.

С .data() делает ли дополнительная обработка jQuery хранит результаты оценки атрибутов в $.cache - в конце концов, как только атрибут данных был оценен, было бы расточительно переоценивать каждый .data() вызов-тем более, что переменные данных могут содержать сложные строки JSON.

я сказал Все это, чтобы сказать следующее:после получения атрибута через .data() любые изменения, сделанные .attr('data-myvar', '') не будет видно последующие .data() звонки.проверьте это на jsfiddle.

чтобы избежать этой проблемы не перемешиваться .data и .attr() звонки. используйте один или другой.

это потому, что имя атрибута data-itemname. Вы не можете использовать - в стенографии obj.attribute обозначение (obj.data-itemname будет intepreted как " obj.данные минус имя").

почему бы вам просто не использовать .data() везде?

вы также можете объявить значения по умолчанию встроенные в HTML, что тоже хорошо.

<span data-code="pony">text</span>

и

$("span").data("code") == "pony" // true

если вы хотите изменить его, вы просто сделать

$("span").data("code", "not-a-pony");

и чтобы удалить его полностью, вы можете вызвать

$("span").removeData("code");

вы должны действительно попытаться избежать использования .attr("data-*"), Я не знаю, почему вы хотите сделать это в любом случае.

вы должны установить данные с помощью .data('itemname', 'someValue');. Используя .attr() установить атрибуты данных не получится:http://jsfiddle.net/ThiefMaster/YHsKx/

, вы можете обеспечить встроенные значения с помощью, например,<div data-key="value"> в разметке.

.attr("data-itemname", "someValue") изменяет DOM.

.data("itemname", "someValue") изменяет кэш jQuery.

чтобы заставить это работать в следующем Javascript и, кроме того, в CSS, вы должны установить оба.

theaterA.find(".someLink").attr("data-itemname", "someValue");
theaterA.find(".someLink").data("itemname", "someValue");

это результат недоразумения:data не является аксессуаром для data-* атрибуты. Это и больше и меньше.

data является средством доступа для кэша данных jQuery на элементе. Это кэш инициализации С data-* атрибуты, если они есть, но data никогда пишет к атрибутам, и изменение атрибута не изменяет кэш данных после инициализация.

data также массажирует то, что он находит различными способами, угадывая типы данных, делая data("foo") на элемент data-foo="1" число, а не строка или даже разбор вещей как JSON, если они выглядят правильно:

console.log(typeof $("[data-foo]").data("foo"));
console.log(typeof $("[data-bar]").data("bar"));
<div data-foo="1"></div>
<div data-bar='{"answer":42}'></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

если вы хотите использовать атрибуты (как чтение, так и установка их), используйте attr, а не data. attrи аксессуар для атрибуты.