:scope
در CSS Selectors 4 به صورت زیر تعریف شده است:
یک کلاس شبه که نشان دهنده هر عنصری است که در مجموعه عناصر مرجع متنی است. این مجموعه ای از عناصر (بالقوه خالی) است که به طور صریح مشخص شده است، مانند آنچه توسط
querySelector()
مشخص شده است، یا عنصر والد عنصر<style scoped>
، که برای "scope" یک انتخابگر استفاده می شود به طوری که فقط مطابق با یک زیر درخت
نمونه ای از استفاده از آن در <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
قرار می دهد. دلیلش این است که در زمینه این <style scoped>
، ul
با :scope
مطابقت دارد. این بافت محلی است. اگر بخواهیم یک قانون :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.) با انتخابگر مطابقت دارند و b.) که آنها نیز از نوادگان عنصر زمینه هستند. بنابراین در مثال دوم، مرورگر همه a
را پیدا میکند، سپس آنهایی را که در عنصر scope
نیستند فیلتر میکند. این کار می کند، اما اگر مراقب نباشید می تواند منجر به رفتارهای عجیب و غریب شود. ادامه مطلب
وقتی querySelector اشتباه میکند
نکته بسیار مهمی در مشخصات Selectors وجود دارد که مردم اغلب از آن غافل می شوند. حتی زمانی که 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
... enter :scope
برای حل این ابهامات معنایی.
رفع querySelector با :scope
WebKit اخیراً پشتیبانی برای استفاده از :scope
pseudo-class در querySelector[All]()
دریافت کرده است. می توانید آن را در Chrome Canary 27 تست کنید.
می توانید از آن استفاده کنید انتخابگرها را به یک عنصر زمینه محدود کنید . بیایید یک مثال را ببینیم. در ادامه از :scope
برای "scope" انتخابگر به زیردرخت عنصر scope استفاده می شود. درسته سه بار 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 در حال حاضر 1.5-2 برابر بیشتر از عدم استفاده از :scope
طول می کشد. درات ها! هنگامی که crbug.com/222028 رفع شد، استفاده از آن از نظر تئوری باعث افزایش عملکرد جزئی نسبت به عدم استفاده از آن می شود.