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

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

एक स्यूडो-क्लास, जो संदर्भ के हिसाब से रेफ़रंस एलिमेंट सेट में मौजूद किसी भी एलिमेंट को दिखाता है. यह एलिमेंट का साफ़ तौर पर बताया गया सेट है, जो शायद खाली हो. जैसे, 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 के साथ querySelector को ठीक करना

WebKit ने querySelector[All]() में :scope स्यूडो-क्लास का इस्तेमाल करने के लिए, हाल ही में सहायता उपलब्ध कराई है. इसे Chrome Canary 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 ठीक होने के बाद, इसका इस्तेमाल करने से आपको परफ़ॉर्मेंस में थोड़ी बढ़ोतरी दिख सकती है.