DOM-technieken: ouder-, kind- en buurelementen. Kindkiezers

Complexe en zware webapplicaties zijn tegenwoordig gemeengoed geworden. Cross-browser en eenvoudig te gebruiken bibliotheken zoals jQuery kunnen met hun rijke functionaliteit enorm helpen bij het direct manipuleren van de DOM. Het is daarom niet verrassend dat veel ontwikkelaars dergelijke bibliotheken vaker gebruiken dan dat ze met de native DOM API werken, waarmee er veel problemen waren. Hoewel browserverschillen nog steeds een probleem zijn, verkeert de DOM er nu beter voor dan vijf tot zes jaar geleden, toen jQuery aan populariteit won.

In dit artikel demonstreer ik de HTML-manipulatiemogelijkheden van de DOM, met de nadruk op ouder-, kind- en buurrelaties. Tot slot zal ik informatie geven over browserondersteuning voor deze functies, maar houd er rekening mee dat een bibliotheek als jQuery nog steeds een goede optie is vanwege de aanwezigheid van bugs en inconsistenties in de implementatie van native functionaliteit.

Onderliggende knooppunten tellen

Ik gebruik de volgende HTML-opmaak voor deze demonstratie, en we zullen deze in het artikel een paar keer wijzigen:

  • Voorbeeld één
  • Voorbeeld twee
  • Voorbeeld drie
  • Voorbeeld vier
  • Voorbeeld vijf
  • Voorbeeld zes

Var mijnLijst = document.getElementById("mijnLijst"); console.log(mijnLijst.kinderen.lengte); // 6 console.log(mijnList.childElementCount); // 6

Zoals u kunt zien, zijn de resultaten hetzelfde, hoewel de gebruikte technieken verschillend zijn. In het eerste geval maak ik gebruik van de kindereigendom. Dit is een alleen-lezen eigenschap en retourneert de verzameling HTML-elementen die zich in het aangevraagde element bevinden; Om hun aantal te tellen, gebruik ik de lengte-eigenschap van deze verzameling.

In het tweede voorbeeld gebruik ik de methode childElementCount, waarvan ik denk dat het een nettere en potentieel beter onderhoudbare manier is (bespreek dit later meer, ik denk niet dat je problemen zult hebben om te begrijpen wat het doet).

Ik zou kunnen proberen childNodes.length te gebruiken (in plaats van child.length), maar kijk eens naar het resultaat:

Var mijnLijst = document.getElementById("mijnLijst"); console.log(mijnList.childNodes.length); // 13

Het retourneert 13 omdat childNodes een verzameling is van alle knooppunten, inclusief spaties. Houd hier rekening mee als u zich zorgen maakt over het verschil tussen onderliggende knooppunten en knooppunten van onderliggende elementen.

Controleren van het bestaan ​​van onderliggende knooppunten

Om te controleren of een element onderliggende knooppunten heeft, kan ik de methode hasChildNodes() gebruiken. De methode retourneert een Booleaanse waarde die hun aanwezigheid of afwezigheid aangeeft:

Var mijnLijst = document.getElementById("mijnLijst"); console.log(mijnList.hasChildNodes()); // WAAR

Ik weet dat mijn lijst onderliggende knooppunten heeft, maar ik kan de HTML wijzigen zodat die er niet meer zijn; De opmaak ziet er nu als volgt uit:

En hier is het resultaat van het opnieuw uitvoeren van hasChildNodes():

Console.log(mijnList.hasChildNodes()); // WAAR

De methode retourneert nog steeds waar. Hoewel de lijst geen elementen bevat, bevat deze wel een spatie, wat een geldig knooppunttype is. Deze methode houdt rekening met alle knooppunten, niet alleen met elementknooppunten. Om ervoor te zorgen dat hasChildNodes() false retourneert, moeten we de markup opnieuw wijzigen:

En nu wordt het verwachte resultaat weergegeven in de console:

Console.log(mijnList.hasChildNodes()); // vals

Als ik weet dat ik mogelijk witruimte tegenkom, controleer ik natuurlijk eerst of er onderliggende knooppunten bestaan ​​en gebruik ik vervolgens de eigenschap nodeType om te bepalen of er elementknooppunten tussen zitten.

