Chrome DevTools: $(selector)
shorthand doesn't return the element while $$(selector)[0]
does
From time to time I face a weird phenomenon with the $
chrome api shorthand for document.querySelector
that it doesn't return the element with the correct selector, while it works correctly with $$
. As puppeteer heavily depends on these shorthands (page.$
, page.$$
, page.$eval
, page.$$eval
) it can cause unexpected issues.
The issue can be even reproduced here, on Stack Overflow at the moment (09-29-2020).
E.g.:
$('h1').innerText
=>undefined
$$('h1')[0].innerText
=>Chrome DevTools: $(selector) shorthand doesn't return the element...
What is its cause, and why the workaround with $$
works?
I've found it affects those pages that use jQuery library on their frontend (Stack Overflow uses it at the moment).
On such pages the $
is occupied by jQuery (as an alias for itself), so chrome api returns an object instead of the element for $(selector)
. The first element is the DOM element itself, that's why [0]
works.
By the way: $$(selector)[0]
can be even replaced with $(selector)[0]
, as this problem has nothing to do with querySelector
vs. querySelectorAll
.
Page using jQuery:
$('h1')
:
n.fn.init(2)Â [h1.grid--cell.fs-headline1.fl1.ow-break-word.mb8, h1#feed-modal-title.s-modal--header.fw-bold.js-first-tabbable.c-move, prevObject: n.fn.init(1), context: document, selector: "h1"]
$('h1')[0]
/ document.querySelector('h1')
:
<h1>...</h1>
Page doesn't use jQuery:
...while on pages doesn't rely on jQuery it works as usual.
$('h1')
/ document.querySelector('h1')
:
<h1>...</h1>
$('h1')[0]
:
undefined
It might be useful for others.