jquery डेटा चयनकर्ता


184

मुझे किसी तत्व के .data()ऑब्जेक्ट में संग्रहीत मूल्यों के आधार पर तत्वों का चयन करने की आवश्यकता है । कम से कम, मैं चयनकर्ताओं का उपयोग करके शीर्ष-स्तरीय डेटा गुणों का चयन करना चाहूंगा, शायद इस तरह:

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

या शायद चयनकर्ता नियमित विशेषता चयनकर्ता प्रारूप में होगा:

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

या विशेषता प्रारूप में, लेकिन यह निर्दिष्ट करने के लिए एक विशेष के साथ .data():

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

मुझे जेम्स पडोल्सी का कार्यान्वयन सरल, अभी तक अच्छा दिखने के लिए मिला है । उस पृष्ठ पर दिखाए गए दर्पण विधियों के ऊपर चयनकर्ता प्रारूप। यह Sizzle पैच भी है ।

किसी कारण से, मुझे कुछ समय पहले पढ़ने की याद है कि jQuery 1.4 में jquery .data()वस्तु में मूल्यों पर चयनकर्ताओं के लिए समर्थन शामिल होगा । हालाँकि, अब जब मैं इसकी तलाश कर रहा हूं, तो मैं इसे नहीं पा सकता। शायद यह केवल एक सुविधा अनुरोध था जो मैंने देखा था। क्या इसके लिए समर्थन है और मैं इसे नहीं देख रहा हूं?

आदर्श रूप में, मैं डॉट नोटेशन का उपयोग करके डेटा में उप-संपत्तियों () का समर्थन करना चाहूंगा। ऐशे ही:

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

मैं कई डेटा चयनकर्ताओं का समर्थन करना चाहूंगा, जहां सभी निर्दिष्ट डेटा चयनकर्ताओं के साथ केवल तत्व पाए जाते हैं। नियमित jquery कई चयनकर्ता एक OR ऑपरेशन करता है। उदाहरण के लिए, वर्ग या ) के साथ टैग $('a.big, a.small')का चयन करता है । मैं एक के लिए देख रहा हूँ, शायद इस तरह:abigsmall

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

अंत में, यह बहुत अच्छा होगा यदि तुलना ऑपरेटर और रेगेक्स सुविधाएँ डेटा चयनकर्ताओं पर उपलब्ध थीं। तो $(a[:artist.id>5000])संभव होगा। मुझे लगता है कि मैं शायद इस का उपयोग कर सकता है filter(), लेकिन एक सरल चयनकर्ता प्रारूप होना अच्छा होगा।

ऐसा करने के लिए क्या समाधान उपलब्ध हैं? क्या इस समय जेम का पडोलसी सबसे अच्छा समाधान है? मेरी चिंता मुख्य रूप से प्रदर्शन के संबंध में है, लेकिन उप-संपत्ति डॉट-नोटेशन और कई डेटा चयनकर्ताओं जैसी अतिरिक्त सुविधाओं में भी। क्या अन्य कार्यान्वयन हैं जो इन चीजों का समर्थन करते हैं या किसी तरह से बेहतर हैं?


Jquery ui core api.jqueryui.com/category/ui-core का उपयोग करें इसमें डेटा: () चयनकर्ता
regisbsb

जवाबों:


101

मैंने एक नया dataचयनकर्ता बनाया है, जो आपको नेस्टेड क्वेरी और शर्तों को करने में सक्षम बनाना चाहिए। उपयोग:

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

पैटर्न है:

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

"ऑपरेटर" और "चेक" वैकल्पिक हैं। इसलिए, यदि आपके पास केवल :data(a.b.c)इसकी सत्यता की जांच होगी a.b.c

आप नीचे दिए गए कोड में उपलब्ध ऑपरेटरों को देख सकते हैं। उनमें से ~=जो regex परीक्षण की अनुमति देता है:

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

मैंने कुछ भिन्नताओं के साथ इसका परीक्षण किया है और यह काफी अच्छा काम करता है। मैं शायद इसे जल्द ही (पूर्ण परीक्षण सूट के साथ) एक गितुब रेपो के रूप में जोड़ दूंगा, इसलिए एक नज़र रखना!

कोड:

(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;

    };

}());

@ जेपी: बहुत प्यारी, मुझे पता था कि मैं आप पर भरोसा कर सकता हूं! अभी बिस्तर पर है, लेकिन मैं इसे कल आजमाऊंगा। क्या OR ऑपरेशन करना संभव है? मुझे इसकी जरूरत नहीं है, बस जिज्ञासु हूं।
टॉरेन

