सीएसएस :scope pseudo-class क्या है?

सीएसएस सिलेक्टर 4 में :scope को इस तरह परिभाषित किया गया है:

एक स्यूडो-क्लास, जो संदर्भ के हिसाब से रेफ़रंस एलिमेंट सेट में मौजूद किसी भी एलिमेंट को दिखाता है. यह एलिमेंट का साफ़ तौर पर बताया गया सेट है, जो शायद खाली हो. जैसे, querySelector() या <style scoped> एलिमेंट का पैरंट एलिमेंट. इसका इस्तेमाल, किसी सिलेक्टर को "स्कोप" करने के लिए किया जाता है, ताकि वह सिर्फ़ किसी सबट्री में मैच करे.

इसका इस्तेमाल करने का उदाहरण, <style scoped> में दिया गया है (ज़्यादा जानकारी):

<style>
    li {
    color: blue;
    }
</style>

<ul>
    <style scoped>
    li {
        color: red;
    }
    :scope {
        border: 1px solid red;
    }
    </style>
    <li>abc</li>
    <li>def</li>
    <li>efg</li>
</ul>

<ul>
    <li>hij</li>
    <li>klm</li>
    <li>nop</li>
</ul>

इससे पहले ul में मौजूद li एलिमेंट लाल रंग में दिखते हैं. साथ ही, :scope नियम की वजह से ul के चारों ओर बॉर्डर दिखता है. ऐसा इसलिए है, क्योंकि इस <style scoped> के संदर्भ में, ul :scope से मेल खाता है. यह स्थानीय संदर्भ है. अगर हम बाहरी <style> में कोई :scope नियम जोड़ें, तो वह पूरे दस्तावेज़ से मेल खाएगा. असल में, :root के बराबर.

कॉन्टेक्स्ट के हिसाब से एलिमेंट

शायद आपको querySelector() और querySelectorAll() के Element वर्शन के बारे में पता हो. पूरे दस्तावेज़ के लिए क्वेरी करने के बजाय, नतीजे के सेट को संदर्भ के हिसाब से किसी एलिमेंट तक सीमित किया जा सकता है:

<ul>
    <li id="scope"><a>abc</a></li>
    <li>def</li>
    <li><a>efg</a></li>
</ul>
<script>
    document.querySelectorAll('ul a').length; // 2

    var scope = document.querySelector('#scope');
    scope.querySelectorAll('a').length; // 1
</script>

इन फ़ंक्शन को कॉल करने पर, ब्राउज़र एक ऐसा NodeList दिखाता है जिसे फ़िल्टर किया गया है, ताकि उसमें सिर्फ़ उन नोड का सेट शामिल हो जो a.) सिलेक्टर से मैच करते हैं और b.) जो कॉन्टेक्स्ट एलिमेंट के वंशज भी हैं. इसलिए, दूसरे उदाहरण में ब्राउज़र सभी a एलिमेंट ढूंढता है. इसके बाद, scope एलिमेंट में मौजूद एलिमेंट को फ़िल्टर कर देता है. यह तरीका काम करता है, लेकिन अगर सावधानी नहीं बरती जाती है, तो इससे कुछ अजीब व्यवहार हो सकता है. आगे पढ़ें.

जब querySelector गलत तरीके से काम करता है

सिलेक्टर स्पेसिफ़िकेशन में एक बहुत अहम बात है, जिसे लोग अक्सर अनदेखा कर देते हैं. किसी एलिमेंट पर querySelector[All]() का इस्तेमाल करने पर भी, सर्वर, पूरे दस्तावेज़ के संदर्भ में सेलेक्टर का आकलन करता है. इसका मतलब है कि अनचाही चीज़ें हो सकती हैं:

    scope.querySelectorAll('ul a').length); // 1
    scope.querySelectorAll('body ul a').length); // 1

WTF! पहले उदाहरण में, ul मेरा एलिमेंट है. इसके बावजूद, मैं इसका इस्तेमाल कर सकता हूं और यह नोड से मैच करता है. दूसरे उदाहरण में, body मेरे एलिमेंट का वंशज भी नहीं है, लेकिन "body ul a" फिर भी मैच करता है. ये दोनों बातें उलझन पैदा करने वाली हैं और आपकी उम्मीद के मुताबिक नहीं हैं.

यहां jQuery की तुलना करना सही रहेगा, जो सही तरीके से काम करता है और आपकी उम्मीद के मुताबिक नतीजे देता है:

    $(scope).find('ul a').length // 0
    $(scope).find('body ul a').length // 0

...अंतरंग से जुड़ी इन समस्याओं को हल करने के लिए, :scope में जाएं.

:scope की मदद से क्वेरी चुनने वाले टूल को ठीक करना

WebKit ने querySelector[All]() में :scope स्यूडो-क्लास का इस्तेमाल करने के लिए, हाल ही में सहायता उपलब्ध कराई है. Chrome कैनरी 27 में इसकी जांच की जा सकती है.

इसका इस्तेमाल करके, सिलेक्टर को किसी कॉन्टेक्स्ट एलिमेंट तक सीमित किया जा सकता है. आइए, एक उदाहरण देखते हैं. यहां :scope का इस्तेमाल, स्कोप एलिमेंट के सबट्री में सिलेक्टर को "स्कोप" करने के लिए किया गया है. हां, मैंने तीन बार स्कोप कहा था!

    scope.querySelectorAll(':scope ul a').length); // 0
    scope.querySelectorAll(':scope body ul a').length); // 0
    scope.querySelectorAll(':scope a').length); // 1

:scope का इस्तेमाल करने से, querySelector() तरीकों के सेमेटिक्स को थोड़ा और अनुमानित बनाया जा सकता है. साथ ही, jQuery जैसे दूसरे तरीकों के साथ इनका इस्तेमाल किया जा सकता है.

परफ़ॉर्मेंस बेहतर हो रही है?

अभी नहीं :(

मुझे जानना था कि qS/qSA में :scope का इस्तेमाल करने से परफ़ॉर्मेंस बेहतर होती है या नहीं. इसलिए... एक अच्छे इंजीनियर की तरह मैंने भी साथ मिलकर परीक्षा की. मेरा तर्क: ब्राउज़र के लिए, चुनने वाले के हिसाब से मैच करने के लिए कम जगह का मतलब है कि लुकअप तेज़ी से होगा.

मेरे प्रयोग के हिसाब से, :scope इस्तेमाल न करने की तुलना में WebKit को फ़िलहाल ~1.5 से 2 गुना ज़्यादा समय लगता है. ड्रेट्स! crbug.com/222028 ठीक होने के बाद, इसका इस्तेमाल करने से आपको परफ़ॉर्मेंस में थोड़ी बढ़ोतरी दिख सकती है.