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 ответов:
я столкнулся с подобной "ошибкой" несколько дней назад при работе с
.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
и аксессуар для атрибуты.