Создание короткого псевдонима для document.querySelectorAll
Я собираюсь запустить document.querySelectorAll() целую кучу и хотел бы иметь сокращенный псевдоним для него.
var queryAll = document.querySelectorAll
queryAll('body')
TypeError: Illegal invocation
Не работает. Принимая во внимание:
document.querySelectorAll('body')
Тем не менее. Как я могу заставить псевдоним работать?
Ответы
Ответ 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;
}