Je vais courir le document.QuerySelectorallall () beaucoup, et j'aimerais un alias racnorifique pour cela.
var queryAll = document.querySelectorAll
queryAll('body')
TypeError: Illegal invocation
Ne fonctionne pas. Tandis que:
document.querySelectorAll('body')
Toujours fait. Comment puis-je faire fonctionner l'alias?
Cela semble fonctionner:
var queryAll = document.querySelectorAll.bind(document);
bind
renvoie une référence à la fonction querySelectorAll
, modifiant le contexte de "Ceci" à l'intérieur de la méthode QuerySelectorall pour être l'objet de document.
La fonction de liaison n'est prise en charge que dans IE9 + (et tous les autres navigateurs) - https://developer.mozilla.org/en-us/docs/javascript/reference/global_objects/function/bind
Mise à jour: En fait, vous pouvez créer des raccourcis sur une gamme complète de méthodes de document comme celle-ci:
var query = document.querySelector.bind(document);
var queryAll = document.querySelectorAll.bind(document);
var fromId = document.getElementById.bind(document);
var fromClass = document.getElementsByClassName.bind(document);
var fromTag = document.getElementsByTagName.bind(document);
L'interprète JavaScript jette une erreur car querySelectorAll()
doit être invoqué dans le contexte du document.
La même erreur est lancée lorsque vous essayez d'appeler console.log()
aliased.
Vous devez donc envelopper comme ça:
function x(selector) {
return document.querySelectorAll(selector);
}
Ma solution couvre les quatre cas d'utilisation suivants:
Le code:
let doc=document,
qsa=(s,o=doc)=>o.querySelectorAll(s),
qs=(s,o=doc)=>o.querySelector(s);
En termes de paramètres, le sélecteur s
est requis, mais l'objet élément du conteneur o
est facultatif.
Usage:
qs("div")
: interroge l'ensemble du document pour le premier div, renvoie cet élémentqsa("div")
: interroge tout le document pour tous les divs, renvoie une nodéliste de tous ces élémentsqs("div", myContainer)
: requêtes juste dans l'élément Mycontainer pour le premier div, renvoie cet élémentqsa("div", myContainer)
: requêtes juste dans l'élément Mycontainer pour tous les DIV, renvoie une nodéliste de tous ces élémentsPour rendre le code légèrement plus court (mais pas tout aussi efficace), le code qs
pourrait être écrit comme suit:
let qs=(s,o=doc)=>qsa(s,o)[0];
Le code ci-dessus utilise des fonctionnalités ES6 (let
, fonctions fléchées et valeurs de paramètre par défaut). Un équivalent ES5 est:
var doc=document,
qsa=function(s,o){return(o||doc).querySelectorAll(s);},
qs=function(s,o){return(o||doc).querySelector(s);};
ou la version équivalente plus courte mais moins efficace de qs
:
var qs=function(s,o){return qsa(s,o)[0];};
Vous trouverez ci-dessous une démonstration de travail. Pour que cela fonctionne sur tous les navigateurs, il utilise la version ES5, mais si vous allez utiliser cette idée, rappelez-vous que la version ES6 est plus courte:
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>
Cela fonctionnerait, vous devez invoquer l'alias à l'aide de call()
ou apply()
avec le contexte approprié.
func.call(context, arg1, arg2, ...)
func.apply(context, [args])
var x = document.querySelectorAll;
x.call(document, 'body');
x.apply(document, ['body']);
Une réponse commune est d'utiliser $
et $$
pour querySelector
et querySelectorAll
. Cet alias imite celle de JQuery.
Exemple:
$ = document.querySelector.bind(document)
$$ = 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>
J'ai pris l'approche de @david Muller et je l'a doublé à l'aide d'une Lambda
let $ = (selector) => document.querySelector(selector);
let $all = (selector) => document.querySelectorAll(selector);
Exemple:
$('body');
// <body>...</body>
function x(expr)
{
return document.querySelectorAll(expr);
}
Voici mon emporter dessus. Si le sélecteur a plusieurs correspondances, renvoyez comme querySelectorAll
. Si ony, une correspondance est trouvée, rendez-vous comme querySelector
.
function $(selector) {
let all = document.querySelectorAll(selector);
if(all.length == 1) return all[0];
return all;
}
let one = $('#my-single-element');
let many = $('#multiple-elements li');
mise à jour de 2019
Aujourd'hui, j'ai fait une nouvelle prise sur le problème. Dans cette version, vous pouvez également utiliser une base comme celle-ci:
let base = document.querySelectorAll('ul');
$$('li'); // All li
$$('li', base); // All li within ul
fonctions
function $(selector, base = null) {
base = (base === null) ? document : base;
return base.querySelector(selector);
}
function $$(selector, base = null) {
base = (base === null) ? document : base;
return base.querySelectorAll(selector);
}
function $(selector, base = null) { base = (base === null) ? document : base; return base.querySelector(selector); } function $$(selector, base = null) { base = (base === null) ? document : base; return base.querySelectorAll(selector); }
Pourquoi pas plus simple ??? :
let $ = (selector, base = document) => {
let elements = base.querySelectorAll(selector);
return (elements.length == 1) ? elements[0] : elements;
}