1
@ जेपी: इसके अलावा, मैं आपके बनाम अन्य डेटा चयनकर्ता समाधानों के बारे में उत्सुक हूं। उदाहरण के लिए, यह प्लगइन: plugins.jquery.com/project/dataSelector
टॉरेन

1
OR ऑपरेशन करना संभव है, लेकिन यह केवल दो चयनकर्ताओं के लिए सबसे अच्छा हो सकता है, $("a:data(condition),a:data(orCondition)")... इसका प्रभाव समान होगा। आप जितनी अधिक सुविधाएँ जोड़ेंगे, वह उतनी ही धीमी होगी। यदि तर्क जटिल है, तो उपयोग करें $(foo).filter(function(){...})
जेम्स

3
@ जेपी: क्या आपने कभी इसे गीथूब प्रोजेक्ट में बदल दिया? मैं html5 विशेषता डेटा-परीक्षण = "500" के साथ इनपुट पर चयनकर्ता $ ("इनपुट: डेटा (परीक्षण> 400)") का उपयोग करके jQuery 1.5.1 का उपयोग करके एक परीक्षण चला रहा हूं लेकिन चयनकर्ता कुछ भी नहीं लौटा रहा है।
जेम्स साउथ

1
@JamesSouth ऐसा इसलिए है क्योंकि इस उत्तर में चयनकर्ता निम्न स्तर का उपयोग करता है jQuery.data, जिससे एचटीएमएल 5 विशेषताओं में परिभाषित डेटा नहीं मिलता है। आपको लगता है कि कार्यक्षमता चाहते हैं, आप बदल सकते हैं jQuery.dataकरने के लिए $('selector').dataहै, लेकिन उस गति के लिए एक व्यापार है।
शैफ

175

फिलहाल मैं इस तरह का चयन कर रहा हूं:

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

जो सिर्फ ठीक काम करने के लिए लगता है, लेकिन यह अच्छा होगा यदि jQuery उस विशेषता द्वारा 'डेटा-' उपसर्ग के बिना चयन करने में सक्षम था।

मैंने इसे jQuery के माध्यम से तत्वों में जोड़े गए डेटा के साथ परीक्षण नहीं किया है, ताकि इस पद्धति का पतन हो सके।


यही वह है जिसकी तलाश में मैं हूं। स्वीट
मिकमर्को सेप

109
यह वास्तव में काम नहीं करता है यदि आप .data () फ़ंक्शन के माध्यम से जेएस के माध्यम से डेटा संलग्न / संशोधित करते हैं, तो चयनकर्ता केवल DOM, JS स्टोर्स .data () को मेमोरी में चेक करता है
क्लेरेंस लियू

1
क्या आप बता सकते हैं कि यदि आप .data () से जुड़ते हैं तो आप विशेषता द्वारा कैसे पहुँच सकते हैं?
मैक्सिम वी। पावलोव

1
मेरा सुझाव है कि इस धागे में दिए गए अन्य उत्तर बहुत ही सरल उपयोग के मामले के अलावा किसी भी चीज़ के लिए बेहतर विकल्प हैं।
राख

दिमित्री का समाधान मुझे अच्छा लगता है क्योंकि यह तीसरे पक्ष के कोड पर निर्भर नहीं करता है।
ऐश

83

आप किसी भी प्लगइन्स के बिना एक साधारण फ़िल्टरिंग फ़ंक्शन का उपयोग कर सकते हैं। यह बिल्कुल वैसा नहीं है जैसा आप चाहते हैं लेकिन परिणाम समान है:

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

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

2
यह एक महान विचार है, मैं भूल गया था कि filterट्रैवर्सल फ़ंक्शन एक परीक्षण फ़ंक्शन =) को स्वीकार कर सकता है
क्लेरेंस लिउ

मैं टॉम के बराबर "समाहित" कैसे कर सकता हूं?
एलिसो

1
Alisso, name.first == के बजाय "Tom" name.first && name.first.indexOF ("टॉम")> -1 का उपयोग करें;
दिमित्री

24

मैं आपको चेतावनी देना चाहता हूं कि $('a[data-attribute=true]')एशले के उत्तर के अनुसार काम नहीं करता है, यदि आपने डेटा () फ़ंक्शन के माध्यम से डोम तत्व से डेटा संलग्न किया है।

यदि आप अपने HTML में एक वास्तविक डेटा-अटायर जोड़ते हैं, तो यह आपकी अपेक्षा के अनुरूप काम करता है, लेकिन jQuery डेटा को मेमोरी में संग्रहीत करता है, इसलिए आपके द्वारा प्राप्त किए जाने वाले परिणाम $('a[data-attribute=true]')सही नहीं होंगे।

