2012-09-18 8 views
32

जाहिर है, जैसा कि मैंने another answer पर टिप्पणी करते समय खोजा है, jQuery (इसके बजाय इसके अंतर्निहित चयनकर्ता इंजन Sizzle) आपको :not() चयनकर्ता के साथ-साथ :has() चयनकर्ता को तर्क उद्धृत करने देता है। To wit:कार्यात्मक छद्म जैसे क्यों: नहीं() और: है() उद्धृत तर्कों की अनुमति देते हैं?

$('div:not("span")') 
$('span:has("span")') 

Selectors standard में, उद्धरण हमेशा की तरह, और एक स्ट्रिंग के प्रतिनिधि एक चयनकर्ता या एक कीवर्ड की कभी नहीं कर रहे हैं तो :not() को तर्क के हवाले से हमेशा अमान्य है। This will not change in Selectors 4.

आप यह भी देख सकते हैं कि यह जोड़कर अमानक वाक्य रचना है एक unsupported CSS selector ऐसे :nth-last-child(1) रूप causing the selector to fail completely:

$('div:not("span"):nth-last-child(1)') 
$('span:has("span"):nth-last-child(1)') 

कोई अच्छा कारण है, तकनीकी या अन्यथा, उद्धरण यहाँ अनुमति देने के लिए? केवल संभावनाओं जो मन में आ रहे हैं: जो दोनों उद्धृत और गैर उद्धृत तर्कों के रूप में देखा the old Selectors spec अनुमति देता है, :contains() साथ

  • संगति। सिवाय :contains() तार/कीवर्ड, नहीं चयनकर्ताओं ... $.expr[':'] का उपयोग कर कस्टम pseudos के कार्यान्वयन है, जो हमेशा उद्धृत की अनुमति देता है और गैर उद्धृत तर्क के साथ

  • संगति स्वीकार करता है।

  • संगति और उनके विधि समकक्षों .not() और .has() को पोर्टिंग में आसानी (बस हटाने या बाहरी उद्धरण विभाजित है और समय के लिए कोलन को बदलने?)।

लेकिन मैं किसी भी स्रोत का समर्थन या उन्हें विरोध करने के लिए नहीं मिल रहा। वास्तव में, चयनकर्ता तर्क ही उद्धृत करने के लिए क्षमता कहीं भी या तो दर्ज नहीं किया है, न ही वहाँ के हवाले से और तर्क के हवाले नहीं के बीच कोई अंतर प्रतीत करता है:

$('div:not(span)') 
$('span:has(span)') 
+5

यह संभवतः [Sizzle] (http://sizzlejs.com/) का एक quirk है, jQuery की नहीं। – lanzz

+1

@ बोल्टक्लॉक क्षमा करें मेरा उदाहरण खराब था, मुझे लगता है कि उद्धरण का एकमात्र उद्देश्य भाग रहा है। – undefined

+0

यह शायद '$ .expr [':']' के कार्यान्वयन में स्थिरता के लिए है। – zzzzBov

उत्तर

30

यह :not(...) और :has(...) चयनकर्ताओं के लिए विशिष्ट नहीं है - वास्तव में, सिज़ल में सभी छद्म उद्धृत तर्कों की अनुमति देते हैं। pseudos के तर्क के लिए पैटर्न के रूप में परिभाषित किया गया है:

pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)" 

कौन सा लाइन 91 of sizzle.js as of 831c9c48...

पर पाया जा सकता है कि करने के लिए कुछ खरोज जोड़ने के लिए, यह थोड़ा अधिक पठनीय बनाने के लिए करते हैं। दुर्भाग्य से, यह अभी भी एक regexp है, इसलिए "में थोड़ा और अधिक पठनीय" अभी भी एक बहुत छोड़ देता है वांछित होने के लिए:

pseudos = (
    ":(" + characterEncoding + ")" + 
    "(?:" + 
    "\\(" + // literal open-paren 
     "(?:" + 

       "(['\"])" + // literal open-quote 
        "((?:\\\\.|[^\\\\])*?)" + // handle backslash escaping 
       "\\2" + // close-quote 

      "|" + // - OR - 

       "(" + 
        "[^()[\\]]*" + 
        "|" + 
        "(?:" + 
         "(?:" + attributes + ")" + 
         "|" + 
         "[^:]" + 
         "|" + 
         "\\\\." + 
        ")*" + 
        "|" + 
        ".*" + 
       ")" + 

     ")" + 
    "\\)" + // literal close-paren 
    "|" + // ie, 'or nothing' 
")" 
); 

