Подтвердить что ты не робот

Создание короткого псевдонима для document.querySelectorAll

Я собираюсь запустить document.querySelectorAll() целую кучу и хотел бы иметь сокращенный псевдоним для него.

var queryAll = document.querySelectorAll

queryAll('body')
TypeError: Illegal invocation

Не работает. Принимая во внимание:

document.querySelectorAll('body')

Тем не менее. Как я могу заставить псевдоним работать?

4b9b3361

Ответ 1

Это работает:

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

bind возвращает ссылку на функцию querySelectorAll, изменяя контекст 'this' внутри метода querySelectorAll как объект документа.

Функция привязки поддерживается только в IE9 + (и во всех других браузерах) - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind


Обновление: Фактически вы можете создавать ярлыки для целого ряда методов документа, таких как:

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);

Ответ 2

интерпретатор JavaScript выдает ошибку, потому что querySelectorAll() должен быть вызван в контексте документа.

Эта же ошибка возникает, если вы пытаетесь вызвать console.log() aliased.

Итак, вам нужно обернуть его следующим образом:

 function x(selector) {
     return document.querySelectorAll(selector);
 }

Ответ 3

Распространенным ответом является использование $ и $$ для querySelector и querySelectorAll. Этот псевдоним имитирует JQuery один.

Пример:

$ = 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>

Ответ 4

Мое решение охватывает четыре следующих варианта использования:

  • document.querySelector(...)
  • document.querySelectorAll(...)
  • element.querySelector(...)
  • element.querySelectorAll(...)

Код:

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

В терминах параметров требуется селектор s, но объект элемента контейнера o является необязательным.

Использование:

  • qs("div"): запрашивает весь документ для первого div, возвращает этот элемент
  • qsa("div"): запрашивает весь документ для всех div, возвращает nodeList из всех этих элементов
  • qs("div", myContainer): запрашивает только элемент myContainer для первого div, возвращает этот элемент
  • qsa("div", myContainer): запросы только внутри элемента myContainer для всех div, возвращает nodeList из всех этих элементов

Чтобы сделать код немного короче (но не настолько эффективным), код qs можно записать следующим образом:

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

В приведенном выше коде используются функции ES6 (let, функции стрелок и значения параметров по умолчанию). Эквивалент ES5:

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

или эквивалентную более короткую, но менее эффективную версию ES5 qs:

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

Ниже приведена рабочая демонстрация. Чтобы убедиться, что он работает во всех браузерах, он использует версию ES5, но если вы собираетесь использовать эту идею, помните, что версия ES6 короче:

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

Это сработает, вам нужно вызвать псевдоним, используя call() или apply() с соответствующим контекстом.

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

var x = document.querySelectorAll;
x.call(document, 'body');
x.apply(document, ['body']);

Ответ 6

Я выбрал подход Дэвида Мюллера и выстроил его с помощью лямбды

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

Пример:

$('body');
// <body>...</body>

Ответ 7

function x(expr)
{
    return document.querySelectorAll(expr);
}

Ответ 8

Вот мой взгляд на это. Если селектор имеет несколько совпадений, вернуть как querySelectorAll. Если найдено только одно совпадение, верните как 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');

Обновление 2019

Сегодня я сделал новый взгляд на проблему. В этой версии вы также можете использовать такую базу:

let base = document.querySelectorAll('ul');

$$('li'); // All li
$$('li', base); // All li within ul

функции

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);
}

Ответ 9

ES6:

$ = q=>document.querySelector(q);      // usage: $('your_css_selector')

$$ = q=>document.querySelectorAll(q);  // usage: $$('your_css_selector')

Ответ 10

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);
}

Почему не проще??? :

let $ = (selector, base = document) => {
  let elements = base.querySelectorAll(selector);
  return (elements.length == 1) ? elements[0] : elements;
}