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

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="" />



답변

설명서에 언급되어 .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');수행합니다.


답변

나는 심각한 문제가 있었다

.data('property', value);

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

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

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

.attr('property', value)

값을 설정하고

.attr('property')

값을 검색합니다.

이제는 작동합니다!


답변

@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을 업데이트해야하므로 일반적으로 강조 합니다. 너무.


답변

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

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

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

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

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


답변

견적을 인용하려면 :

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

.data() -jQuery 문서화

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

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

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

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

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

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

TL; DR

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


답변

언급 한 바와 같이, .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()하면 의도 된 동작에 대해 더 명확하게 알 수 있습니다.


답변

같은 문제가 있었다. .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;
};