jQuery Data () API를 사용하여 데이터 속성을 설정할 수 없습니다


131

MVC보기에 다음 필드가 있습니다.

@Html.TextBoxFor(model => model.Course.Title, new { data_helptext = "Old Text" })</span>

별도의 js 파일에서 data-helptext속성을 문자열 값 으로 설정하고 싶습니다 . 내 코드는 다음과 같습니다.

alert($(targetField).data("helptext"));

$(targetField).data("helptext", "Testing 123");

alert()호출은 경고 대화 상자의 텍스트 "올드 텍스트"를 보여주고, 잘 작동합니다. 그러나 data-helptext특성을 "Testing 123" 으로 설정하기위한 호출이 작동하지 않습니다. "오래된 텍스트"는 여전히 속성의 현재 값입니다.

data () 호출을 잘못 사용하고 있습니까? 나는 이것을 웹에서 찾았는데, 내가 뭘 잘못하고 있는지 볼 수 없다.

HTML 마크 업은 다음과 같습니다.

<input data-helptext="Old Text" id="Course_Title" name="Course.Title" type="text" value="" />

코드는 괜찮아 보입니다. 이 데모 에는 문제가 없습니다 . 어떤 버전의 jQuery를 사용하고 있습니까?
andyb

ASP NET MVC 프로젝트 템플릿과 함께 제공되는 1.5.1을 사용하고 있습니다. jQuery를 업데이트해야합니까?
Jason Evans

좋아, 그것은 jQuery의 버전이 아니다. 나는 그것이 정말로 오래된 버전 일 것이라고 생각했다. 사용중인 data () API가 v1.2.3에 추가되었습니다
andyb

마크 업을 추가해 주시겠습니까? 맞춤 HTML5 data-속성 을 사용하고 있습니까?
andyb

그 가치를 어떻게 관찰하고 있습니까? jQuery는 값을 올바르게 업데이트하지만 DOM으로 값을 다시 유지하지 않습니다. 테스트 및 설명은 아래 답변을 참조하십시오
andyb

답변:


239

설명서에 언급되어 .data()있습니다

데이터 속성은 데이터 속성에 처음 액세스 한 후 더 이상 액세스되거나 변경되지 않습니다 (모든 데이터 값은 내부적으로 jQuery에 저장 됨).

