javascript - Hva returnerer querySelectorAll() og getElementsBy*() metodene?
Fungerer getElementsByClassName (og lignende funksjoner som getElementsByTagName og querySelectorAll) på samme måte som getElementById eller returnerer de et array med elementer?
Grunnen til at jeg spør er fordi jeg prøver å endre stilen til alle elementer ved å bruke getElementsByClassName. Se nedenfor.
//doesn't work
document.getElementsByClassName('myElement').style.size = '100px';
//works
document.getElementById('myIdElement').style.size = '100px';
Svar #1
Koden din for getElementById fungerer siden ID-er må være unike, og derfor returnerer funksjonen alltid nøyaktig ett element (eller null hvis ingen ble funnet).
Metodene getElementsByClassName, getElementsByName, getElementsByTagName og getElementsByTagNameNS returnerer imidlertid en iterabel samling av elementer.
Metodenavnene gir hintet: getElement impliserer entall, mens getElements impliserer flertall.
Metoden querySelector returnerer også ett enkelt element, og querySelectorAll returnerer en itererbar samling.
Den iterable samlingen kan enten være en NodeList eller en HTMLCollection.
getElementsByName og querySelectorAll er begge spesifisert til å returnere en NodeList; de andre getElementsBy*-metodene er spesifisert til å returnere en HTMLCollection, men vær oppmerksom på at noen nettleserversjoner implementerer dette forskjellig.
Begge disse samlingstypene tilbyr ikke de samme egenskapene som Elementer, Nodene eller lignende typer tilbyr; derfor feiler det å lese style fra document.getElements…(…). Med andre ord: en NodeList eller en HTMLCollection har ikke en style; kun et Element har en style.
Disse "array-lignende" samlingene er lister som inneholder null eller flere elementer, som du må iterere over for å få tilgang til dem. Selv om du kan iterere over dem på en måte som ligner en array, merk at de er forskjellige fra Arrayer.
I moderne nettlesere kan du konvertere disse iterablene til et ordentlig Array med Array.from; deretter kan du bruke forEach og andre Array-metoder, f.eks. iterasjonsmetoder:
Array.from(document.getElementsByClassName("myElement"))
.forEach((element) => element.style.size = "100px");
I gamle nettlesere som ikke støtter Array.from eller iterasjonsmetodene, kan du fortsatt bruke Array.prototype.slice.call. Da kan du iterere over det som du ville gjort med et ekte array:
var elements = Array.prototype.slice
.call(document.getElementsByClassName("myElement"));
for(var i = 0; i < elements.length; ++i){
elements[i].style.size = "100px";
}
Du kan også iterere over NodeList eller HTMLCollection selv, men vær oppmerksom på at i de fleste tilfeller er disse samlingene live (MDN-dokumentasjon, DOM-spesifikasjon), dvs. de oppdateres etter hvert som DOM endres. Så hvis du setter inn eller fjerner elementer mens du løper gjennom dem, sørg for å ikke ved et uhell hoppe over noen elementer eller skape en uendelig løkke. MDN-dokumentasjonen bør alltid merke dersom en metode returnerer en live-samling eller en statisk.
For eksempel tilbyr en NodeList noen iterasjonsmetoder som forEach i moderne nettlesere:
document.querySelectorAll(".myElement")
.forEach((element) => element.style.size = "100px");
En enkel for-løkke kan også brukes:
var elements = document.getElementsByClassName("myElement");
for(var i = 0; i < elements.length; ++i){
elements[i].style.size = "100px";
}
Sidebemerkning: .childNodes gir en live NodeList og .children gir en live HTMLCollection, så disse to getterne må også håndteres forsiktig.
Det finnes noen biblioteker som jQuery som gjør DOM-spørring litt kortere og skaper et lag av abstraksjon over «ett element» og «en samling av elementer»:
$(".myElement").css("size", "100px");
Svar #2
Du bruker et array som et objekt, forskjellen mellom getElementbyId og getElementsByClassName er at:
getElementbyIdvil returnere et Element-objekt eller null hvis ingen element med ID-en finnesgetElementsByClassNamevil returnere en levende HTMLCollection, muligens av lengde 0 hvis ingen matchende elementer blir funnet
getElementsByClassName
Metoden
getElementsByClassName(classNames)tar en streng som inneholder et uordnet sett med unike, mellomromseparerte token som representerer klasser. Når den kalles, må metoden returnere et levendeNodeList-objekt som inneholder alle elementene i dokumentet som har alle klassene spesifisert i det argumentet, etter å ha hentet klassene ved å dele en streng på mellomrom. Hvis det ikke er spesifisert noen token i argumentet, må metoden returnere en tom NodeList.
https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#getelementsbyclassname
getElementById
Metoden getElementById() får tilgang til det første elementet med den spesifiserte id-en.
https://developer.mozilla.org/no/docs/Web/API/Document/getElementById
i koden din linjene:
1- document.getElementsByClassName('myElement').style.size='100px';
vil IKKE fungere som forventet, fordi getElementByClassName vil returnere et array, og arrayet vil IKKE ha style-egenskapen, du kan få tilgang til hvert element ved å iterere gjennom dem.
Derfor fungerte funksjonen getElementById for deg, denne funksjonen vil returnere det direkte objektet. Derfor vil du kunne få tilgang til style-egenskapen.
Svar #3
ES6 tilbyr Array.from() metoden, som lager en ny Array-instans fra et array-lignende eller itererbart objekt.
let boxes = document.getElementsByClassName('box');
setTimeout(() => {
Array.from(boxes).forEach(v => v.style.background = 'green');
console.log(Array.from(boxes));
}, 500);.box {
width: 50px;
height: 50px;
margin: 5px;
background: blue;
display: inline-block;
}<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>Som du kan se i kodesnutten, etter å ha brukt Array.from()-funksjonen, kan du deretter manipulere hvert element.
$('.box').css({'background':'green'});.box {
width: 50px;
height: 50px;
margin: 5px;
background: blue;
display: inline-block;
}<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>Svar #4
Følgende beskrivelse er hentet fra denne siden:
Metoden getElementsByClassName() returnerer en samling av alle elementer i dokumentet med det spesifiserte klassenavnet, som et NodeList-objekt.
NodeList-objektet representerer en samling av noder. Nodene kan nås ved hjelp av indeksnumre. Indeksen starter på 0.
Tips: Du kan bruke length-egenskapen til NodeList-objektet for å finne antall elementer med et spesifisert klassenavn, og deretter kan du gå gjennom alle elementene og hente informasjonen du ønsker.
Så, som en parameter vil getElementsByClassName akseptere et klassenavn.
Hvis dette er HTML-kroppen din:
<div id="first" class="menuItem"></div>
<div id="second" class="menuItem"></div>
<div id="third" class="menuItem"></div>
<div id="footer"></div>
da vil var menuItems=document.getElementsByClassName('menuItem') returnere en samling (ikke et array) av de 3 øverste <div>-ene, siden de samsvarer med det angitte klassenavnet.
Du kan deretter iterere over denne nodsamlingen (<div>-er i dette tilfellet) med:
for (var menuItemIndex = 0 ; menuItemIndex < menuItems.length ; menuItemIndex ++) {
var currentMenuItem = menuItems[menuItemIndex];
// do stuff with currentMenuItem as a node.
}
Vennligst referer til dette innlegget for mer om forskjellene mellom elementer og noder.
