ما الغرض من الفئة الزائفة للنطاق في CSS؟

يتم تعريف :scope في أدوات اختيار لغة CSS 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>

يؤدي هذا إلى تلوين عناصر li باللون الأحمر ul الأول، وبسبب القاعدة :scope، يتم وضع حد حول ul. ويرجع ذلك إلى أنّ السمة ul تتطابق مع :scope في سياق هذه السمة <style scoped>. هذا هو السياق المحلي. إذا أضفنا قاعدة :scope في <style> الخارجي، ستتطابق مع المستند بأكمله. يعادل هذا الرمز بشكل أساسي :root.

العناصر السياقية

من المرجّح أنّك على دراية بالإصدار Element من querySelector() وquerySelectorAll(). بدلاً من طلب البحث في المستند بأكمله، يمكنك حصر مجموعة النتائج بعنصر سياقي:

<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، ثم يزيل العناصر التي لا تندرج ضمن عنصر 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 لحلّ هذه الأخطاء الدلالية.

إصلاح querySelector باستخدام :scope

أطلق WebKit مؤخرًا ميزة استخدام الفئة الزائفة :scope في querySelector[All](). يمكنك اختباره في 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.

هل حقّق الفيديو أداءً أفضل؟

لا، ليس بعد :(

أريد معرفة ما إذا كان استخدام :scope في qS/qSA يؤدي إلى تحسين الأداء. وبما أنّني مهندس جيد، أجريتُ اختبارًا. السبب المنطقي: كلما قلّت مساحة العرض التي يحتاجها المتصفّح لمطابقة المحدّد، كان البحث أسرع.

في تجربتي، يستغرق WebKit حاليًا وقتًا أطول بمقدار مرة ونصف إلى مرتين تقريبًا مقارنةً بعدم استخدام :scope. عارٍ عند إصلاح crbug.com/222028، من المفترض أن يؤدي استخدامها نظريًا إلى تحسين الأداء قليلاً مقارنةً بعدم استخدامها.