आपको डेटा प्लगइन का उपयोग करने की आवश्यकता होगी http://code.google.com/p/jquerypluginsblog/ , दिमित्री के filterसमाधान का उपयोग करें , या सभी तत्वों पर $ .each करें और पुन: जाँच करें () पुनरावृत्ति करें।


मेरे मामले में यह ठीक है क्योंकि मैं सर्वर साइड पर फ़ील्ड को प्री-पॉप्युलेट कर रहा हूं और केवल प्रारंभिक लोड पर इस तरह से परामर्श करने की आवश्यकता है। फ़िल्टर शायद उतना ही तेज़ है (प्रत्येक लगभग निश्चित रूप से धीमा है) लेकिन यह पठनीयता पर जीतता है।
डॉन

11

वहाँ एक :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- आई" नहीं है। सामान (आप आमतौर पर तत्व पक्ष से आते हैं)। मेरे सिर के शीर्ष पर, मुझे यकीन नहीं है कि प्रदर्शन के मामले में अद्वितीय आईडी से तत्व तक जाने की प्रक्रिया अपने आप में जटिल है, वैसे भी यह सबसे तेज़ है।

आपके द्वारा उल्लिखित तुलना चयनकर्ता सबसे अच्छा काम करेगा .filter(), प्लगइन में इसके लिए कोई अंतर्निहित समर्थन नहीं है, हालांकि आप इसे बहुत परेशानी के बिना जोड़ सकते हैं।


पूरी तरह से उत्तर के लिए धन्यवाद। क्या आप जानते हैं कि HTML5 data-*विशेषताओं का उपयोग करना और उन पर चयन करना .data()गुणों पर चयन करने से अधिक तेज़ होगा ? इसके अलावा, किसी भी विचार से मुझे $ ._ कैश के बारे में अधिक जानकारी कहां मिल सकती है? मैं इसके लिए googled, लेकिन बहुत कुछ नहीं मिल रहा है।
टॉरेन

@Tauren - मेरी गलती $.cacheनहीं है $._cache, आप देख सकते हैं कि इसे jQuery कोर में कैसे लागू किया जाता है और इसका उपयोग किया जाता है: github.com/jquery/jquery/blob/master/src/data.js#L4 जब आप कॉल करते हैं .data()तो वास्तव में इसे एक वस्तु के रूप में संग्रहीत करना होता है। में $.cache[elementUniqueID]है, जो एक आईडी, जैसे, 1, 2, 3, आदि प्रत्येक तत्व के लिए एक incrimental तरह से रूप में की जरूरत है कि चढ़ाई आईडी आधारित Git दूसरे दिन टिप्पणियाँ बंद jQuery 1.4.3 में उजागर किया जाएगा मुझे विश्वास है, सौंपा है। मुझे लगता है कि HTML 5 मार्ग तेज होगा, यह निर्भर करता है कि कौन से ब्राउज़र अनुकूलन उपलब्ध हैं (मुझे यकीन है कि अधिक उपलब्ध होगा)।
निक Craver

7

आप data-*एल्म का उपयोग करके एक विशेषता सेट कर सकते हैं 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 लियू को @ ऐश के जवाब के साथ-साथ इस पोस्ट के लिए धन्यवाद ।



5

यदि आप jQueryUI का उपयोग भी करते हैं, तो आपको :dataइसके साथ चयनकर्ता का एक (सरल) संस्करण मिलता है जो डेटा आइटम की उपस्थिति के लिए जांच करता है, इसलिए आप कुछ ऐसा कर सकते हैं $("div:data(view)"), या $( this ).closest(":data(view)")

Http://api.jqueryui.com/data-selector/ देखें । मुझे नहीं पता कि उनके पास यह कब तक है, लेकिन यह अब है!


यह केवल आपके द्वारा कहे गए डेटा आइटम की उपस्थिति के लिए जाँच करता है। यह मानों की जाँच नहीं करता (डॉक्स के अनुसार)। हालांकि इसके बारे में जानकर अच्छा लगा
Fractalf

3

यहाँ एक प्लगइन है जो जीवन को सरल बनाता है https://github.com/rootical/jQueryDataSelector

इसे इस तरह उपयोग करें:

data selector           jQuery selector
  $$('name')              $('[data-name]')
  $$('name', 10)          $('[data-name=10]')
  $$('name', false)       $('[data-name=false]')
  $$('name', null)        $('[data-name]')
  $$('name', {})          Syntax error
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.