58

document.querySelectorAll()を大量に実行する予定であり、その省略形のエイリアスが必要です。

var queryAll = document.querySelectorAll

queryAll('body')
TypeError: Illegal invocation

動作しません。一方:

document.querySelectorAll('body')

それでもします。エイリアスを機能させるにはどうすればよいですか?

4

10 に答える 10

101

これはうまくいくようです:

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

bind関数と同じように機能する新しい関数を返します。ここで、メソッド内のquerySelectorAll値はオブジェクトにバインドされています。thisquerySelectorAlldocument

バインド機能は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);
于 2013-02-19T00:33:03.457 に答える
26

一般的な答えは、andforとを使用$すること$$です。このエイリアスはjQueryのエイリアスを模倣しています。querySelectorquerySelectorAll

例:

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>

于 2017-09-06T15:29:14.827 に答える
15

JavaScriptインタープリターはquerySelectorAll()、ドキュメントコンテキストで呼び出す必要があるため、エラーをスローします。

console.log()エイリアスを呼び出そうとすると、同じエラーがスローされます。

したがって、次のようにラップする必要があります。

 function x(selector) {
     return document.querySelectorAll(selector);
 }
于 2012-11-14T17:29:46.247 に答える
10

私のソリューションは、次の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):最初の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>

于 2016-02-29T08:40:57.437 に答える
7

call()これは機能します。適切なコンテキストを使用して、または適切なコンテキストでエイリアスを呼び出す必要がありapply()ます。

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

var x = document.querySelectorAll;
x.call(document, 'body');
x.apply(document, ['body']);
于 2012-11-14T17:28:18.953 に答える
6

@David Mullerのアプローチを採用し、ラムダを使用して1行に並べました

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

例:

$('body');
// <body>...</body>
于 2018-05-09T06:58:26.877 に答える
4
function x(expr)
{
    return document.querySelectorAll(expr);
}
于 2012-11-14T17:23:42.117 に答える
2

これが私の見解です。セレクターに複数の一致がある場合は、のように戻り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);
}
于 2018-12-16T17:59:43.487 に答える
1

誰も使用してはならない古くてひどいブラウザをサポートすることに関心がない場合は、次のようにすることができます。

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
  • デフォルトのパラメーター(2016年より前のブラウザーではサポートされていません)
  • 関数本体にステートメントが1つしかない場合はスキップできるため、no{}または。return
  • 結果(常にNodeListまたは空のNodeList)を配列に変換する最新の関数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%の市場シェア)のサポートのみを考慮しています。現時点でのリストは次のとおりです。

  • 0.5%以上の市場シェア
  • 最後の2つのメジャーバージョンのみ
  • 死んだブラウザではありません(廃止されていません)
  • Chrome> = 60
  • Firefox> = 60
  • Firefox ESR
  • iOS> = 12
  • Safari> = 12
  • Explorer <= 11ではありません(Internet Explorerのバージョンがまったくないことを意味します)

そして、私はこれに完全に同意します。私は2000年代初頭にウェブ開発者でしたが、それは絶対に地獄でした。ランダムで愚かなユーザーの古いブラウザで動作することが期待されていたのは地獄でした。それはウェブ開発からすべての楽しみを奪いました。それは私を嫌いにし、ウェブ開発をやめさせました。私の時間の90%がブラウザの互換性に浪費されていたからです。それは人生がどうあるべきかではありません。一部の顧客/訪問者が怠惰であることはあなたのせいではありません。そして最近、訪問者は怠惰なままでいるためのもはや言い訳がありません。

代わりに、最新のブラウザを使用しているユーザーのみをターゲットにする必要があります。これは基本的に最近はみんなです。誰もが古いブラウザを使用する言い訳はありません。また、古いブラウザを使用している場合は、「どうぞ、自分のために現代の世界に参加してください。新しいブラウザをダウンロードしてください。このような古いブラウザで通常の生活を送ることができるようにするには、大きくて太いバナーを表示する必要があります。 ?あなたは穴居人時代からのタイムトラベラーですか?」

人々はもはや古いブラウザを持っている言い訳はありません:

  1. Linux:デフォルトで最新バージョンのFirefoxに同梱されています。
  2. Mac:最新のブラウザであるSafariに同梱されています。ただし、一部の古いバージョンのmacOSは新しいバージョンのSafariを取得できず、古いマシンも最新のmacOSバージョンをインストールできないことがよくあります。さて、それらの訪問者にとっては大変な幸運です。彼らはあなたのウェブサイト以上のもので問題を抱えるでしょう。最新のブラウザ(Chromeなど)をインストールするのは彼ら次第です。これは、古いバージョンのmacOSでも実行できます。だから彼らには言い訳がありません。非常に古い、バグのあるSafariバージョンで人々にケータリングするあなたの人生を無駄にしないでください。
  3. Windows:Windows 10にはEdgeが付属しています。これは、Chromiumに基づいており、Chromeと同じようにWebサイトと互換性があります。人々は古いブラウザを持っている言い訳はありません。そして、ほとんどのWindowsユーザーはChromeを使用しています。非常に古い、廃止されたバージョンのWindows(XP、Vista、7、8)については、以前と同じ質問に再び到達します。古いOSと古いInternet Explorerを使用する0.0000001%の愚かな訪問者を気にしますか?バージョン?とにかくおかしなウェブ全体が彼らのために壊れます、それであなたのサイトが彼らのためにも壊れているかどうか誰が気にしますか?怠惰になるのをやめて、OSをWindows 10にアップグレードするか、少なくとも現在のOSにChromeまたはFirefoxをインストールする必要があります。彼らには言い訳がありません。
  4. iOS:非常に古いiOSデバイスで立ち往生している場合は、最新のWebを使用できません。頑張ってください。ウェブの多くはあなたのために壊されるでしょう。新しいデバイスを入手してください。世界一のモバイルWebフレームワークであるBootstrapのようなフレームワークでさえ、iOS11以前をサポートしていません。それは私たちの問題ではありません。彼らがまだそのような古いデバイスにぶら下がっているならば、それは安いスケートの訪問者の問題です。彼らは文字通り、ほとんどお金をかけずに新しいiOSデバイスを中古で入手し、最新のWebにアクセスする際のすべての問題を解決することができます。そして、ほとんどのアプリ(銀行/重要なアプリでさえ)は最新のiOSバージョンを必要とするため、とにかくそれを購入する必要があります。
  5. Android:ブラウザはOSから独立して更新され、サイドロードすることもできるため、古いAndroidバージョンを使い続けている場合でも、最新のブラウザにアクセスできます。ですから、言い訳はありません。

最近のほとんどの人は、完全に最新で自動更新されたブラウザを持っています。それが事実です。

そうそう...古いブラウザに対応するためだけに地獄で苦しんでいるウェブサイトデザイナーの時代は終わりました。したがって、Webデザインを初めて楽しむために、WebサイトにES6とCSS3を使用することをお勧めします。

私が提供したES6機能をお楽しみください。

于 2021-05-01T22:37:01.780 に答える
0
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;
}
于 2019-10-08T12:57:21.640 に答える