CSS, HTML und Javascript mit {stil}

querySelector / querySelectorAll

query selector und query selector all

querySelector bzw. querySelectorAll wirken wie jQuery $(). Sie wählen Elemente anhand eines CSS-Selektors aus und geben ein einzelnes Element oder eine Liste der Treffer (Node List) zurück (ab IE8).

querySelector gibt das erste gefundene Element zurück, querySelectorAll gibt alle gefundenen Elemente in einer NodeList zurück.

Schon IE8 unterstützt querySelector() und querySelectorAll() – doch tatsächlich!. Allerdings verstehen querySelector und querySelectorAll dort nur CSS-Selektoren, die IE8 bereits kennt (also CSS 2.1 Selektoren) und funktioniert nicht mit HTML5-Tags.

querySelector

document.querySelector('h3')          selektiert das erste h3-Element     
document.querySelectorAll('h3')       selektiert alle h3-Elemente
document.querySelector('.ci')         gibt das erste Element mit der Klasse .ci zurück
document.querySelectorAll('.ci a')    gibt alle a-Elemente unterhalb der Klasse .ci zurück
document.querySelector('#postheader') gibt das Element mit id="postheader" zurück
document.querySelectorAll('li:nth-child(odd)')    alle li-Elemente mit ungeradem Index                    

querySelector und querySelectorAll sind flexibler als document.getElementById() und getElementsByTagName() und obendrein schneller.

Beide Methoden können sowohl den ganzen DOM-Baum als auch einen einzelnen Zweig parsen. Jeder CSS-Selektor funktioniert als Parameter.

var bluetext = document.querySelector('h3[style="color:blue"]').innerText;

querySelectorAll

querySelectorAll() gibt alle Fundstellen als statische NodeList – staticNodeList – zurück. Eine NodeList sieht aus wie ein Array, verhält sich ähnlich wie ein Array, ist aber kein Array.

Eine statische NodeList ist von folgenden Änderungen des DOM-Baums nicht betroffen.

Die Eigenschaft length liefert die Anzahl der Fundstellen. Javascript kann also durch die Liste der Fundstellen wie bei einem Array iterieren.

var el = document.querySelectorAll ('li:nth-child(odd)');
for (var i=0; i<el.length; i++) {
	Mach was mit den li-Elementen mit ungeradem Index
}

Das ist nicht so komfortabel wie die Interation über alle Elemente in jQuery.

jQuery
$(selector).each(function(i, el){

});
Javascript
var el = document.querySelectorAll(selector);
Array.prototype.forEach.call(elements, function(el, i){

});

Ab IE 9

Das bequeme each() aus jQuery wird in Javascript durch Array.prototype.forEach.call() ersetzt: querySelectorAll gibt kein Array zurück, sondern eine NodeList, die nur aussieht als wäre sie ein Array.

querySelector() und querySelectorAll() lösen komplexe CSS-Query-Strings auf, die klassische Methoden wie getElementById() und getElementByTagName nur mit großem Aufwand umsetzen können. In einfachen Anwendungen ersetzen sie das Einbinden von jQuery (You might noch need jQuery). jQuery hat allerdings über die CSS-Querys hinaus Filter wie filter(), find(), children(), parent(), map(), not() und gleicht Browser-Inkonsistenzen aus.

querySelector und Pseudo-Elemente

Vor querySelector und querySelectorAll konnte Javascript keine Pseudo-Elemente wie ::before und ::after erreichen. In der Tat schafft das nicht einmal jQuery.

Damit erschließen wir Effekte, die durch Pseudo-Klassen wie :hover zustande kommen, für die mobilen Geräten.

.circle:before {
	box-shadow: inset 150px 0 0 hsla(30,70%,50%,0.2), 
                inset 0 150px 0 hsla(30,70%,50%,0.2), 
                inset -150px 0 0 hsla(30,70%,50%,0.2), 
                inset 0 -150px 0 hsla(30,70%,50%,0.2);
}

Mit getComputedStyle funktioniert dann der Zugriff auf Pseudo-Elemente (gefunden bei treehouse):

var boxShadow = window.getComputedStyle (
    document.querySelector('.circle'), ':before'
).getPropertyValue('box-shadow');

Da wir hier ein Pseudo-Element vor uns haben und Pseudo-Elemente kein Teil des DOMs sind, kann Javascript die CSS-Regel nicht ohne Weiteres ändern.

Es gibt zwar getComputedStyle, aber kein setComputedStyle. Javascript kann allerdings ein style-Element anlegen und das Pseudo-Element mit innerHTML beschreiben. querySelector hängt das style-Element anschließend mit appendChild an das Ende von head.