javascript / jQuery를 사용하여 data- * 속성 목록 가져 오기


150

data-*속성 이 0 개 이상인 임의의 HTML 요소가 주어지면 데이터의 키-값 쌍 목록을 검색하는 방법이 있습니다.

예를 들면 다음과 같습니다.

<div id='prod' data-id='10' data-cat='toy' data-cid='42'>blah</div>

프로그래밍 방식으로 이것을 검색하고 싶습니다.

{ "id":10, "cat":"toy", "cid":42 }

$.data()키를 미리 알고 있으면 jQuery (v1.4.3)를 사용하여 개별 데이터 비트에 액세스하는 것이 간단하지만 임의의 데이터 세트로 어떻게 수행 할 수 있는지는 확실하지 않습니다.

'단순한'jQuery 솔루션이 있으면 찾고 있지만 그렇지 않으면 더 낮은 수준의 접근 방식을 신경 쓰지 않습니다. 파싱을 시도 $('#prod').attributes했지만 Javascript-fu가 부족하여 실망 스럽습니다.

최신 정보

customdata 는 내가 필요한 것을 수행합니다. 그러나 기능의 일부에 대해서만 jQuery 플러그인을 포함시키는 것은 과도한 것으로 보입니다.

소스를 살펴보면 내 코드를 수정하는 데 도움이되었고 Javascript-fu가 향상되었습니다.

내가 생각해 낸 해결책은 다음과 같습니다.

function getDataAttributes(node) {
    var d = {}, 
        re_dataAttr = /^data\-(.+)$/;

    $.each(node.get(0).attributes, function(index, attr) {
        if (re_dataAttr.test(attr.nodeName)) {
            var key = attr.nodeName.match(re_dataAttr)[1];
            d[key] = attr.nodeValue;
        }
    });

    return d;
}

업데이트 2

허용 된 답변에서 알 수 있듯이 솔루션은 jQuery (> = 1.4.4)로 간단합니다. $('#prod').data()필요한 데이터를 반환합니다.


"update 2"를 추가하면 jquery data ()가 일부 내부 캐시를 사용하고 data (key, value)는 DOM으로 전파되지 않으므로 많은 두통을 유발할 수 있습니다. 또한 jquery 3 data ()가 속성 data-some-thing = "test"를 {someThing : "test"}로 변환 한 이후
ETNyx

답변:


96

실제로 jQuery로 작업하는 경우 버전 기준 1.4.31.4.4 (아래 주석에 언급 된 버그로 인해) data-*속성은 다음을 통해 지원됩니다 .data().

jQuery 1.4.3부터 HTML 5 data- 속성은 자동으로 jQuery의 데이터 객체로 가져옵니다.

JavaScript 값은 연관된 값 (부울, 숫자, 객체, 배열 및 null 포함)으로 변환되는 동안 문자열은 그대로 유지됩니다. data- 속성은 더 이상 액세스하거나 (모든 데이터 값이 다음 jQuery를 내부에 저장되어있다) 돌연변이 다음 데이터 속성에 액세스 할 때 처음에 뽑아 있습니다.

jQuery.fn.data함수는 data-객체 내부의 모든 속성을 키-값 쌍으로 반환 하며, 키는 속성 이름의 일부이고 키 data-는 위에 명시된 규칙에 따라 변환 된 후 해당 속성의 값입니다.

나는 그것이 당신을 확신하지 못하면 간단한 데모를 만들었습니다 : http://jsfiddle.net/yijiang/WVfSg/


3
아니요, 이것은 1.4.3에서 깨졌습니다 . 명시 적으로 최소 1.4.4가 필요합니다.
Crescent Fresh

감사. 바로 내가 찾던 것입니다. 이전에 1.4.3으로 시도했지만 멀리 가지 않았습니다. jsfiddle 데모도 도움이되었습니다.
Shawn Chin

2
@Isc : 매우 성가신 것은 jQuery가 속성에서 찾은 값을 "직렬화 (deserialize)"하려는 시도입니다 (예 : master :) !jQuery.isNaN( data ) ? parseFloat( data ) : .... data-serial="00071134"jQuery가 숫자로 녹이는 것과 같은 속성에 제품 일련 번호가 있었으므로 71134덜 우아하게 되돌릴 수 .attr('data-serial')있었습니다 (귀하의 경우 옵션이 아님). 나는 비슷한 좌절 wrt 소리 .data()를 발굴 SO에 대한 질문을 보았다 , 하나를 파 내려고 노력할 것입니다 ...
Crescent Fresh