이것은 또한에 포함 된 해당 HTML 5의 데이터 - * 속성을 업데이트) jQuery를 $ .fn.data (에없는 변경 이유는 무엇입니까?

아래의 원래 답변에 대한 데모는 더 이상 작동하지 않는 것 같습니다.

업데이트 된 답변

다시, .data()문서에서

포함 된 대시가있는 속성 처리는 W3C HTML5 사양을 준수하도록 jQuery 1.6에서 변경되었습니다.

따라서 <div data-role="page"></div>다음은 사실입니다$('div').data('role') === 'page'

나는 그것이 $('div').data('data-role')과거에 일한 것이 확실 하지만 더 이상은 아닌 것 같습니다. 콘솔을 열지 않고 HTML에 기록하는 더 나은 쇼케이스를 만들었고 camelCase 데이터 속성 변환에 멀티 하이픈의 추가 예를 추가했습니다 .

업데이트 된 데모 (2015-07-25)

또한 참조 Attr의 대 jQuery를 데이터를?

HTML

<div id="changeMe" data-key="luke" data-another-key="vader"></div>
<a href="#" id="changeData"></a>
<table id="log">
    <tr><th>Setter</th><th>Getter</th><th>Result of calling getter</th><th>Notes</th></tr>
</table>

자바 스크립트 (jQuery 1.6.2+)

var $changeMe = $('#changeMe');
var $log = $('#log');

var logger;
(logger = function(setter, getter, note) {
    note = note || '';
    eval('$changeMe' + setter);
    var result = eval('$changeMe' + getter);
    $log.append('<tr><td><code>' + setter + '</code></td><td><code>' + getter + '</code></td><td>' + result + '</td><td>' + note + '</td></tr>');
})('', ".data('key')", "Initial value");

$('#changeData').click(function() {
    // set data-key to new value
    logger(".data('key', 'leia')", ".data('key')", "expect leia on jQuery node object but DOM stays as luke");
    // try and set data-key via .attr and get via some methods
    logger(".attr('data-key', 'yoda')", ".data('key')", "expect leia (still) on jQuery object but DOM now yoda");
    logger("", ".attr('key')", "expect undefined (no attr <code>key</code>)");
    logger("", ".attr('data-key')", "expect yoda in DOM and on jQuery object");

    // bonus points
    logger('', ".data('data-key')", "expect undefined (cannot get via this method)");
    logger(".data('anotherKey')", ".data('anotherKey')", "jQuery 1.6+ get multi hyphen <code>data-another-key</code>");
    logger(".data('another-key')", ".data('another-key')", "jQuery < 1.6 get multi hyphen <code>data-another-key</code> (also supported in jQuery 1.6+)");

    return false;
});

$('#changeData').click();

이전 데모


원래 답변

이 HTML의 경우 :

<div id="foo" data-helptext="bar"></div>
<a href="#" id="changeData">change data value</a>

이 JavaScript (jQuery 1.6.2 포함)

console.log($('#foo').data('helptext'));

$('#changeData').click(function() {
    $('#foo').data('helptext', 'Testing 123');
//  $('#foo').attr('data-helptext', 'Testing 123');
    console.log($('#foo').data('data-helptext'));
    return false;
});

데모보기

은 Using 크롬 DevTools로 콘솔을 DOM을 검사하려면이 $('#foo').data('helptext', 'Testing 123'); 되지 않습니다 에서 볼 수 있듯이 값 갱신 콘솔$('#foo').attr('data-helptext', 'Testing 123');수행합니다.


1
확실하지 변경,하지만 바이올린 데모 반환 크롬 콘솔에 정의되지 않은 것을
manubkk

그렇다면 두 번째 인수를 넣을 수있는 jQuery의 요점은 무엇입니까? js 변수 캐시에 저장된 값을 업데이트하려면?
ahnbizcad

@gwho 나는 당신의 질문을 완전히 이해하지 못하지만 jQuery 1.6.2를 사용하여 2011 년의 원래 답변을 참조한다고 가정합니다. 그렇다면. data('key', 'value')메소드 jQuery 캐시의 값을 업데이트하지만 성능상의 이유로 (DOM 돌연변이를 추측) DOM 자체는 업데이트되지 않습니다.
andyb

2
따라서 DOM을 업데이트하려면 수행 .attr('key','value')했는지 여부에 관계없이 수행해야합니다 .data('key', 'value'). 그것은 나에게 중복되는 것처럼 보이고, 실제 DOM이 아닌 캐시 된 DOM에 쓰려고하는 시나리오를 상상하는 데 어려움을 겪고 있습니다. 아마도 jQuery 캐시를 이해하지 못할 수도 있습니다. 방문자 .data()는 화면에서 수정 하는 모든 것을 보았을까요?
ahnbizcad

1
따라서 성능 문제 만이 아닙니다. 그들은 비교할 수 없습니다. 그것들은 완전히 다른 목적을 가지고 있으며 DOM의 다른 "버전"을 변경합니다. 따라서 ACUTAL DOM을 변경하기 위해 .attr ()을 수행해야하는 경우 .data ()를 사용하는 시점은 무엇입니까? 중복되는 것 같습니다.
ahnbizcad

34

나는 심각한 문제가 있었다

.data('property', value);

data-property속성을 설정하지 않았습니다 .

jQuery를 사용하여 시작 .attr():

일치하는 요소 세트에서 첫 번째 요소의 속성 값을 가져 오거나 일치하는 모든 요소에 대해 하나 이상의 속성을 설정하십시오.

.attr('property', value)

값을 설정하고

.attr('property')

값을 검색합니다.

이제는 작동합니다!


1
나를 위해 data ()를 사용하여 data 속성을 변경할 수 있었지만 개발자 도구에서 변경 사항이 표시되지 않았 음을 알았으므로 attr ()를 사용했습니다.
drooh

8

@andyb의 대답에는 작은 버그가 있습니다. 위의 그의 게시물에 대한 나의 의견에 더하여 ...

이 HTML의 경우 :

<div id="foo" data-helptext="bar"></div>
<a href="#" id="changeData">change data value</a>

다음과 같이 속성에 액세스해야합니다.

$('#foo').attr('data-helptext', 'Testing 123');

그러나 다음과 같은 데이터 방법 :

$('#foo').data('helptext', 'Testing 123');

.data () 메소드에 대한 위의 수정은 "정의되지 않음"을 방지하고 데이터 값이 업데이트되지만 (HTML은 그렇지 않습니다)

"data"속성의 요점은 요소와 값을 바인딩 (또는 "링크")하는 것입니다. onclick="alert('do_something')"요소에 동작을 바인딩하는 속성 과 매우 유사합니다. 텍스트는 요소를 클릭 할 때 동작을 원할 때 쓸모가 없습니다.

데이터 또는 액션이 ​​요소에 바인딩되면 일반적으로 * 응용 프로그램 (JavaScript)이 사용하는 HTML이므로 데이터 나 메서드 만 HTML을 업데이트 할 필요가 없습니다. 성능면에서는 어쨌든 HTML을 업데이트하려는 이유를 알지 못합니다 .Firebug 또는 다른 콘솔을 제외하고는 아무도 html 속성을 보지 못합니다.

당신이 그것에 대해 생각하고 싶은 한 가지 방법 : HTML (속성들과 함께)은 단지 텍스트입니다. JavaScript가 사용하는 데이터, 함수, 객체 등은 별도의 평면에 존재합니다. JavaScript가 지시 한 경우에만 HTML 텍스트를 읽거나 업데이트하지만 JavaScript로 작성한 모든 데이터 및 기능은 Firebug (또는 기타) 콘솔에 표시되는 HTML 텍스트 / 속성과 완전히 별개로 작동합니다.

* 다른 페이지에서 HTML을 새로로드 할 HTML (예 : 마이크로 형식 / 데이터 인식 텍스트 편집기)을 보존하고 내 보내야하는 경우 HTML을 업데이트해야하므로 일반적으로 강조 합니다. 너무.


감사. 이것은 잘못된 예와 함께 다른 모든 답변 중에서 도움이되었습니다! data에서이 attr('data-helptext'허용 대답 많은 표를 얻은 사람이 작동하지 않는 차이를 만든다. +1
Aleks

6

나에게도 같은 일이 일어났다. 그것은 밝혀졌다

var data = $("#myObject").data();

쓰기 불가능한 개체를 제공합니다. 나는 그것을 사용하여 그것을 해결했다 :

var data = $.extend({}, $("#myObject").data());

그 이후로 data표준 쓰기 가능한 JS 객체였습니다.


그런 다음 어떻게 씁니까?
생활을위한 작품

톰 미안 해요, 무슨 뜻 이죠 ... 수행 한 후 모르는 $.extend..., 당신이 사용할 수있는 data당신과 같이하십시오 data.name = 'Nico'; data.questionSolved = true;, 그리고 console.log(data)이 새로 추가 된 속성이 표시됩니다
니코

3

견적을 인용하려면 :

데이터 속성은 처음으로 데이터 속성에 액세스 한 후 더 이상 액세스되거나 변경되지 않습니다 (모든 데이터 값은 내부적으로 jQuery에 저장 됨).

.data() -jQuery 문서화

이 (Frankly odd ) 제한 사항은의 사용으로 만 보류됩니다 .data().

해결책? .attr대신 사용하십시오 .

물론 일부 사용자는 전용 방법을 사용하지 않으면 불편할 수 있습니다. 다음 시나리오를 고려하십시오.

  • 사용자 정의 속성의 데이터 부분이 더 이상 필요하지 않거나 대체되도록 '표준'이 업데이트됩니다.

상식-왜 그렇게 이미 설정된 속성 을 변경 합니까? 그냥 상상 class에 이름 시작 그룹id식별자 . 인터넷이 끊어 질 것입니다.

그럼에도 불구하고 Javascript 자체는이 문제를 해결할 수 있습니다. 물론 HTML과의 비 호환성에도 불구하고 REGEX (및 다양한 유사한 방법)는 속성을 새로운 신화적인 '표준'으로 빠르게 바꿀 수 있습니다.

TL; DR

alert($(targetField).attr("data-helptext"));

1

언급 한 바와 같이, .data()메소드는 실제로 data-속성 값을 설정 하지 않으며, data-속성이 변경 되면 업데이트 된 값을 읽지도 않습니다 .

내 솔루션은 .realData()실제로 속성의 현재 값에 해당 하는 메소드로 jQuery를 확장 하는 것이 었습니다.

// Alternative to .data() that updates data- attributes, and reads their current value.
(function($){
  $.fn.realData = function(name,value) {
      if (value === undefined) {
        return $(this).attr('data-'+name);
      } else {
        $(this).attr('data-'+name,value);
      }
  };
})(jQuery);

참고 : 물론을 사용할 수 .attr()는 있지만 내 경험에 따르면 대부분의 개발자 (일명 나)는 실수를 .attr()하고 .data()상호 교환 할 수 있으며 종종 생각하지 않고 다른 것으로 대체합니다. 대부분의 경우 작동하지만 특히 동적 데이터 바인딩을 처리 할 때 버그를 발생시키는 좋은 방법입니다. 따라서을 사용 .realData()하면 의도 된 동작에 대해 더 명확하게 알 수 있습니다.


0

같은 문제가 있었다. .data () 메서드를 사용하여 데이터를 가져올 수 있으므로 요소에 쓰는 방법 만 알아 내면됩니다. 이것이 내가 사용하는 도우미 방법입니다. 대부분의 사람들이 말했듯이 .attr을 사용해야합니다. 나는 그것을 알고있는 것처럼 _를 대체합니다. 나는 그것을 대체하는 다른 문자를 모른다. 그러나 나는 그것을 연구하지 않았다.

function ExtendElementData(element, object){
    //element is what you want to set data on
    //object is a hash/js-object
    var keys = Object.keys(object);
    for (var i = 0; i < keys.length; i++){
        var key = keys[i];
        $(element).attr('data-'+key.replace("_", "-"), object[key]);
    }
}

편집 : 2017 년 5 월 1 일

내장 메소드를 사용하여 올바른 데이터를 얻을 수없는 인스턴스가 여전히 있었으므로 지금 사용하는 것은 다음과 같습니다.

function setDomData(element, object){
    //object is a hash

    var keys = Object.keys(object);
    for (var i = 0; i < keys.length; i++){
        var key = keys[i];
        $(element).attr('data-'+key.replace("_", "-"), object[key]);
    }
};

function getDomData(element, key){
    var domObject = $(element).get(0);
    var attKeys = Object.keys(domObject.attributes);

    var values = null;
    if (key != null){
        values = $(element).attr('data-' + key);
    } else {
        values = {};

        var keys = [];
        for (var i = 0; i < attKeys.length; i++) {
            keys.push(domObject.attributes[attKeys[i]]);
        }

        for (var i = 0; i < keys.length; i++){
            if(!keys[i].match(/data-.*/)){
                values[keys[i]] = $(element).attr(keys[i]);
            }
        }
    }
    return values;
};
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.