jQuery .data ()는 작동하지 않지만 .attr ()은 작동합니다.


107

이것에 대해 더 구체적이지 않은 것을 용서하십시오. 이상한 버그가 있습니다. 다큐먼트로드 후, 루프 일부 요소 원래 가지고 그 data-itemname="", 내가 사용하여 그 값을 설정합니다 .attr("data-itemname", "someValue").

문제 : 나중에 이러한 요소를 반복 할 때,하면을 elem.data().itemname얻지 ""elem.attr("data-itemname"),하면 "someValue". jQuery의 .data()getter는 처음에 일부 값을 포함하도록 설정된 요소 만 가져 오지만 원래 비어 있었다가 나중에 설정되면 .data()나중에 값을 가져 오지 않는 것과 같습니다.

이 버그를 재현하려고 시도했지만 할 수 없었습니다.

편집하다

버그를 재현했습니다! 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>

4
버그를 재현하기 위해 더 열심히 노력하십시오 :-)
dkamins

1
그렇지 않습니다 elem.data("itemname")하지 elem.data().itemname?
Hogan 2012 년

elem.data (). itemname을 사용하면 값을 읽을 수 있지만 값을 설정할 수 없습니다. (따라서, elem.data().itemname = somevalue;기본 데이터를 변경하지 않는다.)
호건

@dkamins-버그를 재현했습니다. 편집 된 버전을 참조하십시오.
Ian Davis

답변:


210

작업 할 때 나는 며칠 전 비슷한 "버그"로 실행 .data().attr('data-name')HTML5 데이터 속성에 대해.

설명하는 동작은 버그가 아니라 의도적으로 설계된 것입니다.

.data()호출은 특별하다 -뿐만 아니라 그것은 HTML5 데이터를 검색 않습니다 그것은 또한 / 평가 속성을 구문 분석하는 시도를 속성. data-myjson='{"hello":"world"}'따라서을 통해 검색 될 때 와 같은 속성을 사용 .data()하면 Objectwhile 검색을 통해 .attr()문자열을 반환합니다. jsfiddle 예제를 참조하십시오.

이후 .data()에 추가 처리 jQuery를 저장에게 속성 평가 결과를 수행 $.cache- 데이터 속성을 평가하고 나면 결국, 그것은 낭비입니다마다에 다시 평가.data() 전화 - 데이터 변수가 복잡한 JSON 문자열을 포함 할 수 있습니다 특히 때문이다.

나는 다음과 같이 모든 것을 말했다.에 의해 변경된 속성을 통해 속성을 검색 한 후에 는 후속 호출에서 볼 수 없습니다 . .data().attr('data-myvar', '').data() jsfiddle에서 이것을 테스트하십시오.

이 문제를 피하기 위해 혼용 .data.attr()통화 하지 마십시오 . 둘 중 하나를 사용하십시오.


이것을 답변으로 표시합니다. .data () 대 .attr ()의 모든 가능한 시나리오에 대해서는이 테스트를 참조하십시오. 여기에는 각각을 사용하여 가져 오기 및 설정하고 설정 한 후 선택기 길이를 출력하는 것이 포함됩니다. jsbin.com/acegef/edit# javascript, html, live
Ian Davis

9
적어도 이것은 분명히 비 직관적 인 동작을 설명합니다 ... 이것은 타사 라이브러리를 사용하고 일부는 data () 만 사용하고 다른 일부는 실제 속성을 변경할 때 약간의 두통을 유발할 수 있습니다.
Haroldo_OK 2013-10-11

1
@leepowers, ".data ()를 통해 속성을 검색 한 후 .attr ( 'data-myvar', '')에 의한 변경 사항은 후속 .data () 호출에서 볼 수 없습니다", 이것이 실제로 cache ( $ .cache), 그러면 좋지 않은 것 같습니다! 캐시에 맹목적으로 의존하는 대신, 후속 .data () 호출은 값이 지금 비어 있는지 또는 문자열 길이가 변경되었는지 (캐시와 현재 값이 일치)와 같은 몇 가지 기본적인 check ()를 수행 할 수 있습니다.
minhajul

1
데이터 ( 'id', val) 설정 시도는 값이 더 일찍 검색되지 않은 경우에도 실패합니다 ... Jquery에 의한 data () 함수의 훌륭한 디자인.
andreszs

3
그래서 몇 시간 동안 저를 잡고있는 것은 data () 캐시입니다. 아무리 값을 변경해도 여전히 동일한 값을 반환하는 이유는 당연합니다. 감사합니다.
Lynnell Emmanuel Neri

17

이것은 오해의 결과입니다 : 속성에 data대한 접근자가 아닙니다data-* . 그것은 그보다 더 많고 적습니다.

data요소에 대한 jQuery의 데이터 캐시에 대한 접근 자입니다. 그 캐시가되어 초기화 에서 data-*이 어떤 존재하지만 경우 속성 data결코 기록하지 속성으로도 초기화 후 속성 변경을 데이터 캐시를 변경하지 :

const div = $("[data-example]");
console.log('div.data("example"):', div.data("example"));
console.log('div.attr("data-example"):', div.attr("data-example"));
console.log('Using div.data("example", "updated")');
div.data("example", "updated");
console.log('div.data("example"):', div.data("example"));
console.log('div.attr("data-example"):', div.attr("data-example"));
<div data-example="initial value"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

