[javascript] 맞춤 속성-예 또는 아니요?

최근에 나는 주로 자바 스크립트 코드에 사용하기 위해 약간의 추가 데이터 비트를 포함하기 위해 HTML 태그에 사용자 정의 속성을 사용하는 사람들에 대해 점점 더 많이 읽었습니다.

사용자 지정 특성을 사용하는 것이 좋은지 여부와 일부 대안이 무엇인지에 대한 피드백을 수집하기를 희망했습니다.

서버 측과 클라이언트 측 코드를 모두 단순화 할 수있는 것처럼 보이지만 W3C와 호환되지 않습니다.

웹앱에서 사용자 정의 HTML 속성을 사용해야합니까? 그 이유는 무엇?

커스텀 속성이 좋은 것이라고 생각하는 사람들을 위해 : 그것들을 사용할 때 명심해야 할 것은 무엇입니까?

커스텀 속성이 좋지 않다고 생각하는 사람들에게 : 비슷한 것을 달성하기 위해 어떤 대안을 사용하십니까?

업데이트 : 내가 주로에 관심이 추론 하나 개의 방법이 다른 것보다 더 나은 이유에 대한 다양한 방법의 뒤에뿐만 아니라 포인트. 나는 우리 모두가 같은 것을 성취하기 위해 4-5 가지 다른 방법을 생각해 낼 수 있다고 생각합니다. (숨겨진 요소, 인라인 스크립트, 추가 클래스, ID의 구문 분석 정보 등).

업데이트 2 : HTML 5 data-속성 기능은 여기에서 많은 지원을하는 것으로 보입니다 (그리고 나는 확실한 옵션처럼 보입니다). 지금까지 나는이 제안에 대한 반박의 방식을 많이 보지 못했다. 이 방법을 사용할 때 걱정할만한 문제가 있습니까? 아니면 단순히 현재 W3C 사양의 ‘무해한’무효화입니까?



답변

HTML 5는로 시작하는 맞춤 속성을 명시 적으로 허용합니다 data. 예를 들어 <p data-date-changed="Jan 24 5:23 p.m.">Hello</p>유효합니다. 표준에서 공식적으로 지원되기 때문에 이것이 사용자 정의 속성에 가장 적합한 옵션이라고 생각합니다. 또한 다른 속성을 해킹으로 과부하시키지 않아도 HTML이 의미를 유지할 수 있습니다.

출처 : http://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes


답변

최근에 사용한 기술이 있습니다.

<div id="someelement">

    <!-- {
        someRandomData: {a:1,b:2},
        someString: "Foo"
    } -->

    <div>... other regular content...</div>
</div>

