[jquery] jquery 데이터 선택기

요소의 .data()객체에 저장된 값을 기반으로 요소를 선택해야 합니다. 최소한 선택기를 사용하여 최상위 데이터 속성을 선택하고 싶습니다.

$('a').data("category","music");
$('a:data(category=music)');

또는 선택기는 일반 속성 선택기 형식 일 수 있습니다.

$('a[category=music]');

또는 속성 형식이지만 지정자를 지정하여 다음을 나타냅니다 .data().

$('a[:category=music]');

내가 발견 한 제임스 Padolsey의 구현 봐 간단하면서도 좋은으로합니다. 위의 선택기는 해당 페이지에 표시된 미러 방법을 포맷합니다. 이 Sizzle 패치도 있습니다.

어떤 이유로 jQuery 1.4에 jquery .data()객체의 값에 대한 선택기 지원이 포함되어 있다는 것을 잠시 되돌아 본 적이 있습니다. 그러나 이제는 찾고 있는데 찾을 수 없습니다. 어쩌면 내가 본 기능 요청 일 수도 있습니다. 이것에 대한 지원이 있고 그것을 보지 못하고 있습니까?

이상적으로는 점 표기법을 사용하여 data ()의 하위 속성을 지원하고 싶습니다. 이처럼 :

$('a').data("user",{name: {first:"Tom",last:"Smith"},username: "tomsmith"});
$('a[:user.name.first=Tom]');

또한 모든 지정된 데이터 선택기가있는 요소 만있는 여러 데이터 선택기를 지원하고 싶습니다. 일반 jquery 다중 선택기는 OR 연산을 수행합니다. 예를 들어 class 또는 )가있는 태그를 $('a.big, a.small')선택 a합니다 . AND를 찾고 있는데 아마도 다음과 같습니다.bigsmall

$('a').data("artist",{id: 3281, name: "Madonna"});
$('a').data("category","music");
$('a[:category=music && :artist.name=Madonna]');

마지막으로 비교 연산자와 정규식 기능을 데이터 선택기에서 사용할 수 있다면 좋을 것입니다. 따라서 $(a[:artist.id>5000])가능할 것입니다. 나는 아마도 이것을 사용하여 이것을 많이 할 수 있다는 것을 알고 filter()있지만 간단한 선택기 형식을 갖는 것이 좋을 것입니다.

이를 위해 어떤 솔루션을 사용할 수 있습니까? 현재 Jame의 Padolsey가 최고의 솔루션입니까? 내 관심사는 주로 성능뿐만 아니라 하위 속성 점 표기법 및 여러 데이터 선택기와 같은 추가 기능에 관한 것입니다. 이러한 것들을 지원하거나 어떤면에서 더 나은 다른 구현이 있습니까?



답변

data중첩 된 쿼리 및 AND 조건을 수행 할 수 있는 새로운 선택기를 만들었습니다 . 용법:

$('a:data(category==music,artist.name==Madonna)');

패턴은 다음과 같습니다.

:data( {namespace} [{operator} {check}]  )

“operator”및 “check”는 선택 사항입니다. 따라서 당신이 가지고있는 것만 있다면 :data(a.b.c)진실성 을 점검 할 것 입니다 a.b.c.

아래 코드에서 사용 가능한 연산자를 확인할 수 있습니다. 그중 ~=정규 표현식 테스트가 가능합니다.

$('a:data(category~=^mus..$,artist.name~=^M.+a$)');

몇 가지 변형으로 테스트했으며 꽤 잘 작동하는 것 같습니다. 아마 이것을 전체 테스트 스위트와 함께 곧 Github 저장소로 추가 할 것이므로 조심하십시오!

코드:

(function(){

    var matcher = /\s*(?:((?:(?:\\\.|[^.,])+\.?)+)\s*([!~><=]=|[><])\s*("|')?((?:\\\3|.)*?)\3|(.+?))\s*(?:,|$)/g;

    function resolve(element, data) {

        data = data.match(/(?:\\\.|[^.])+(?=\.|$)/g);

        var cur = jQuery.data(element)[data.shift()];

        while (cur && data[0]) {
            cur = cur[data.shift()];
        }

        return cur || undefined;

    }

    jQuery.expr[':'].data = function(el, i, match) {

        matcher.lastIndex = 0;

        var expr = match[3],
            m,
            check, val,
            allMatch = null,
            foundMatch = false;

        while (m = matcher.exec(expr)) {

            check = m[4];
            val = resolve(el, m[1] || m[5]);

            switch (m[2]) {
                case '==': foundMatch = val == check; break;
                case '!=': foundMatch = val != check; break;
                case '<=': foundMatch = val <= check; break;
                case '>=': foundMatch = val >= check; break;
                case '~=': foundMatch = RegExp(check).test(val); break;
                case '>': foundMatch = val > check; break;
                case '<': foundMatch = val < check; break;
                default: if (m[5]) foundMatch = !!val;
            }

            allMatch = allMatch === null ? foundMatch : allMatch && foundMatch;

        }

        return allMatch;

    };

}());


답변

현재 다음과 같이 선택하고 있습니다.

$('a[data-attribute=true]')

어느 것이 잘 작동하는 것처럼 보이지만 jQuery가 ‘data-‘접두사없이 해당 속성으로 선택할 수 있다면 좋을 것입니다.

jQuery를 통해 요소에 동적으로 추가 된 데이터로 이것을 테스트하지 않았 으므로이 방법이 실패 할 수 있습니다.


답변

플러그인없이 간단한 필터링 기능을 사용할 수도 있습니다. 이것은 정확히 원하는 것이 아니지만 결과는 같습니다.

$('a').data("user", {name: {first:"Tom",last:"Smith"},username: "tomsmith"});

$('a').filter(function() {
    return $(this).data('user') && $(this).data('user').name.first === "Tom";
});


답변

$('a[data-attribute=true]')data () 함수를 통해 DOM 요소에 데이터를 첨부하면 Ashley의 답변에 따라 작동하지 않는다는 경고를하고 싶습니다 .

HTML에 실제 데이터 공격자를 추가하면 예상대로 작동하지만 jQuery는 데이터를 메모리에 저장하므로 결과 $('a[data-attribute=true]')가 정확하지 않습니다.

데이터 플러그인 http://code.google.com/p/jquerypluginsblog/ 를 사용 filter하거나 Dmitri의 솔루션을 사용 하거나 모든 요소에 대해 $ .each를 수행하고 .data ()를 반복적으로 확인해야합니다.


답변

이 작업을 수행하는 :data()필터 플러그인 이 있습니다 🙂

귀하의 질문에 근거한 몇 가지 예 :

$('a:data("category=music")')
$('a:data("user.name.first=Tom")');
$('a:data("category=music"):data("artist.name=Madonna")');
//jQuery supports multiple of any selector to restrict further, 
//just chain with no space in-between for this effect

가능한$._cache 요소에 비해 성능이 크게 향상되지는 않습니다 . 해당 요소를 선택 하고 잡는 것이 훨씬 빠르지 만 훨씬 더 많은 정보를 얻을 수 있으며 “jQuery-ey”는 아닙니다. 물건 (일반적으로 요소 측면에서 나옵니다). 내 머리 꼭대기에서 나는 고유 ID에서 요소로 이동하는 프로세스가 성능 측면에서 자체적으로 복잡하기 때문에 어쨌든 이것이 가장 빠르지 않다.

언급 한 비교 선택기는에서 가장 잘 수행 .filter()할 수 있지만 플러그인에는 기본적으로 지원되지 않지만 많은 문제없이 추가 할 수 있습니다.


답변

data-*사용하여 elm에 속성을 설정 한 attr()다음 해당 속성을 사용하여 선택할 수 있습니다 .

var elm = $('a').attr('data-test',123); //assign 123 using attr()
elm = $("a[data-test=123]"); //select elm using attribute

지금 그 느릅 나무를 위해, 모두 attr()data()얻을 것 123 :

console.log(elm.attr('data-test')); //123
console.log(elm.data('test')); //123

당신이 할 값을 수정할 경우, 456을 사용하여 attr(), data() 여전히 것 123 :

elm.attr('data-test',456); //modify to 456
elm = $("a[data-test=456]"); //reselect elm using new 456 attribute

console.log(elm.attr('data-test')); //456
console.log(elm.data('test')); //123

내가 이해 한 것처럼, 필요하지 않으면 코드에서 혼합 attr()data()명령을 피해야 할 것 같습니다 . 있으므로 attr()반면 DOM 직접 대응 같다 data()초기 값이 될 수 DOM에서 불구하고, ‘메모리’와 상호 작용한다. 그러나 핵심은 두 가지가 반드시 동기화되어 있지는 않다는 것입니다.

그러니 조심하세요

어쨌든 data-*DOM 또는 메모리에서 속성을 변경 하지 않으면 문제가 없습니다. 곧 값을 수정하기 시작하면 잠재적 인 문제가 발생할 수 있습니다.

@Clarence Liu에게 @Ash의 답변 과이 게시물에 감사드립니다 .


답변

$('a[data-category="music"]')

효과가있다. Attribute Equals Selector [name =”value”]를 참조하십시오 .