इस से मुख्य ले की दूरी पर है: या तो एकल या डबल-उद्धरण हो सकता है एक छद्म-विशेषता में तर्क के आसपास प्रयोग किया जाता है। बैकस्लैश एस्केपिंग ठीक से संभाला गया है, और इसलिए किसी भी मनमानी स्ट्रिंग को तर्क के रूप में पारित किया जा सकता है।ध्यान दें कि उपरोक्त regexp में "चयनकर्ता" भाग के रूप में "स्ट्रिंग" भाग एक ही मैच इंडेक्स में हवाओं को चलाता है; इसलिए, संक्षेप में, यही कारण है कि उनका समान व्यवहार किया जाता है: क्योंकि pseudos पैटर्न दोनों के बीच अंतर नहीं करता है। संपादित करें: jQuery 1.8.2 के रूप में, तर्क उद्धरण के साथ और बिना उद्धरण अधिक स्पष्ट रूप से समकक्ष हैं। मैं jQuery Git भंडार [मदद की सराहना की जाएगी] में इस कोड को खोजने के लिए नहीं कर पा रहे हैं, लेकिन the version of 1.8.2 hosted by google, having the sha1sum of a0f48b6ad5322b35383ffcb6e2fa779b8a5fcffc, लाइन 4206 पर एक "PSEUDO": समारोह है, जो स्पष्ट रूप से "उद्धृत" और "गैर उद्धृत" तर्कों, और जो अंतर पता लगाता है है सुनिश्चित करता है कि वे दोनों एक ही स्थान पर हवाएं हैं। यह तर्क को छद्म ("स्थितित्मक" या नहीं) के बीच अंतर करता है जो कि तर्क है।

कड़ाके की धूप जावास्क्रिप्ट तार का उपयोग करता है के रूप में चयन प्रक्रिया शुरू करने के लिए, वहाँ "स्ट्रिंग" और "चयनकर्ता" के बीच कोई अंतर नहीं है जब तर्क कार्यों के लिए में पारित कर रहे हैं। उस तरह का भेद बनाना संभव होगा, लेकिन जहां तक ​​मुझे पता है, वास्तव में वांछित क्या है आसानी से सबसे बुनियादी संदर्भ से निर्धारित किया जाता है (यानी: छद्म का उपयोग किस प्रकार किया जा रहा है), इसलिए कोई नहीं है भेद बनाने का वास्तविक कारण। (अगर कोई अस्पष्ट स्थितियां हैं, तो मुझे टिप्पणियों में सही करें, जिन्हें मैं अनजान हूं - मुझे पता होना चाहिए!)

तो फिर, अगर तार और चयनकर्ताओं के बीच के अंतर की कमी एक मात्र कार्यान्वयन विस्तार है, क्यों pseudos ऐसे :eq(...) स्पष्ट रूप इस तरह के चयन को अस्वीकार करते हैं?

उत्तर सरल है: यह वास्तव में नहीं है। कम से कम, jQuery 1.8.1 के रूप में नहीं। [संपादित करें: jQuery 1.8.2 के रूप में, यह बिल्कुल नहीं है। "पोजिशनल" छद्म शब्दों के तर्क किसी और चीज की तरह उद्धृत किए जा सकते हैं। नीचे 1.8.1 के कार्यान्वयन विवरण के बारे में नोट एक ऐतिहासिक जिज्ञासा] इस तरह के :eq(...) रूप

कार्य के रूप में लागू किया जाता है के रूप में छोड़ दिया जाता है:

"eq": function(elements, argument, not) { 
    var elem = elements.splice(+argument, 1); 
    return not ? elements : elem; 
} 