@CrescentFresh : 좋은 지적입니다. 분명히 내가 조심해야 할 것. 내 솔루션 ( gist.github.com/701652 )에서 jQuery <1.4.3 일 때 node.attributes 구문 분석으로 넘어갑니다. 이 문제를 염두에두고 속성을 수동으로 파싱해야합니다.
Shawn Chin

7
$.data()사용하여 저장 한 모든 항목도 반환됩니다 $.data(key, value). 실제로 마크 업에 무언가가 data- * 속성으로 저장되어 있는지 확인하려면이 방법이 최선의 선택이 아닐 수 있습니다.
Philip Walton

81

솔루션은 어렵지 않으므로 순수한 JavaScript 솔루션도 제공해야합니다.

var a = [].filter.call(el.attributes, function(at) { return /^data-/.test(at.name); });

이 속성이 오브젝트의 배열을 제공 name하고 value특성 :

if (a.length) {
    var firstAttributeName = a[0].name;
    var firstAttributeValue = a[0].value;
}

편집 : 한 단계 더 나아가려면 속성을 반복하고 데이터 객체를 채워 사전을 얻을 수 있습니다.

var data = {};
[].forEach.call(el.attributes, function(attr) {
    if (/^data-/.test(attr.name)) {
        var camelCaseName = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) {
            return $1.toUpperCase();
        });
        data[camelCaseName] = attr.value;
    }
});

그런 다음, 예를 들어, 값에 액세스 할 수 있습니다 data-my-value="2"data.myValue;

jsfiddle.net/3KFYf/33

편집 : 객체에서 프로그래밍 방식으로 요소의 데이터 속성을 설정하려면 다음을 수행하십시오.

Object.keys(data).forEach(function(key) {
    var attrName = "data-" + key.replace(/[A-Z]/g, function($0) {
        return "-" + $0.toLowerCase();
    });
    el.setAttribute(attrName, data[key]);
});

jsfiddle.net/3KFYf/34

편집 : babel 또는 TypeScript를 사용하거나 es6 브라우저 전용 코딩을 사용하는 경우 es6 화살표 기능을 사용하고 코드를 약간 단축하는 것이 좋습니다.

var a = [].filter.call(el.attributes, at => /^data-/.test(at.name));

좋은 대답입니다! 첫 번째 줄은 -jQuery처럼 문자를 대체 하지 않지만 편집 된 답변은 문자를 대체합니다 .
Timo Huovinen

@ gilly3 jsfiddle이 작동하지 않는 것 같습니다. 당신은 볼 수 있습니까?
Ethan

1
@Ethan-수정되었습니다. 알려 줘서 고마워. jsbeautifier.org의 beautify.js를 사용 하여 JSON을 인쇄했습니다. 분명히 그 링크가 깨졌습니다. 그러나 JSON.stringify()JSON 형식이 내장 된 이후로 이는 과도 했습니다.
gilly3

@ gilly3 Fantastic, 당신의 일상은 모두를 가져 오기에 좋습니다. 주어진 키에 대한 페치 데이터를 추가하고 키에 대한 수정 된 데이터를 쉽게 업데이트 할 수 있습니까? 공유 할 수 있다면 좋을 것입니다.
Ethan

@Ethan-단일 값을 얻으려면 너무 생각하지 마십시오 el.getAttribute("data-foo"). 객체를 기반으로 데이터 속성을 설정하는 방법을 보여주기 위해 답변을 업데이트했습니다.
gilly3 2019

22

여기를보세요 :

브라우저가 HTML5 JavaScript API도 지원하는 경우 다음을 사용하여 데이터를 얻을 수 있어야합니다.

var attributes = element.dataset

또는

var cat = element.dataset.cat

아, 그러나 나는 또한 읽었다 :

불행하게도, 새로운 데이터 세트 속성은 아직 그래서 그 동안은 사용하는 것이 가장 좋습니다, 모든 브라우저에서 구현되지 않은 getAttributesetAttribute이전 있듯이.

2010 년 5 월부터입니다.


어쨌든 jQuery를 사용하는 경우를 살펴해야 할 수 있습니다 CUSTOMDATA의 플러그인을. 그래도 경험이 없습니다.



고마워 펠릭스. 나는 커스텀 데이터를 발견했다. 불행히도, 그것은 필요한 것을하지 않습니다. 즉 키가 미리 알려지지 않았다면 모든 데이터를 얻습니다.
Shawn Chin

