114

I am a jQuery beginner and while going through some code examples I found:

$(document.body) and $('body')

Is there any difference between these two?

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
  • 1
    One is faster, however considering that would never be called more than a few times on a single page, the difference between the two is *very* small. – Kevin B Sep 06 '12 at 19:37
  • `$(body)` does not work for `.on('click'...` events, whereas `$(document.body)` and `$(document)` both work. – rybo111 Jun 13 '15 at 22:18
  • 3
    The above statement is false and also there is small difference in performance, approximately 10% in favor of $(document.body). You can view comparison here https://www.sitepoint.com/jquery-body-on-document-on/ – Sigismund Jun 28 '16 at 06:59

8 Answers8

84

They refer to the same element, the difference is that when you say document.body you are passing the element directly to jQuery. Alternatively, when you pass the string 'body', the jQuery selector engine has to interpret the string to figure out what element(s) it refers to.

In practice either will get the job done.

If you are interested, there is more information in the documentation for the jQuery function.

Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
  • 1
    The first statement is not completely correct. They *may* refer to the same element. Usually even. But not always :). See my answer below. – Jerod Venema Feb 28 '18 at 22:28
18

The answers here are not actually completely correct. Close, but there's an edge case.

The difference is that $('body') actually selects the element by the tag name, whereas document.body references the direct object on the document.

That means if you (or a rogue script) overwrites the document.body element (shame!) $('body') will still work, but $(document.body) will not. So by definition they're not equivalent.

I'd venture to guess there are other edge cases (such as globally id'ed elements in IE) that would also trigger what amounts to an overwritten body element on the document object, and the same situation would apply.

Jerod Venema
  • 44,124
  • 5
  • 66
  • 109
  • I don't think it's possibly to set `document.body` to anything other than a ``: https://i.imgur.com/unJVwXy.png – mpen Mar 31 '18 at 18:53
  • Could be resolved now. There was a time when FF and IE would let you do this, and/or would get confused by items with an id of "body" (the error I hit was a customer using our script on a plastic surgeon's site with a picture tagged with the id "body"). Hopefully no longer an issue :) – Jerod Venema May 22 '18 at 21:30
18

I have found a pretty big difference in timing when testing in my browser.

I used the following script:

WARNING: running this will freeze your browser a bit, might even crash it.

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>

I did 10 million interactions, and those were the results (Chrome 65):

selector: 19591.97509765625ms
element: 4947.8759765625ms

Passing the element directly is around 4 times faster than passing the selector.

Phiter
  • 14,570
  • 14
  • 50
  • 84
  • 11
    You get an upvote just for the "arrow notation", you cheeky phiter you! – KlaymenDK Mar 31 '18 at 18:47
  • 2
    I read about this somewhere and I wanted to use it right away XD – Phiter Mar 31 '18 at 18:48
  • 1
    Yes, but -- are you really going to do this 10 million times? Why not do this kind of analysis where it counts? – scrayne Feb 27 '20 at 14:39
  • @scrayne those performance tests are not about real use cases. It's quite rare to do 10 million operations on an element like this. But OP wanted to know the difference and I noticed that there is a performance difference, so I suppose it's worth noting. – Phiter Feb 28 '20 at 18:44
  • Downvote. This kind of intense attention to the performance of trivial operations is harmful in the current year. Actual, appreciable gains in performance are realized at higher abstraction levels (e.g. better algorithms, UX illusions) — not syntax. – Jackson Dec 17 '20 at 08:22
  • @Jackson is that a reason for a downvote though? This is just some information regarding a comparison of two methods. Use whatever you like. – Phiter Dec 18 '20 at 12:06
  • @Phiter yes, it is. Superstitious optimizations are like crack for a certain class of programmers. It needs to stop. – Jackson Dec 22 '20 at 01:30
  • huh ok then, do as you please – Phiter Dec 23 '20 at 13:18
  • is there any real case where this speed diff matters? – Barbz_YHOOL Jul 07 '21 at 02:01
  • 1
    @Barbz_YHOOL honestly? Nah. I just did this for research purposes, but the difference in a real life scenario is too small. – Phiter Jul 08 '21 at 14:40
9

$(document.body) is using the global reference document to get a reference to the body, whereas $('body') is a selector in which jQuery will get the reference to the <body> element on the document.

No major difference that I can see, not any noticeable performance gain from one to the other.

Gabe
  • 49,577
  • 28
  • 142
  • 181
7

There should be no difference at all maybe the first is a little more performant but i think it's trivial ( you shouldn't worry about this, really ).

With both you wrap the <body> tag in a jQuery object

Nicola Peluchetti
  • 76,206
  • 31
  • 145
  • 192
3

Outputwise both are equivalent. Though the second expression goes through a top down lookup from the DOM root. You might want to avoid the additional overhead (however minuscule it may be) if you already have document.body object in hand for JQuery to wrap over. See http://api.jquery.com/jQuery/ #Selector Context

santon
  • 1,654
  • 16
  • 26
0

Today while trying to make the chrome extension example in https://developer.chrome.com/docs/extensions/mv3/getstarted/

I tried to switch

document.body.style.backgroundColor = color;

With

$("body").css("background-color", "black");

Of course it has to be said that I added this at the html file

<script src="script/jquery-3.6.0.min.js"></script>

The result is that it does not work. It will not change the background color of the page, which is what the extension is meant for.

What works though is that jQuery is still able to change/manipulate the elements "in" the extension pop up.

cerebrus6
  • 86
  • 8
0
  • $(document) only references to document,
  • $('body') references to body and document.

When you do this:

$('body').on('log', () => {
    console.log('log body');
});

$(document).on('log', () => {
    console.log('log document');
});

$('body').trigger('log'); => log body + log document

$(document).trigger('log'); => only log document

Results:

console log output

Destroy666
  • 892
  • 12
  • 19
rednas16
  • 1
  • 1
  • If I'm not mistaking, the OP is asking the difference between `$(document.body)` and `$('body')`, not `${document)` and `$(body)`. Also, in your answer, `$('body')` does not refer to the body AND document, it only refers to the body element, the only reason `log document` is logged, is because of event bubbling. If you would return `false` from the `$('body').on('log', ...)` handler, the `document` `log` handler would not be called. – Gerrit Bertier May 26 '23 at 08:21