Crear un alias corto para el documento.querySelectorAll


Voy a ejecutar document.querySelectorAll () un montón, y le gustaría un alias abreviado para ello.

var queryAll = document.querySelectorAll

queryAll('body')
TypeError: Illegal invocation

No funciona. Considerando lo siguiente:

document.querySelectorAll('body')

Todavía lo hace. ¿Cómo puedo hacer que funcione el alias?

Author: mikemaccana, 2012-11-14

7 answers

Esto parece funcionar:

var queryAll = document.querySelectorAll.bind(document);

bind devuelve una referencia a la función querySelectorAll, cambiando el contexto de 'this' dentro del método querySelectorAll para que sea el objeto del documento.

La función bind solo es compatible con IE9+ (y todos los demás navegadores) - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind


Actualización: De hecho, podría crear accesos directos a una amplia gama de métodos de documento como esto:

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);
 71
Author: Sunday Ironfoot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-03 09:48:36

El intérprete JavaScript lanza un error porque querySelectorAll() debe ser invocado en el contexto del documento.

Se produce el mismo error cuando intenta llamar a console.log() con alias.

Así que necesitas envolverlo así:

 function x(selector) {
     return document.querySelectorAll(selector);
 }
 14
Author: zlebnik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-15 11:22:41

Esto funcionaría, necesita invocar el alias usando call() o apply() con el contexto apropiado.

func.call(context, arg1, arg2, ...) 
func.apply(context, [args]) 

var x = document.querySelectorAll;
x.call(document, 'body');
x.apply(document, ['body']);
 7
Author: Gabe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-14 17:33:28

Mi solución cubre los cuatro casos de uso siguientes:

  • documento.querySelector(...)
  • documento.querySelectorAll(...)
  • elemento
  • .querySelector(...)
  • elemento
  • .querySelectorAll(...)

El código:

let doc=document,
    qsa=(s,o=doc)=>o.querySelectorAll(s),
    qs=(s,o=doc)=>o.querySelector(s);

En términos de parámetros, el selector s es obligatorio, pero el elemento contenedor object o es opcional.

Uso:

  • qs("div"): Consulta todo el documento para el primer div, devuelve que elemento
  • qsa("div"): Consulta el documento completo para todos los divs, devuelve un NodeList de todos esos elementos
  • qs("div", myContainer): Consulta justo dentro del elemento myContainer para el primer div, devuelve ese elemento
  • qsa("div", myContainer): Consultas justo dentro del elemento myContainer para todos los divs, devuelve una lista de nodos de todos esos elementos

Para hacer el código ligeramente más corto (pero no tan eficiente), el código qs podría escribirse de la siguiente manera:

let qs=(s,o=doc)=>qsa(s,o)[0];

El código anterior utiliza características ES6 (let, funciones de flecha y valores de parámetros predeterminados). Un equivalente ES5 es:

var doc=document,
    qsa=function(s,o){return(o||doc).querySelectorAll(s);},
    qs=function(s,o){return(o||doc).querySelector(s);};

O la versión ES5 equivalente más corta pero menos eficiente de qs:

var qs=function(s,o){return qsa(s,o)[0];};

A continuación se muestra una demostración de trabajo. Para asegurarse de que funciona en todos los navegadores, utiliza la versión ES5, pero si vas a usar esta idea, recuerda que la versión ES6 es más corta:

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>
 5
Author: Andrew Willems,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-01 07:27:10

Una respuesta común es usar $ y $$ para querySelector y querySelectorAll. Este alias imita el de jQuery.

Ejemplo:

$ = 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>
 3
Author: aloisdg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-28 14:58:37
function x(expr)
{
    return document.querySelectorAll(expr);
}
 2
Author: David Müller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-14 17:23:42

Tomé el enfoque de @David Muller y lo alineé usando una lambda

let $    = (e) => document.querySelector(e);
let $all = (e) => document.querySelectorAll(e);

Ejemplo:

$('body');
// <body>...</body>
 1
Author: svarog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-09 06:58:26