Różnica między $ (document.body) a $ ('body')

105

Jestem początkującym jQuery i przeglądając kilka przykładów kodu, które znalazłem:

$(document.body) i $('body')

Czy jest jakaś różnica między tymi dwoma?

ashleedawg
źródło
1
Jeden jest szybszy, jednak biorąc pod uwagę, że nigdy nie zostałby wywołany więcej niż kilka razy na jednej stronie, różnica między nimi jest bardzo mała.
Kevin B
$(body)nie działa na .on('click'...wydarzenia, podczas gdy $(document.body)i $(document)oba działają.
rybo111
3
Powyższe stwierdzenie jest fałszywe, a także występuje niewielka różnica w wydajności, około 10% na korzyść $ (document.body). Możesz zobaczyć porównanie tutaj sitepoint.com/jquery-body-on-document-on
Sigismund

Odpowiedzi:

78

Odnoszą się do tego samego elementu, różnica polega na tym, że kiedy mówisz, document.bodyże przekazujesz element bezpośrednio do jQuery. Alternatywnie, gdy przekazujesz ciąg 'body', silnik selektora jQuery musi zinterpretować ciąg, aby dowiedzieć się, do jakich elementów się odwołuje.

W praktyce albo wykonają swoją pracę.

Jeśli jesteś zainteresowany, więcej informacji znajdziesz w dokumentacji funkcji jQuery .

Justin Ethier
źródło
1
Pierwsze stwierdzenie nie jest całkowicie poprawne. Oni mogą odnosić się do tego samego elementu. Zwykle nawet. Ale nie zawsze :). Zobacz moją odpowiedź poniżej.
jvenema
18

Odpowiedzi tutaj nie są w rzeczywistości całkowicie poprawne. Blisko, ale jest skrajna sprawa.

Różnica polega na tym, że $ ('body') faktycznie wybiera element na podstawie nazwy znacznika, podczas gdy document.body odwołuje się do obiektu bezpośredniego w dokumencie.

Oznacza to, że jeśli Ty (lub nieuczciwy skrypt) nadpiszesz element document.body (szkoda!) $ ('Body') nadal będzie działać, ale $ (document.body) nie. Więc z definicji nie są równoważne.

Zaryzykowałbym zgadywanie, że istnieją inne przypadki skrajne (takie jak globalnie identyfikowane elementy w IE), które również wyzwalałyby to, co oznacza nadpisany element ciała na obiekcie dokumentu i taka sama sytuacja miałaby zastosowanie.

jvenema
źródło
Nie sądzę, aby możliwe było ustawienie document.bodyczegoś innego niż <body>: i.imgur.com/unJVwXy.png
mpen
Można to teraz rozwiązać. Był czas, kiedy FF i IE pozwalały ci to zrobić i / lub były zdezorientowane przez przedmioty z identyfikatorem „ciała” (błąd, który napotkałem, to klient korzystający z naszego skryptu na stronie chirurga plastycznego ze zdjęciem oznaczonym tagiem identyfikator „body”). Miejmy nadzieję, że już nie problem :)
jvenema
12

Podczas testowania w przeglądarce zauważyłem dość dużą różnicę w czasie.

Użyłem następującego skryptu:

OSTRZEŻENIE: uruchomienie tego spowoduje trochę zawieszenie przeglądarki, a nawet jej zawieszenie.

var n = 10000000, i;
i = n;
console.time('selector');
while (i --> 0){
    $("body");
}

console.timeEnd('selector');

i = n;
console.time('element');
while (i --> 0){
    $(document.body);
}

console.timeEnd('element');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Zrobiłem 10 milionów interakcji i takie były wyniki (Chrome 65):

selector: 19591.97509765625ms
element: 4947.8759765625ms

Bezpośrednie przejście elementu jest około 4 razy szybsze niż przejście selektora.

Phiter
źródło
7
Dostajesz głos za tylko za „notację strzałkową”, ty bezczelny phiter!
KlaymenDK
1
Gdzieś o tym przeczytałem i chciałem od razu to wykorzystać XD
Phiter
Tak, ale - czy naprawdę zamierzasz to zrobić 10 milionów razy? Dlaczego nie przeprowadzić tego rodzaju analizy tam, gdzie to się liczy?
scrayne
@scrayne te testy wydajności nie dotyczą rzeczywistych przypadków użycia. Rzadko wykonuje się 10 milionów operacji na takim elemencie. Ale OP chciał poznać różnicę i zauważyłem, że jest różnica w wydajności, więc myślę, że warto to zauważyć.
Phiter
9

$(document.body)używa globalnego odniesienia, documentaby uzyskać odwołanie do elementu body, podczas gdy $('body')jest selektorem, w którym jQuery pobierze odwołanie do <body>elementu w document.

Żadnej większej różnicy, którą widzę, ani żadnego zauważalnego wzrostu wydajności między nimi.

Gabe
źródło
9
$(document.body)jest mierzalnie szybszy zgodnie z tym artykułem: sitepoint.com/jquery-body-on-document-on
Steve Harrison.
6

Nie powinno być żadnej różnicy, może pierwsza jest trochę bardziej wydajna, ale myślę, że jest trywialna (naprawdę nie powinieneś się tym martwić).

W obu przypadkach zawijasz <body>tag w obiekt jQuery

Nicola Peluchetti
źródło
3

Wyjściowo oba są równoważne. Chociaż drugie wyrażenie przechodzi przez wyszukiwanie z góry na dół z katalogu głównego DOM. Możesz chcieć uniknąć dodatkowego narzutu (nawet najmniejszego), jeśli masz już obiekt document.body w ręku, aby JQuery mógł go zawinąć. Zobacz http://api.jquery.com/jQuery/ #Selector Context

Santon
źródło