:scope
, CSS Seçiciler 4'te şu şekilde tanımlanır:
Bağlamsal referans öğesi grubundaki herhangi bir öğeyi temsil eden sözde sınıf. Bu,
querySelector()
tarafından belirtilenler gibi açıkça belirtilmiş bir öğe grubu (büyük olasılıkla boş) veya bir<style scoped>
öğesinin üst öğesidir ve bir seçiciyi yalnızca bir alt ağacın içinde eşleşecek şekilde "kapsama almak" için kullanılır.
Bunun kullanımına <style scoped>
içinde bir örnek verilebilir (daha fazla bilgi):
<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>
Bu işlem, ilk ul
içindeki li
öğelerini kırmızıya boyatır ve :scope
kuralı nedeniyle ul
öğesinin etrafına bir kenarlık yerleştirir. Bunun nedeni, bu <style scoped>
bağlamında ul
değerinin :scope
ile eşleşmesidir. Yerel bağlam. Dış <style>
öğesine :scope
kuralı eklersek tüm dokümanla eşleşir. Temelde :root
ile eşdeğerdir.
Bağlamsal öğeler
Büyük olasılıkla querySelector()
ve querySelectorAll()
Element
sürümlerini biliyorsunuz. Dokümanın tamamını sorgulamak yerine sonuç kümesini bağlamsal bir öğeyle kısıtlayabilirsiniz:
<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>
Bunlar çağrıldığında, tarayıcı yalnızca a.) seçici ile eşleşen ve b.) ile eşleşen ve aynı zamanda bağlam öğesinin alt öğeleri olan düğüm grubunu içerecek şekilde filtrelenmiş bir NodeList
döndürür. Dolayısıyla, ikinci örnekte tarayıcı tüm a
öğelerini bulur ve ardından scope
öğesinde olmayan öğeleri filtreler. Bu yöntem işe yarıyor ancak dikkatli olmazsanız tuhaf davranışlara neden olabilir. Okumaya devam edin.
querySelector yanlış gittiğinde
Seçiciler spesifikasyonunda kullanıcıların genellikle göz ardı ettiği gerçekten önemli bir nokta vardır. Bir öğede querySelector[All]()
çağrılsa bile seçiciler, tüm belgenin bağlamında değerlendirmeye devam eder. Bu durum, beklenmedik durumların ortaya çıkabileceği anlamına gelir:
scope.querySelectorAll('ul a').length); // 1
scope.querySelectorAll('body ul a').length); // 1
Vay canına! İlk örnekte, ul
öğemdir, ancak yine de onu kullanabilirim ve düğümlerle eşleşir. İkincisinde, body
benim öğemin bir alt öğesi bile değil, ancak "body ul a
" hâlâ eşleşiyor. Bunların ikisi de kafa karıştırıcıdır ve beklediğiniz gibi değildir.
Burada, doğru yaklaşımı uygulayan ve beklediğinizi yapan jQuery ile karşılaştırma yapmak yerinde olacaktır:
$(scope).find('ul a').length // 0
$(scope).find('body ul a').length // 0
...bu anlamsal maskaralıkları çözmek için :scope
yazın.
:scope ile querySelector'ı düzeltme
WebKit, kısa bir süre önce querySelector[All]()
ürününde :scope
sözde sınıfının kullanımı için destek aldı. Bu özelliği Chrome Canary 27'de test edebilirsiniz.
Seçicileri bir bağlam öğesiyle sınırlandırabilirsiniz. Bir örnekle açıklayalım. Aşağıda :scope
, seçiciyi kapsam öğesinin alt ağacının kapsamına "kapsama almak" için kullanılır. Doğru, üç kez kapsam dedim.
scope.querySelectorAll(':scope ul a').length); // 0
scope.querySelectorAll(':scope body ul a').length); // 0
scope.querySelectorAll(':scope a').length); // 1
:scope
kullanımı, querySelector()
yöntemlerinin anlamını biraz daha tahmin edilebilir ve jQuery gibi diğer yöntemlere uygun hale getirir.
Peki, performans açısından kazançlı mı?
Henüz değil :(
QS/qSA'da :scope
kullanmanın performansı artırıp artırmadığını merak ediyorum. Ben de iyi bir mühendis gibi bir test yaptım. Gerekçe: Tarayıcının seçici eşleştirme yapması için daha az yüzey alanı olması, aramaların daha hızlı olacağı anlamına gelir.
Denememde, WebKit şu an :scope
kullanmamaya göre yaklaşık 1,5-2 kat daha uzun sürüyor. Drats! crbug.com/222028 adresi düzeltildiğinde, bu adresi kullanmamak yerine bu adresi kullanmak teorik olarak size biraz performans artışı sağlayacaktır.