समय है कि :eq(...) तर्क प्राप्त करता है, यह है अभी भी में एक नंगे तर्क (उद्धरण और सभी) के रूप में। :not(...) के विपरीत, यह तर्क compile(...) चरण से गुजरता नहीं है। का "अस्वीकृति" वास्तव में शॉर्टकट-कास्टिंग +argument के माध्यम से शॉर्टकट-कास्टिंग के कारण होता है, जिसके परिणामस्वरूप NaN किसी भी उद्धृत स्ट्रिंग के लिए परिणामस्वरूप होगा ( बारी में, कभी भी कुछ भी मेल नहीं खाता)। हालांकि इस मामले में एक "सही ढंग से" एक व्यवहार कर यह अभी तक एक और कार्यान्वयन विस्तार है (फिर से, जहाँ तक के रूप में मैं अवगत हूं। ऐसी परिस्थितियाँ होती हैं, जहां इस तरह कार्यों के लिए गैर-संख्यात्मक तर्क चाहिए तथ्य मैच में?)

संपादित करें: jQuery 1.8.2 के रूप में, हालात कुछ हद तक पुनर्संशोधित गया है, और "स्थितीय" pseudos न अब "कच्चे" तर्क प्राप्त करते हैं। नतीजतन, उद्धृत तर्क अब :eq(...) और इस तरह स्वीकार किए जाते हैं।यह परिवर्तन एक और बगफिक्स का दुष्प्रभाव प्रतीत होता है, क्योंकि af8206ff.. के लिए चेंजलॉग में उद्धृत तर्कों के लिए समर्थन का कोई उल्लेख नहीं है, जिसका उद्देश्य an error in handling :first and :last, jQuery bug #12303 को ठीक करना था। यह प्रतिबद्धता git bisect और a relatively simple phantomjs script का उपयोग करके पाई गई थी। यह उल्लेखनीय है कि e89d06c4.. में Sizzle फिर से लिखने के बाद, Sizzle केवल :eq("3") जैसे चयनकर्ताओं के लिए चुपचाप विफल नहीं होगा, यह वास्तव में एक अपवाद फेंक देगा। इसे अभी तक और सबूत के रूप में लिया जाना चाहिए कि :eq("3") समर्थन इरादा व्यवहार नहीं है।

वहाँ वास्तव में कस्टम फिल्टर, जिसका तर्क कुछ मामलों में तारों के रूप में, और कभी कभी के रूप में चयनकर्ताओं, के बारे में सोचा जा सकता है कोई फर्क नहीं पड़ता कि वे क्या अल्पज्ञता विधि है जिसमें वे मूल्यांकन किया जाता है पर निर्भर करता है की तरह लग रहे हैं, जिसके संबंध तर्क कर रहे हैं। .. लेकिन यह बहुत अधिक पैडेंटिक के करीब आ रहा है। यह कहने के लिए पर्याप्त होना चाहिए कि कम से कम भेद नहीं होने पर कार्यों को कॉल करते समय चीजों को सरल बना दिया जाता है, जो कोई फर्क नहीं पड़ता कि वे क्या प्रतिनिधित्व कर सकते हैं, स्ट्रिंग प्रतिनिधित्व की अपेक्षा करते हैं।

संक्षेप में, पूरे स्थिति एक कार्यान्वयन विस्तार के बारे में सोचा जा सकता है और तथ्य यह है कि चयनकर्ताओं पहली जगह में तारों के रूप में चारों ओर पारित कर रहे हैं में निहित है (और कैसे आप उन्हें कड़ाके की धूप में मिलेगा?)।

+0

क्या आपने [कच्चे तार] (http://docs.python.org/reference/lexical_analysis.html#string-literals) के बारे में नहीं सुना है? या शायद यह सिर्फ मुझे और पायथन है ... –

+1

+1 रेगेक्स को प्रारूपित करने के लिए समय निकालने के लिए और इसे समझाए जाने का प्रयास करें (जो एक कार्य का नरक है)। लेने के लिए बक्षीस तुम्हारा है। –

+0

मुझे लगता है कि मुझे वास्तव में इसे फिर से कदम उठाने की ज़रूरत है।आपकी टिप्पणी ने मुझे एक और नज़र देने के लिए प्रेरित किया, और मुझे लगता है कि मेरे सभी स्वरूपण प्रयासों के बावजूद, मैंने गलत पढ़ा होगा। मैंने वास्तव में टोकननाइज़ेशन प्रक्रिया के माध्यम से कदम नहीं उठाया है क्योंकि jQuery 1.8.2 जारी किया गया था, इसलिए मुझे वास्तव में यह सुनिश्चित करना चाहिए कि तर्क अभी भी सटीक है। –

संबंधित मुद्दे

 संबंधित मुद्दे