comment-object는 부모 요소 (예 : #someelement)에 연결됩니다.

파서는 다음과 같습니다. http://pastie.org/511358

특정 요소에 대한 데이터를 얻으려면 parseData유일한 인수로 전달 된 해당 요소에 대한 참조로 호출 하십시오.

var myElem = document.getElementById('someelement');

var data = parseData( myElem );

data.someRandomData.a; // <= Access the object staight away

그보다 더 간결 할 수 있습니다.

<li id="foo">
    <!--{specialID:245}-->
    ... content ...
</li>

액세스 :

parseData( document.getElementById('foo') ).specialID; // <= 245

이것을 사용하는 유일한 단점은 자체 폐쇄 요소 (예 :)와 함께 사용할 수 없다는 점입니다 <img/>. 주석은 해당 요소의 데이터로 간주 될 요소 내에 있어야 하기 때문입니다.


편집 :

이 기술의 주목할만한 이점 :

  • 손쉬운 구현
  • 합니까 하지 무효화 HTML / XHTML
  • 사용하기 쉽고 이해하기 (기본 JSON 표기법)
  • 대부분의 대안보다 눈에 거슬리지 않고 의미 론적으로 깨끗합니다.

파서 코드는 다음과 같습니다 ( pastie.org에서 사용할 수없는 경우 http://pastie.org/511358 하이퍼 링크 에서 복사 ).

var parseData = (function(){

    var getAllComments = function(context) {

            var ret = [],
                node = context.firstChild;

            if (!node) { return ret; }

            do {
                if (node.nodeType === 8) {
                    ret[ret.length] = node;
                }
                if (node.nodeType === 1) {
                    ret = ret.concat( getAllComments(node) );
                }
            } while( node = node.nextSibling );

            return ret;

        },
        cache = [0],
        expando = 'data' + +new Date(),
        data = function(node) {

            var cacheIndex = node[expando],
                nextCacheIndex = cache.length;

            if(!cacheIndex) {
                cacheIndex = node[expando] = nextCacheIndex;
                cache[cacheIndex] = {};
            }

            return cache[cacheIndex];

        };

    return function(context) {

        context = context || document.documentElement;

        if ( data(context) && data(context).commentJSON ) {
            return data(context).commentJSON;
        }

        var comments = getAllComments(context),
            len = comments.length,
            comment, cData;

        while (len--) {
            comment = comments[len];
            cData = comment.data.replace(/\n|\r\n/g, '');
            if ( /^\s*?\{.+\}\s*?$/.test(cData) ) {
                try {
                    data(comment.parentNode).commentJSON =
                        (new Function('return ' + cData + ';'))();
                } catch(e) {}
            }
        }

        return data(context).commentJSON || true;

    };

})();


답변

페이지의 스키마를 지정하면 모든 속성을 작성할 수 있습니다.

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

이거 추가 해봐

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:addthis="http://www.addthis.com/help/api-spec">
...
<a addthis:title="" addthis:url="" ...>

페이스 북 (태그 포함)

<html xmlns:og="http://opengraphprotocol.org/schema/" xmlns:fb="http://www.facebook.com/2008/fbml">
...
<fb:like href="http://developers.facebook.com/" width="450" height="80"/>


답변

사용자 정의 속성을 사용하지 않는 가장 쉬운 방법은 기존 속성을 사용하는 것입니다.

의미 있고 관련성이 높은 클래스 이름을 사용하십시오.
예를 들어 책과 CD를 나타내려면 다음 type='book'과 같은 작업을 수행하십시오 type='cd'. 수업은 뭔가가 무엇을 나타내는 훨씬 더 나은 입니다 .

예 : class='book'

나는 과거에 사용자 정의 속성을 사용했지만 솔직히 의미 론적으로 의미있는 방식으로 기존 속성을 사용하는 경우 속성을 사용할 필요가 없습니다.

보다 구체적인 예를 들기 위해 다른 종류의 상점에 대한 링크를 제공하는 사이트가 있다고 가정 해 봅시다. 다음을 사용할 수 있습니다.

<a href='wherever.html' id='bookstore12' class='book store'>Molly's books</a>
<a href='whereverelse.html' id='cdstore3' class='cd store'>James' Music</a>

CSS 스타일링은 다음과 같은 클래스를 사용할 수 있습니다.

.store { }
.cd.store { }
.book.store { }

위의 예에서 두 사이트 모두 상점에 대한 링크 (사이트의 다른 관련없는 링크와 반대)이고 하나는 CD 저장소이고 다른 하나는 서점입니다.


답변

dom에 데이터를 포함시키고 jQuery에 메타 데이터 를 사용하십시오 .

모든 우수한 플러그인은 메타 데이터 플러그인 (태그 당 옵션 허용)을 지원합니다.

또한 키-값 쌍뿐만 아니라 매우 복잡한 데이터 / 데이터 구조도 허용합니다.

<li class="someclass {'some': 'random,'json':'data'} anotherclass">...</li>

또는

<li class="someclass" data="{'some':'random', 'json': 'data'}">...</li>

또는

<li class="someclass"><script type="data">{"some":"random","json":"data"}</script> ...</li>

그런 다음 데이터를 다음과 같이 얻으십시오.

var data = $('li.someclass').metadata();
if ( data.some && data.some == 'random' )
alert('It Worked!');


답변

네임 스페이스를 확장하거나 확장하지 않고 기존 XHTML 기능을 사용하는 데 아무런 문제가 없습니다. 작은 예를 살펴 보겠습니다.

<div id="some_content">
 <p>Hi!</p>
</div>

추가 속성없이 some_content에 추가 정보를 추가하는 방법은 무엇입니까? 다음과 같은 다른 태그를 추가하는 것은 어떻습니까?

<div id="some_content">
 <div id="some_content_extended" class="hidden"><p>Some alternative content.</p></div>
 <p>Hi!</p>
</div>

그것은 당신이 선택한 잘 정의 된 id / extension “_extended”와 계층에서의 위치에 의해 관계를 유지합니다. 필자는 종종이 접근법을 jQuery와 함께 사용하고 실제로 Ajax와 유사한 기술을 사용하지 않습니다.


답변

아니. 대신 다음과 같이 해보십시오.

<div id="foo"/>

<script type="text/javascript">
  document.getElementById('foo').myProperty = 'W00 H00! I can add JS properties to DOM nodes without using custom attributes!';
</script>