Making a short alias for document.querySelectorAll
Solution 1:
This seems to work:
const queryAll = document.querySelectorAll.bind(document);
bind
returns a new function which works identically to the querySelectorAll
function, where the value of this
inside the querySelectorAll
method is bound to the document
object.
The bind function is only supported in IE9+ (and all the other browsers) - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind
Update: In fact you could create shortcuts to a whole range of document methods like this:
const query = document.querySelector.bind(document);
const queryAll = document.querySelectorAll.bind(document);
const fromId = document.getElementById.bind(document);
const fromClass = document.getElementsByClassName.bind(document);
const fromTag = document.getElementsByTagName.bind(document);
Solution 2:
A common answer is to use $
and $$
for querySelector
and querySelectorAll
. This alias mimics jQuery's one.
Example:
const $ = document.querySelector.bind(document)
const $$ = document.querySelectorAll.bind(document)
$('div').style.color = 'blue'
$$('div').forEach(div => div.style.background = 'orange')
div {
margin: 2px;
}
<div>
test
</div>
<section>
<div>
hello
</div>
<div>
foo
</div>
</section>
Solution 3:
The JavaScript interpreter throws an error because querySelectorAll()
should be invoked in document context.
The same error is thrown when you are trying to call console.log()
aliased.
So you need to wrap it like this:
function x(selector) {
return document.querySelectorAll(selector);
}
Solution 4:
My solution covers the four following use cases:
- document.querySelector(...)
- document.querySelectorAll(...)
- element.querySelector(...)
- element.querySelectorAll(...)
The code:
let doc=document,
qsa=(s,o=doc)=>o.querySelectorAll(s),
qs=(s,o=doc)=>o.querySelector(s);
In terms of parameters, the selector s
is required, but the container element object o
is optional.
Usage:
-
qs("div")
: Queries the whole document for the first div, returns that element -
qsa("div")
: Queries the whole document for all divs, returns a nodeList of all those elements -
qs("div", myContainer)
: Queries just within the myContainer element for the first div, returns that element -
qsa("div", myContainer)
: Queries just within the myContainer element for all divs, returns a nodeList of all those elements
To make the code slightly shorter (but not quite as efficient), the qs
code could be written as follows:
let qs=(s,o=doc)=>qsa(s,o)[0];
The code above uses ES6 features (let
, arrow functions and default parameter values). An ES5 equivalent is:
var doc=document,
qsa=function(s,o){return(o||doc).querySelectorAll(s);},
qs=function(s,o){return(o||doc).querySelector(s);};
or the equivalent shorter but less efficient ES5 version of qs
:
var qs=function(s,o){return qsa(s,o)[0];};
Below is a working demo. To ensure it works on all browsers, it uses the ES5 version, but if you're going to use this idea, remember that the ES6 version is shorter:
var doc = document;
var qs=function(s,o){return(o||doc).querySelector(s);},
qsa=function(s,o){return(o||doc).querySelectorAll(s);}
var show=function(s){doc.body.appendChild(doc.createElement("p")).innerHTML=s;}
// ____demo____ _____long equivalent______ __check return___ _expect__
// | | | | | | | |
let one = qs("div"); /* doc.querySelector ("#one") */ show(one .id ); // "one"
let oneN = qs("div",one); /* one.querySelector ("div") */ show(oneN .id ); // "oneNested"
let many = qsa("div"); /* doc.querySelectorAll("div") */ show(many .length); // 3
let manyN = qsa("div",one); /* one.querySelectorAll("div") */ show(manyN.length); // 2
<h3>Expecting "one", "oneNested", 3 and 2...</h3>
<div id="one">
<div id="oneNested"></div>
<div></div>
</div>