data또한 데이터 유형을 추측 하고 문자열이 아닌 숫자 data("answer")로 요소를 만들 data-answer="42"거나 JSON처럼 보이는 경우 JSON으로 구문 분석하는 등 다양한 방법으로 찾은 내용을 마사지합니다 .

console.log(typeof $("[data-answer]").data("answer"));
console.log(typeof $("[data-json]").data("json"));
console.log(typeof $("[data-str]").data("str"));
<div data-answer="42"></div>
<div data-json='{"answer":42}'></div>
<div data-str="example"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

이 속성을 사용하려면 (모두 읽기 및 설정), 사용을 attr하지 data. attr 속성에 대한 접근.


6

속성의 이름이 data-itemname. -축약 obj.attribute표기법 으로는 사용할 수 없습니다 (obj.data-itemname은 "obj.data minus itemname"로 해석 됨).


누가 그래? 링크를 제공 할 수 있습니까?
jahrichie 2015

6

.attr("data-itemname", "someValue") DOM을 수정합니다.

.data("itemname", "someValue") jQuery 캐시를 수정합니다.

이 작업을 다음 Javascript와 CSS에 추가하여 두 가지를 모두 설정해야합니다.

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

4

그냥 사용하지 그래 .data() 어디서나 않습니까?

HTML에서 기본값을 인라인으로 선언 할 수도 있습니다.

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

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

변경하고 싶다면 그냥

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

모두 제거하려면 호출 할 수 있습니다.

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

당신은 정말로 사용을 시도하고 피해야합니다 .attr("data-*"). 나는 당신이 어쨌든 그렇게하고 싶어하는 이유를 모르겠습니다.


S /해야 / 필수, 사용 .attr('data-*', ...)에 대한 데이터를 표시하지 않습니다.data()
ThiefMaster

하지만 jQuery 없이 해야하는 방식으로 attr ()을 사용하지 않습니까? (getAttribute tho 사용)
powerbuoy

당신이 jQuery를이없는 경우 사용 getAttribute()하고 setAttribute()- 두 가지 방법이 실제 속성에 액세스 할 수 있도록 그것은 다시 작동합니다. 또는 dataSet최신 브라우저가 제공 하는 속성을 사용하면 됩니다.
ThiefMaster

1
그런 요소를 선택하지 마십시오. 문서의 모든 요소 를 반복해야하기 때문에 매우 비효율적 입니다. class브라우저에는 특정 클래스의 요소를 가져 오는 기본 함수가 있으므로 대신를 사용하십시오 .
ThiefMaster

1
하지만 "555"는 데이터이므로 data () 로직을 사용해야합니다. 그 데이터를 클래스 이름에 넣는 것은 데이터를 프레젠테이션과 혼합하는 것입니다. 다른 방법으로 생각합니다.
Ian Davis 2012 년

1

를 사용하여 데이터를 설정해야합니다 .data('itemname', 'someValue');. 사용 .attr()설정 데이터 속성하지 않습니다 작업에 : http://jsfiddle.net/ThiefMaster/YHsKx/

그러나 마크 업에서 예 를 사용하여 인라인 값을 제공 할 수 있습니다<div data-key="value"> .


jsfiddle에서 두 세트를 모두 수행하면 get이 작동합니다. 따라서 attr ( "data-itemname", "value")는 작동합니다. Chrome을 사용하고 있습니다.
이안 데이비스

@Ian 어, 아니. .data()그동안 호출, 속성을 설정 .attr()전화는 아무것도하지 않습니다.
bevacqua 2012 년

@IanDavis : "set attr"을 클릭하면 "get"이 빈 개체를 제공합니다. "데이터 설정"만 작동합니다.
ThiefMaster

@Nico-정확히 내가 한 일입니다. (1) "set attr"버튼을 클릭 한 다음 (2) "get"버튼을 클릭합니다. 이것이 일어난 일입니다. "{"test ":"meow "}"라고 경고했습니다. 따라서 .attr ()은 속성을 설정합니다. 그렇지 않으면 경고가 비어있을 것입니다. 이 정확한 단계를 따르면 다른 결과를 얻습니까? 감사.
Ian Davis

1
@ThiefMaster - 내 제공되는 코드의 theaterA에, 내가 사용하지 않는 .attr()전혀 만 .data(), 그리고, 선택의 길이는 $(".someLink[data-tofilllater='theater5link']")제로입니다. 내가 사용이 같은 그건 .attr(): /
이안 데이비스

0

이로 인해 데이터 속성 설정에 접근하는 방법에 대한 일부 구분이 발생했음을 알 수 있습니다.

나도이 문제에 부딪 혔고 문제가 단순히 데이터 속성 이름 형식화 인 것처럼 보였습니다 .

내 경험상 데이터 변수 ( " data- " 뒤에 오는 변수 이름)에 하이픈을 사용하지 않아야합니다 .

이것은 나를 위해 작동하지 않았습니다.

[마크 업]

<div class="list" id="myElement1" data-item-order="some-value"> .... </div>

[jQuery]

jQuery("#myElement1").data("item-order", "my-new-value");

그러나 다음은 잘 작동했습니다! :) :

(필요한 경우 하이픈 대신 밑줄을 사용합니다)

[마크 업]

<div class="list" id="myElement1" data-item_order="some-value"> .... </div>

[jQuery]

jQuery("#myElement1").data("item_order", "my-new-value");

도움이되기를 바랍니다. 모두 건배!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.