Potrzebuję funkcji, aby uzyskać wartość atrybutu name każdego elementu z class =” class „. Zastanawiałem się, jak to zrobić najlepiej pod względem wydajności.
Obecnie używam jQuery i robię to w ten sposób:
$("#Button").click(function() { var myElements = $(".class"); for (var i=0;i<myElements.length;i++) { alert(myElements.eq(i).attr("name")); } });
Alert ma oczywiście pokazać, co robi. Dla następującego kodu HTML:
<input type="checkbox" class="class" name="1"> <input type="checkbox" class="nope" name="2"> <input type="checkbox" class="class" name="3">
Wystąpi:
alert("1") alert("3")
Zastanawiałem się, czy użycie czystego Javascript nie byłoby szybsze, czy jest inny (lepszy) sposób na zrobienie tego. Przepraszam, jeśli tego pytania nie ma na tej stronie. zakres, jeśli tak jest, przenieś go do Stackoverflow.
Komentarze
- Zawsze zamieniaj alert na console.log Alert to kod blokujący wykonanie i wymusza kliknięcie OK lub naciśnięcie klawisza Enter tyle razy, ile zostanie znaleziony wynik.
Odpowiedz
Czysty JS vs jQuery
Czysty JavaScript będzie znacznie szybszy, co widać po tym jsPerf , który oznacza document.getElementByClassName
vs selektor jQuery. Tutaj to wyniki dla przeglądarki Chrome 25:
-
$(".class")
– 4355 operacje na sekundę -
getElementsByClassName("class")
– 94636 operacje na sekundę
Jak widać, dla tej prostej operacji opcja jQuery jest około 22 razy wolniejsza niż odpowiednik w czystym JavaScript. Możesz łatwo zobaczyć, dlaczego tak jest, sprawdzając źródło programowania jQuery , ponieważ „funkcja selektora” jQuery jest tak ogólna, że wymaga wielu czynności sprawdza, jakie są dane wejściowe, zanim będzie mógł na nich działać.
Implementacja czystego JS
Opuściłem zdarzenie jQuery click
wygląda na to, że masz już zależność od jQuery, więc nie ma sensu zmieniać sposobu łączenia zdarzeń.
$("#Button").click(function() { var items = document.getElementsByClassName("class"); for (var i = 0; i < items.length; i++) alert(items[i].name); });
getElementsByClassName
Zwróć też uwagę, że użyłem getElementsByClassName
. Wybór idealnego selektora jest bardzo ważny, jeśli zależy Ci na wydajności. Ponieważ zależy nam na wszystkich elementach z określoną klasą, możemy natychmiast odrzucić pozostałe, takie jak getElementsByTagName
i querySelectorAll
, i wybrać funkcję, która została utworzona do znajdowania elementów określonej klasy.
Implementacja jQuery
To byłaby moja implementacja wykorzystująca jQuery, zauważ, że nie zawracałem sobie głowy uzyskaniem obiektu jQuery dla this
(tj. $(this)
), ponieważ zwykły atrybut JavaScript jest w tym przypadku znacznie łatwiejszy.
$("#Button").click(function() { $(".class").each(function() { alert(this.name); }); });
Komentarze
- Idealnie. Chociaż lubię jQuery I unikaj tego, gdy można to łatwo zrobić za pomocą czystego JavaScript. Z jakiegoś powodu nie mogłem ' t sprawić, by działało wcześniej, prawdopodobnie jakiś głupi błąd składni.
- Jak wyżej. Zajmuje trochę czasu, aby zapoznać się ze wszystkimi funkcjami JS, upewnij się, że ' sprawdzasz błędy przeglądarki, aby ją zdebugować.
- W zależności od tego, co chcesz zrobić z
name
s, możesz użyć jQuery ' s.map()
, aby uzyskać tablicę. - @RoToRa Myślę, że byłoby to tak samo przydatne jak
$(".class").each( function() {//stuff});
w tym przypadku, ale dzięki!
Odpowiedz
Zamiast przechowywać je w tablicy, możesz użyć funkcji $.each
do przeglądania ich w pętli. W ten sposób:
$("#Button").click(function() { $(".class").each( function() { alert( $(this).attr("name") ); } });
Odpowiedź
Aby to zrobić w „czystym” JavaScript, robisz coś takiego, jeśli używasz składni ES6:
var elements = document.getElementsByClassName("class"); elements.forEach(e => { alert(e.name) });
Dla przeglądarek nie obsługujących ES6 (w tym wszystkich wersji IE):
var elements = document.getElementsByClassName("class"); elements.forEach(function(e) { alert(e.name); });
Jeśli wymagana jest obsługa IE8:
var elements = document.querySelectorAll(".class"); for (var i = 0; i < elements.length; i++) { alert(elements[i].name); }
Co będzie nieco szybsze w porównaniu z użyciem jQuery . Jednak jQuery nadal będzie najkrótszym kodem:
$(".class").each(e => { alert(e.name); });
Komentarze
- Dziękuję. Mogę mieć do czynienia z ponad 100 elementami, ponieważ zostanie to użyte w sekcji komentarzy. ' przeprowadzę testy porównawcze obu kodów i przekażę informacje zwrotne, gdy wszystko będzie gotowe. Zastanawiałem się, czy byłoby możliwe użycie zamiast tego
document.getElementsByClassName()
i pętli for. Próbowałem, ale nie ' nie udało mi się uruchomić tego.Użyłem tego samego dla pętli idocument.getElementsByClassName('class')[i].name
Odpowiedź
Możesz użyć document.querySelectorAll
, aby pobrać żądane elementy:
var namedEls = document.querySelectorAll("input.class"); for (var i=0;i<namedEls.length;i+=1){ console.log(namedEls[i].name); } //=> 1, 3
Lub jako jedna linijka do pobierania nazw jako Array
:
var names = [].slice.call(document.querySelectorAll("input.class")) .map(function(el){return el.name}); //=> names is now [1,3]
Komentarze
- Dlaczego
input[class="class"]
, a nieinput.class
? (Chyba że chcesz konkretnie wykluczyć elementy z wieloma klasami.) - Bez konkretnego powodu, więc zmieniłem odpowiedź. Nie ' nie zmienia wyników.
Odpowiedź
parent.querySelectorAll([name="value"]);
W zależności od twojej wiedzy o Dom, może być super wydajne; możesz wybrać węzeł nadrzędny do przeszukania lub po prostu przejść do dokumentu, jeśli nie masz konkretnej wiedzy o Dom.
Jeśli używasz elementów niestandardowych lub niestandardowej przestrzeni nazw, może to być bardzo potężne i nie wymaga żadnych dodatków do biblioteki. Działa we wszystkich nowoczesnych przeglądarkach.
Platforma rośnie i może teraz robić niesamowite rzeczy.