document.querySelectorAll()を大量に実行する予定であり、その省略形のエイリアスが必要です。
var queryAll = document.querySelectorAll
queryAll('body')
TypeError: Illegal invocation
動作しません。一方:
document.querySelectorAll('body')
それでもします。エイリアスを機能させるにはどうすればよいですか?
document.querySelectorAll()を大量に実行する予定であり、その省略形のエイリアスが必要です。
var queryAll = document.querySelectorAll
queryAll('body')
TypeError: Illegal invocation
動作しません。一方:
document.querySelectorAll('body')
それでもします。エイリアスを機能させるにはどうすればよいですか?
これはうまくいくようです:
const queryAll = document.querySelectorAll.bind(document);
bind
関数と同じように機能する新しい関数を返します。ここで、メソッド内のquerySelectorAll
値はオブジェクトにバインドされています。this
querySelectorAll
document
バインド機能はIE9+(および他のすべてのブラウザ)でのみサポートされています-https ://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind
更新:実際、次のようなドキュメントメソッド全体へのショートカットを作成できます。
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);
一般的な答えは、andforとを使用$
すること$$
です。このエイリアスはjQueryのエイリアスを模倣しています。querySelector
querySelectorAll
例:
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>
JavaScriptインタープリターはquerySelectorAll()
、ドキュメントコンテキストで呼び出す必要があるため、エラーをスローします。
console.log()
エイリアスを呼び出そうとすると、同じエラーがスローされます。
したがって、次のようにラップする必要があります。
function x(selector) {
return document.querySelectorAll(selector);
}
私のソリューションは、次の4つのユースケースをカバーしています。
コード:
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)
:最初のdivのmyContainer要素内でクエリを実行し、その要素を返しますqsa("div", myContainer)
:すべてのdivのmyContainer要素内でクエリを実行し、それらすべての要素の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>
call()
これは機能します。適切なコンテキストを使用して、または適切なコンテキストでエイリアスを呼び出す必要がありapply()
ます。
func.call(context, arg1, arg2, ...)
func.apply(context, [args])
var x = document.querySelectorAll;
x.call(document, 'body');
x.apply(document, ['body']);
@David Mullerのアプローチを採用し、ラムダを使用して1行に並べました
let $ = (selector) => document.querySelector(selector);
let $all = (selector) => document.querySelectorAll(selector);
例:
$('body');
// <body>...</body>
function x(expr)
{
return document.querySelectorAll(expr);
}
これが私の見解です。セレクターに複数の一致がある場合は、のように戻りquerySelectorAll
ます。一致するものが1つ見つかった場合は、のように返し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);
}
誰も使用してはならない古くてひどいブラウザをサポートすることに関心がない場合は、次のようにすることができます。
const $ = (sel, parent = document) => parent.querySelector(sel);
const $$ = (sel, parent = document) => Array.from(parent.querySelectorAll(sel));
使用例を次に示します。
// find specific element by id
console.log($("#someid"));
// find every element by class, within other element
// NOTE: This is a contrived example to demonstrate the parent search feature.
// If you don't already have the parent in a JavaScript variable, you should
// query via $$("#someparent .someclass") for better performance instead.
console.log($$(".someclass", $("#someparent")));
// find every h1 element
console.log($$("h1"));
// find every h1 element, within other element
console.log($$("h1", $("#exampleparent")));
// alternative way of finding every h1 element within other element
console.log($$("#exampleparent h1"));
// example of finding an element and then checking if it contains another element
console.log($("#exampleparent").contains($("#otherelement")));
// example of finding a bunch of elements and then further filtering them by criteria
// that aren't supported by pure CSS, such as their text content
// NOTE: There WAS a ":contains(text)" selector in CSS3 but it was deprecated from the
// spec because it violated the separation between stylesheets and text content, and you
// can't rely on that CSS selector, which is why you should never use it and should
// instead re-implement it yourself like we do in this example.
// ALSO NOTE: This is just a demonstration of .filter(). I don't recommend using
// "textContent" as a filter. If you need to find specific elements, use their way
// more reliable id/class to find them instead of some arbitrary text content search.
console.log($$("#exampleparent h1").filter(el => el.textContent === "Hello World!"));
私が提供した機能は、多くの最新のJS機能を使用しています。
const
関数変数が上書きされないようにするため。(args) => code with implied return statement
{}
または。return
Array.from()
が使用されます。これは基本的にすべての開発者が望むものです。これが、クリーンで短いコードを使用して、検出されたノードをさらに処理できるようにするその他の配列関数にアクセスする方法だからです。そして、すべての要素の浅いコピーを作成します。これは、非常に高速であることを意味します(元のNodeListから各Node DOM要素にメモリ参照/ポインターをコピーするだけです)。これは主要なAPIエンハンサーです。querySelectorAll
.filter()
Array.from()
古いブラウザが気になる場合でも、私の機能を使用できますが、Webサイトをリリースするときに、Babelを使用して最新のJSを古いES5に変換します。
私の提案は、サイト全体をES6以降で作成し、Windows XPやその他の古いオペレーティングシステムからの訪問者、または5年以上ブラウザを更新していないランダムな人々を気にする場合はBabelを使用することです。
しかし、私はバベルを使用することをお勧めしません。古いブラウザを持っている人のことを心配するのはやめましょう。それは彼らの問題であり、あなたの問題ではありません。
現代の「アプリ」の世界は、Webブラウザー、JavaScript、および最新のCSSに非常に深く基づいており、最近の訪問者のほとんどは、最新の自動更新されたブラウザーを使用しています。非常に多くのウェブサイトが現在それを要求しているので、あなたは基本的に現代のブラウザなしで現代の生活を送ることはできません。
私の意見では、1993年からWebデザイナーがブラウザでサイトを機能させるために時間と正気を無駄にすることを期待していた時代は終わりました。怠惰な顧客/訪問者が代わりに古いブラウザを更新する時が来ました。それは難しいことではありません。古いオペレーティングシステムや古いオペレーティングシステムでさえ、通常、新しいバージョンのブラウザをインストールする方法があります。そして、更新されたブラウザを持っていない人は、最近ではほんのわずかな割合です。
たとえば、モバイル/レスポンシブサイトで世界で最も人気のあるフレームワークであるBootstrapフレームワークは、すべての主要なブラウザの最新の2つのメジャーバージョン(少なくとも0.5%の市場シェア)のサポートのみを考慮しています。現時点でのリストは次のとおりです。
そして、私はこれに完全に同意します。私は2000年代初頭にウェブ開発者でしたが、それは絶対に地獄でした。ランダムで愚かなユーザーの古いブラウザで動作することが期待されていたのは地獄でした。それはウェブ開発からすべての楽しみを奪いました。それは私を嫌いにし、ウェブ開発をやめさせました。私の時間の90%がブラウザの互換性に浪費されていたからです。それは人生がどうあるべきかではありません。一部の顧客/訪問者が怠惰であることはあなたのせいではありません。そして最近、訪問者は怠惰なままでいるためのもはや言い訳がありません。
代わりに、最新のブラウザを使用しているユーザーのみをターゲットにする必要があります。これは基本的に最近はみんなです。誰もが古いブラウザを使用する言い訳はありません。また、古いブラウザを使用している場合は、「どうぞ、自分のために現代の世界に参加してください。新しいブラウザをダウンロードしてください。このような古いブラウザで通常の生活を送ることができるようにするには、大きくて太いバナーを表示する必要があります。 ?あなたは穴居人時代からのタイムトラベラーですか?」
人々はもはや古いブラウザを持っている言い訳はありません:
最近のほとんどの人は、完全に最新で自動更新されたブラウザを持っています。それが事実です。
そうそう...古いブラウザに対応するためだけに地獄で苦しんでいるウェブサイトデザイナーの時代は終わりました。したがって、Webデザインを初めて楽しむために、WebサイトにES6とCSS3を使用することをお勧めします。
私が提供したES6機能をお楽しみください。
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;
}