@lsc : 문서는 말한다 $("#my").customdata()당신을 주어야한다 {method: "delete", remote: "true"}... 그것은 작동해야하므로.
Felix Kling

별도의 jQuery 플러그인을 사용하는 것은 지나친 것처럼 보이지만 customdata의 소스를 보면 내 솔루션을 수정하는 데 도움이되었습니다! 작업 기능으로 답변을 수락하고 Q를 업데이트합니다.
Shawn Chin

1
@lsc : 솔루션에서 빌드하는 것이 좋습니다. 불행히도 나는 최신 jQuery 개발에 익숙하지 않다;) 왜 누군가가 나를 투표했는지 궁금해하는 이유는 ...
Felix Kling

5

위에서 언급했듯이 최신 브라우저 에는 The HTMLElement.dataset API가 있습니다.
이 API는 DOMStringMap을 제공하며 data-*간단히 수행하는 속성 목록을 검색 할 수 있습니다 .

var dataset = el.dataset; // as you asked in the question

data-속성의 키 이름을 사용하여 배열을 검색 할 수도 있습니다

var data = Object.keys(el.dataset);

또는 그 값을

Object.keys(el.dataset).map(function(key){ return el.dataset[key];});
// or the ES6 way: Object.keys(el.dataset).map(key=>{ return el.dataset[key];});

이것처럼 당신은 그것들을 반복하고 우리가 전에해야했던 것처럼 요소의 모든 속성 사이에서 필터링 할 필요없이 그것들을 사용할 수 있습니다 .


3

또는 gilly3의 탁월한 답변을 jQuery 메소드 로 변환하십시오 .

$.fn.info = function () {
    var data = {};
    [].forEach.call(this.get(0).attributes, function (attr) {
        if (/^data-/.test(attr.name)) {
            var camelCaseName = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) {
                return $1.toUpperCase();
            });
            data[camelCaseName] = attr.value;
        }
    });
    return data;
}

사용 : $('.foo').info();


2

데이터 세트 속성을 통해 데이터를 가져와야합니다.

var data = element.dataset;

데이터 셋 은 데이터 속성을 얻는 데 유용한 도구입니다


IIRC this.dataset는 아직 모든 브라우저에서 작동하지 않습니다. 그러나이 기능을 제공 하는 jquery 플러그인 이 있습니다.
Shawn Chin

1

다른 객체와 마찬가지로 데이터 속성을 반복하여 키와 값을 얻을 수 있습니다 $.each.

    $.each($('#myEl').data(), function(key, value) {
        console.log(key);
        console.log(value);
    });

1

내가 중첩 사용하십시오 각을 - 날 위해 가장 쉬운 해결책이다 (당신이 값으로 무엇을 제어 / 변화에 쉽게 "- 내 예를 들어 출력에 같은 데이터 속성 ul-list) (JQuery와 코드)

var model = $(".model");

var ul = $("<ul>").appendTo("body");

$(model).each(function(index, item) {
  ul.append($(document.createElement("li")).text($(this).text()));
  $.each($(this).data(), function(key, value) {
    ul.append($(document.createElement("strong")).text(key + ": " + value));
    ul.append($(document.createElement("br")));
  }); //inner each
  ul.append($(document.createElement("hr")));
}); // outer each

/*print html*/
var htmlString = $("ul").html();
$("code").text(htmlString);
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/prism.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/themes/prism-okaidia.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 id="demo"></h1>

<ul>
  <li class="model" data-price="45$" data-location="Italy" data-id="1234">Model 1</li>
  <li class="model" data-price="75$" data-location="Israel" data-id="4321">Model 2</li> 
  <li class="model" data-price="99$" data-location="France" data-id="1212">Model 3</li> 
</ul>

<pre>
<code class="language-html">
  
</code>
</pre>

<h2>Generate list by code</h2>
<br>

코드 펜 : https://codepen.io/ezra_siton/pen/GRgRwNw?editors=1111


0

모든 데이터 속성을 찾는 한 가지 방법은을 사용하는 것 element.attributes입니다. 을 사용 .attributes하면 문자열 "data-"가 포함 된 항목을 필터링하여 모든 요소 속성을 반복 할 수 있습니다.

let element = document.getElementById("element");

function getDataAttributes(element){
    let elementAttributes = {},
        i = 0;

    while(i < element.attributes.length){
        if(element.attributes[i].name.includes("data-")){
            elementAttributes[element.attributes[i].name] = element.attributes[i].value
        }
        i++;
    }

    return elementAttributes;

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