Jag behöver en funktion för att få värdet på namnet attributet för varje element med class =” class ”. Jag undrade vad som är det bästa sättet att göra detta, prestationsmässigt.
För närvarande använder jag jQuery och gör det så här:
$("#Button").click(function() { var myElements = $(".class"); for (var i=0;i<myElements.length;i++) { alert(myElements.eq(i).attr("name")); } });
Alert är bara för att visa vad det gör, förstås. För följande HTML:
<input type="checkbox" class="class" name="1"> <input type="checkbox" class="nope" name="2"> <input type="checkbox" class="class" name="3">
Det skulle ge ut:
alert("1") alert("3")
Jag undrade om det skulle gå snabbare att använda rent Javascript, eller om det finns något annat (bättre) sätt att göra det. Jag ber om ursäkt om denna fråga inte finns på den här webbplatsen räckvidd, flytta det till Stackoverflow om så är fallet.
Kommentarer
- Byt alltid varningen med console.log Alert blockerar kod körning och tvingar dig att klicka på ok eller trycka på enter så många gånger som resultatet hittas.
Svar
Pure JS vs jQuery
Pure JavaScript kommer att bli betydligt snabbare som du kan se genom att denna jsPerf som gropar document.getElementByClassName
mot jQuery-väljaren. Här är resultaten för Chrome 25:
-
$(".class")
– 4355 operationer per sekund -
getElementsByClassName("class")
– 94636 operationer per sekund
Som du kan se är jQuery-alternativet ungefär 22 gånger långsammare än den rena JavaScript-motsvarigheten för denna enkla operation. Du kan enkelt se varför detta är fallet genom att kolla in jQuery-utvecklingskälla , eftersom jQuery ”väljarfunktion” är så allmän att den behöver göra mycket kontrollerar om ingången är innan den kan agera på den.
Ren JS-implementering
Jag har lämnat jQuery click
eftersom det ser ut som om du redan har ett beroende av jQuery, så det är ingen anledning att ändra sättet du kopplar upp dina händelser.
$("#Button").click(function() { var items = document.getElementsByClassName("class"); for (var i = 0; i < items.length; i++) alert(items[i].name); });
getElementsByClassName
Observera också att jag använde getElementsByClassName
. Det är ganska viktigt att välja den perfekta väljaren om du bryr dig om prestanda. Eftersom vi bryr oss om alla element med en viss klass kan vi omedelbart avfärda de andra som getElementsByTagName
och querySelectorAll
och välja den funktion som byggdes för att hitta element i en viss klass.
jQuery-implementering
Detta skulle vara min implementering med jQuery, lägg märke till att jag inte brydde mig om att få jQuery-objektet för this
(dvs. $(this)
) eftersom det vanliga JavaScript-attributet är mycket lättare i detta fall.
$("#Button").click(function() { $(".class").each(function() { alert(this.name); }); });
Kommentarer
- Perfekt. Även om jag gillar jQuery I undvik det när det enkelt kan göras med rent Javascript. Av någon anledning kunde jag inte ' t få det att fungera förut, troligen något dumt syntaxfel.
- Ditto. Det tar lite tid att ta sig runt alla JS-funktioner, se till att du ' tittar på webbläsarfel för att felsöka det.
- Beroende på vad du vill göra med
name
kan du använda jQuery ' s.map()
för att få en matris. - @RoToRa Jag tror att det skulle vara lika användbart som
$(".class").each( function() {//stuff});
i det här fallet, men tack!
Svar
Istället för att lagra dem i en array kan du använda funktionen $.each
för att gå igenom dem. Så här:
$("#Button").click(function() { $(".class").each( function() { alert( $(this).attr("name") ); } });
Svar
Att göra detta är i ”rent” JavaScript, du gör något liknande om du använder ES6-syntax:
var elements = document.getElementsByClassName("class"); elements.forEach(e => { alert(e.name) });
För alla webbläsare som inte stöder ES6 (inklusive alla versioner av IE):
var elements = document.getElementsByClassName("class"); elements.forEach(function(e) { alert(e.name); });
Om IE8-stöd krävs:
var elements = document.querySelectorAll(".class"); for (var i = 0; i < elements.length; i++) { alert(elements[i].name); }
Vilket blir lite snabbare jämfört med att använda jQuery . Dock kommer jQuery fortfarande att vara den kortaste koden:
$(".class").each(e => { alert(e.name); });
Kommentarer
- Tack. Jag kanske har att göra med 100+ element, eftersom detta kommer att användas i en kommentar. Jag ' Jag gör lite benchmarking med båda koderna och ger lite feedback när allt är klart. Jag undrade om det skulle vara möjligt att använda
document.getElementsByClassName()
och en for-loop istället. Jag försökte men kunde inte ' få det att fungera.Jag använde samma för loop ochdocument.getElementsByClassName('class')[i].name
Svar
Du kan använda document.querySelectorAll
för att hämta önskade element:
var namedEls = document.querySelectorAll("input.class"); for (var i=0;i<namedEls.length;i+=1){ console.log(namedEls[i].name); } //=> 1, 3
Eller som en liner för att hämta namn som Array
:
var names = [].slice.call(document.querySelectorAll("input.class")) .map(function(el){return el.name}); //=> names is now [1,3]
Kommentarer
- Varför
input[class="class"]
och inteinput.class
? (Om du inte specifikt vill utesluta element med flera klasser.) - Ingen särskild anledning, så ändrade svaret. Ändrar inte ' resultaten.
Svar
parent.querySelectorAll([name="value"]);
Beroende på din kunskap om din Dom kan vara supereffektiv; du kan välja den överordnade noden du vill söka i eller bara gå till dokument om du inte har någon specifik Dom-kunskap.
Om du använder anpassade element eller anpassat namnutrymme kan det vara mycket kraftfullt och kräver inga bibliotekstillägg. Fungerar i alla moderna webbläsare.
Plattformen växer och kan nu göra fantastiska saker.