Onderliggende elementen toevoegen en verwijderen

Er zijn technieken die u kunt gebruiken om elementen aan de DOM toe te voegen en te verwijderen. De bekendste daarvan is gebaseerd op een combinatie van de methoden createElement() en appendChild().

Var myEl = document.createElement("div"); document.body.appendChild(mijnEl);

In dit geval creëer ik

met behulp van de createElement() methode en deze vervolgens toe te voegen aan body . Het is heel eenvoudig en je hebt deze techniek waarschijnlijk al eerder gebruikt.

Maar in plaats van een speciaal gemaakt element in te voegen, kan ik ook appendChild() gebruiken en eenvoudigweg het bestaande element verplaatsen. Laten we zeggen dat we de volgende opmaak hebben:

  • Voorbeeld één
  • Voorbeeld twee
  • Voorbeeld drie
  • Voorbeeld vier
  • Voorbeeld vijf
  • Voorbeeld zes

Voorbeeld tekst

Ik kan de locatie van de lijst wijzigen met de volgende code:

Var mijnList = document.getElementById("mijnLijst"), container = document.getElementById("c"); container.appendChild(mijnLijst);

De uiteindelijke DOM ziet er als volgt uit:

Voorbeeld tekst

  • Voorbeeld één
  • Voorbeeld twee
  • Voorbeeld drie
  • Voorbeeld vier
  • Voorbeeld vijf
  • Voorbeeld zes

Merk op dat de volledige lijst van zijn plaats is verwijderd (boven de alinea) en vervolgens erna is ingevoegd vóór de afsluitende hoofdtekst . Hoewel de methode appendChild() doorgaans wordt gebruikt om elementen toe te voegen die zijn gemaakt met createElement() , kan deze ook worden gebruikt om bestaande elementen te verplaatsen.

Ik kan een onderliggend element ook volledig uit de DOM verwijderen met behulp van removeChild() . Zo verwijdert u onze lijst uit het vorige voorbeeld:

Var mijnList = document.getElementById("mijnLijst"), container = document.getElementById("c"); container.removeChild(mijnLijst);

Het element is nu verwijderd. De methode removeChild() retourneert het verwijderde element, zodat ik het kan opslaan voor het geval ik het later nodig heb.

Var myOldChild = document.body.removeChild(mijnLijst); document.body.appendChild(myOldChild);

Er is ook een methode ChildNode.remove() die relatief recentelijk aan de specificatie is toegevoegd:

Var mijnLijst = document.getElementById("mijnLijst"); mijnLijst.verwijder();

Deze methode retourneert het externe object niet en werkt niet in IE (alleen Edge). En beide methoden verwijderen tekstknooppunten op dezelfde manier als elementknooppunten.

Onderliggende elementen vervangen

Ik kan een bestaand onderliggend element vervangen door een nieuw element, ongeacht of dat nieuwe element bestaat of dat ik het helemaal opnieuw heb gemaakt. Hier is de opmaak:

Voorbeeldtekst

Var myPar = document.getElementById("par"), myDiv = document.createElement("div"); mijnDiv.className = "voorbeeld"; myDiv.appendChild(document.createTextNode("Nieuwe elementtekst")); document.body.replaceChild(mijnDiv, mijnPar);

Nieuwe elementtekst

Zoals u kunt zien, heeft de methode ReplaceChild() twee argumenten nodig: het nieuwe element en het oude element dat het vervangt.

Ik kan deze methode ook gebruiken om een ​​bestaand element te verplaatsen. Kijk eens naar de volgende HTML:

Voorbeeldtekst 1

Voorbeeldtekst 2

Voorbeeldtekst 3

Ik kan de derde alinea vervangen door de eerste alinea met behulp van de volgende code:

Var mijnPar1 = document.getElementById("par1"), myPar3 = document.getElementById("par3"); document.body.replaceChild(mijnPar1, mijnPar3);

Nu ziet de gegenereerde DOM er als volgt uit:

Voorbeeldtekst 2

Voorbeeldtekst 1

Het selecteren van specifieke kinderen

Er zijn verschillende manieren om een ​​specifiek element te selecteren. Zoals eerder getoond, kan ik beginnen met het gebruik van de kindercollectie of de eigenschap childNodes. Maar laten we eens kijken naar andere opties:

De eigenschappen firstElementChild en lastElementChild doen precies wat hun naam suggereert: het eerste en het laatste onderliggende element selecteren. Laten we terugkeren naar onze opmaak:

  • Voorbeeld één
  • Voorbeeld twee
  • Voorbeeld drie
  • Voorbeeld vier
  • Voorbeeld vijf
  • Voorbeeld zes

Ik kan het eerste en laatste element selecteren met behulp van deze eigenschappen:

Var mijnLijst = document.getElementById("mijnLijst"); console.log(mijnList.firstElementChild.innerHTML); // "Voorbeeld één" console.log(myList.lastElementChild.innerHTML); // "Voorbeeld zes"

Ik kan ook de eigenschappen previousElementSibling en nextElementSibling gebruiken als ik andere onderliggende elementen dan de eerste of laatste wil selecteren. Dit wordt gedaan door de eigenschappen firstElementChild en lastElementChild te combineren:

Var mijnLijst = document.getElementById("mijnLijst"); console.log(mijnList.firstElementChild.nextElementSibling.innerHTML); // "Voorbeeld twee" console.log(myList.lastElementChild.previousElementSibling.innerHTML); // "Voorbeeld vijf"

Er zijn ook vergelijkbare eigenschappen firstChild , lastChild , previousSibling en nextSibling , maar deze houden rekening met alle typen knooppunten, niet alleen met elementen. Over het algemeen zijn eigenschappen die alleen elementknooppunten in aanmerking nemen nuttiger dan eigenschappen die alle knooppunten selecteren.

Inhoud in de DOM invoegen

Ik heb al gekeken naar manieren om elementen in de DOM in te voegen. Laten we verder gaan met een soortgelijk onderwerp en een kijkje nemen naar de nieuwe functies voor het invoegen van inhoud.

Ten eerste is er een eenvoudige methode insertBefore(), vergelijkbaar met ReplaceChild(). Deze heeft twee argumenten nodig en werkt met zowel nieuwe als bestaande elementen. Hier is de opmaak:

  • Voorbeeld één
  • Voorbeeld twee
  • Voorbeeld drie
  • Voorbeeld vier
  • Voorbeeld vijf
  • Voorbeeld zes

Voorbeeld paragraaf

Let op de paragraaf die ik eerst ga verwijderen en vervolgens vóór de lijst invoeg, alles in één klap:

Var mijnList = document.getElementById("mijnLijst"), container = document.getElementBy("c"), myPar = document.getElementById("par"); container.insertBefore(mijnPar, mijnLijst);

In de resulterende HTML verschijnt de alinea vóór de lijst en dit is een andere manier om het element in te sluiten.

Voorbeeld paragraaf

  • Voorbeeld één
  • Voorbeeld twee
  • Voorbeeld drie
  • Voorbeeld vier
  • Voorbeeld vijf
  • Voorbeeld zes

Net als ReplaceChild() heeft insertBefore() twee argumenten nodig: het element dat moet worden toegevoegd en het element waarvoor we het willen invoegen.

Deze methode is eenvoudig. Laten we nu een krachtigere invoegmethode proberen: de methode insertAdjacentHTML().

Ik denk dat veel mensen het weten contextuele selectors in CSS. Ze worden het vaakst gebruikt, maar ervaren lay-outontwerpers weten heel goed dat contextuele selectors soms bepaalde problemen met zich meebrengen. Dit probleem is te wijten aan het feit dat er in de structuur van een element veel identieke elementen in elkaar kunnen zijn genest. En u moet de stijl niet op alle geneste elementen toepassen, maar alleen op het onmiddellijke onderliggende element. Dit is waar ze voor gebruikt worden onderliggende selectors in CSS.

Om het probleem duidelijker te maken, geven we een klein voorbeeld. Laten we er zo één hebben HTML code:



Eerste paragraaf



Tweede paragraaf


En onze taak is om het alleen rood te maken " Tweede paragraaf". Als we schrijven met behulp van een contextselector:

Houder p (
kleur rood;
}

Dan worden beide alinea’s rood, wat we helemaal niet nodig hebben. Dit probleem kan heel eenvoudig worden opgelost met behulp van onderliggende selectors in CSS:

Houder > p (
kleur rood;
}

Dat is alles, nu hebben we alleen maar rood " Tweede paragraaf". Aangezien deze specifieke paragraaf een direct kind is van .container. A " Eerste paragraaf" is een kind van intern div Het wordt dus niet beïnvloed door de onderliggende selector.

Dit is hoe dergelijke problemen gemakkelijk kunnen worden opgelost, maar er is één groot nadeel onderliggende selectors in CSS- ze werken niet in browsers Internet Explorer. Om deze reden is het gebruik ervan zeer ongewenst. Maar als je het ergens ineens tegenkomt, weet je nu wat dit type selector betekent en wat het doet.

De hoofdtaak van deze selector volgt uit de naam en is het verkrijgen van toegang tot een onderliggend element. Weergegeven met een primitief ">"-teken, dat het onderliggende element aan het bovenliggende element koppelt. Het is ook vermeldenswaard dat er eenvoudige selectors worden gebruikt. Beschouw als voorbeeld de volgende codering:

Element > ul (opvulling-top: 20px; )

Deze codering betekent dat een lijst die in een element is genest, een opvulling van 20 pixels vanaf de bovenrand heeft. De aanwezigheid van het pictogram “>” in dit item geeft aan dat de regel alleen van toepassing is op lijsten op het eerste nestniveau.

Een gedetailleerde analyse van hoe de kindelementselector werkt

Een selector voor onderliggende elementen heeft vergelijkbare eigenschappen als het concept van een selector voor onderliggende elementen. Er is echter een karakteristiek kenmerk dat het fundamentele verschil tussen deze operaties laat zien. Het ligt in het feit dat de invloed van de descendant-selector zich uitstrekt tot absoluut alle elementen, terwijl de kind-selector de positiestijlen van het eerste classificatieniveau ondergeschikt maakt.

Het volgende voorbeeld zal u helpen het werk van de operator voor kinderselectie duidelijker te evalueren:

Div > p ( kleur: #ff0000; /* rood */ )

< div>Deze regel heeft standaard zwarte tekst.< span>Deze lijn wordt rood vanwege het feit dat p een onderliggende tag is voor div. < p>Opnieuw zien we zwarte letters.< span>Hier zien we ook zwarte symbolen, omdat voor deze span de ouder de p-tag is.

Dit voorbeeld bevestigt de werking van de kinderselectoroperator volgens de mate van nesting.

Beperking voor het gebruik van de operator voor onderliggende selectie

Het is vermeldenswaard dat deze bewerking door alle browsers wordt ondersteund, behalve de legendarische Internet Explorer 6. Ik denk dat maar weinig mensen deze browser gebruiken, maar als er unieke zijn, dan is er een uitweg voor hen, die zal worden beschreven in een apart artikel.

Waarom wordt het gebruikt?

Programmeurs wenden zich tot selectors voor onderliggende elementen wanneer ze hun eigen unieke stijl aan geneste elementen moeten toewijzen. Bovendien kan het gebruik van deze selector de hoeveelheid CSS verminderen, wat de leesbaarheid van het document ten goede komt. Zoals de praktijk laat zien, wordt deze bewerking het vaakst gebruikt bij het maken van vervolgkeuzemenu's.

De kiezer voor onderliggende elementen wordt ook gebruikt om unieke stijlen toe te wijzen aan elementen waarvan de ouders al bekend zijn. Met andere woorden:

Hoofd > kop ( /* decoratie geldt alleen voor de hoofdkop */ }

Dit voorbeeld is geldig in gevallen waarin de headertag wordt gebruikt om artikeltitels te markeren. In ons geval stellen we het ontwerp alleen in voor de hoofdkop en hebben we geen invloed op de secundaire koptekst. Met deze techniek kunt u ook voorkomen dat u onnodige ID's gebruikt, wat op zijn beurt het gewicht van het CSS-bestand lichter maakt en het leesbaarder maakt.

Opsommen

De operator voor onderliggende elementen kan dus niet alleen worden gebruikt om vervolgkeuzemenu's te ontwerpen, maar ook om uw internetbron enigszins te optimaliseren voor het werk van zoekrobots.