この文書は「Selectors API Level 1 (W3C Working Draft 28 June 2012)」の日本語訳である。日本語訳は参考情報であり、公式な文書ではない。また、翻訳に誤りがある可能性にも注意されたい。

原文の最新版 は、この日本語訳が参照した版から更新された可能性がある。他の仕様の訳については Web 標準仕様 日本語訳一覧 を参照されたい。

公開日:
2012-06-29
翻訳者:
矢倉 眞隆 <yakura-masataka@mitsue.co.jp>

W3C

セレクタ API Level 1

2012 年 6 月 28 日付 W3C 草案 (Working Draft)

この版:
http://www.w3.org/TR/2012/WD-selectors-api-20120628/
最新の編集版ドラフト:
Level 1 http://dev.w3.org/2006/webapi/selectors-api/
Level 2 http://dev.w3.org/2006/webapi/selectors-api2/
最新版:
http://www.w3.org/TR/selectors-api/
前の版:
http://www.w3.org/TR/2009/CR-selectors-api-20091222/
http://www.w3.org/TR/2008/WD-selectors-api-20081114/
http://www.w3.org/TR/2007/WD-selectors-api-20071221/
http://www.w3.org/TR/2007/WD-selectors-api-20071019/
http://www.w3.org/TR/2006/WD-selectors-api-20060926/
http://www.w3.org/TR/2006/WD-selectors-api-20060525/
Editor:
Anne van Kesteren (Opera Software ASA) <annevk@opera.com>
Lachlan Hunt (Opera Software ASA) <lachlan.hunt@lachy.id.au>

概要

CSS で広く利用されているセレクタは、木構造をもつ要素群から、目的のものを探すための仕組みである [SELECT][CSS21]。セレクタ API 仕様は、セレクタを指定して DOM から Element ノードを取り出すメソッドを定義する。この API は、文書の中から特定の要素に対し DOM 操作を行いたい時、とても有用なものだ。このメソッドにより、特定の要素を抽出する処理を、従来の仕組みより簡単に行うことができる。

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This is the 28 June 2012 Last Call Working Draft of "Selectors API". The W3C Membership and other interested parties are invited to review the document and send comments to public-webapps@w3.org (public archive) with [selectors-api] in the subject, through 19 July 2012. (Please note that a different list was used until mid 2008, so some old messages are archived there instead).

Web content and browser developers are encouraged to review this draft. This draft is considered very stable and is expected to progress to Candidate Recommendation after the review period. The Web Applications (WebApps) Working Group has developed a comprehensive Selectors API test suite.

This document was developed by the Web Applications Working Group. The Working Group expects to advance this Working Draft to Recommendation Status.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

目次

1. はじめに

このセクションは非規範的である。

この仕様は、与えられたセレクタに対し、そのセレクタにマッチする/しない要素を選択もしくはテストするメソッドを定義する。これらのメソッドにより、従来よりも簡単に Element ノードを取得できるようになるため、getElementsByTagName() で得られた結果に対しさらにフィルタをかけるなどといったことをする必要がなくなるだろう。

1.1.

このセクションは非規範的である。

この例は ECMAScript [ECMA-262] によって書かれている。

HTML 4.01 で、簡単な表を記述する。

<table id="score">
  <thead>
    <tr>
      <th>Test
      <th>Result
  <tfoot>
    <tr>
      <th>Average
      <td>82%
  <tbody>
    <tr>
      <td>A
      <td>87%
    <tr>
      <td>B
      <td>78%
    <tr>
      <td>C
      <td>81%
</table>

たとえば、グラフを描きたいといった理由で、この表から結果 (“Result”) のみを取得したいとしよう。これには2つの方法が考えられる。ひとつは、DOM Level 2 の API のみを利用する方法だ。このやり方では、table 内の tbody から、各 tr をイテレートして、その行にある 2 番目のセルを見つけることになる。

var table = document.getElementById("score");
var groups = table.tBodies;
var rows = null;
var cells = [];

for (var i = 0; i < groups.length; i++) {
  rows = groups[i].rows;
  for (var j = 0; j < rows.length; j++) {
    cells.push(rows[j].cells[1]);
  }
}

もう一つは、querySelectorAll() メソッドを利用する方法だ。このメソッドを使用すると、スクリプトをとても簡潔に記述できる。

var cells = document.querySelectorAll("#score>tbody>tr>td:nth-of-type(2)");

このスクリプトは DOM 上で動作するため、文書がどの構文で書かれているかは関係ないことに注意されたい。つまり、このスクリプトは HTML だけではなく、製形式の XHTML や DOM API を利用し動的に生成され挿入された表に対しても動作するだろう。

2. 適合性要件

仕様書中のすべての図、例、注釈は非規範的なものとなる。また、明示的に非規範的とされたセクションも非規範的なものとなる。それ以外の部分については、規範的なものとなる。

規範的な文章中にあるキーワード mustshouldmayrecommended は、RFC 2119 で示されるとおりに解釈される [RFC2119].

この仕様では、次の適合性クラスについても検討され、定義されている。

適合するユーザーエージェント (conforming user agent)
この仕様で定義されるインターフェースを実装し、関連するすべての must レベル基準に適合するユーザーエージェントのこと。
適合するアプリケーション (conforming application)
この仕様で定義されるインターフェースを利用し、また製作者に関連するすべての must レベル基準に適合するアプリケーションのこと。

2.1. 用語と慣習

この仕様で利用される用語は、セレクタ仕様のものである [SELECT]

次の機能は DOM Level 3 Core 仕様で定義される。 [DOM-LEVEL-3-CORE]:

アルゴリズムとして記された適合性要件や特定のステップについては、結果が同じものである限りどのような方法を用いて実装することも可能だ (may)。

この仕様で利用される IDL は、Web IDL で定義された構文を用いる [WEBIDL]

Foo が実際にはインターフェースであるにも関わらず、"Foo オブジェクト" と表記されることがある。これは、"Foo インターフェースをインプリメントするオブジェクト" という意味で用いられる。

3. 相互運用性に関する考察

このセクションは非規範的である。

セレクタの実装状況は、実装により異なる可能性がある。あるセレクタをサポートする実装としない実装が存在する場合、そのセレクタを利用したコードは異なる結果を返すことになるだろう。このため、製作者はこれらの API から投げられる DOM の例外を調べ、Graceful Degradation によるフォールバックを提供することをおすすめする。

3.1. 拡張性

このセクションは非規範的である。

この仕様で定義される API の拡張は 奨励されない (strongly discouraged)。実装者やワーキンググループ、そして他の団体は、拡張について public-webapi@w3.org などの公開フォーラムで議論するべきだ。

4. セキュリティに関する考察

この仕様を実装するにあたって、ユーザーがセキュリティに関するリスクを負わないようにすることが望まれる。

セキュリティポリシーに違反すると判断される状況に遭遇した場合、実装は処理を中止し、セキュリティ例外を発生させられる (may)。この仕様や関連する仕様の範囲外でエラーが起こった場合、実装は処理を中止し、言語バインディング固有、または実装固有の例外を発生させられる (may)。

5. プライバシーに関する考察

プライバシーに関して考えられる懸念のひとつに、履歴の取得が挙げられる。セレクタ [SELECT]:visited 擬似クラスをクエリーにかけたとき、訪問済みのリンクを取得できることが問題視されている。

しかしながら、これは古くからある問題だ。訪問済みリンクの取得は、CSS と getComputedStyle() など既存の DOM API により取得できるからだ [DOM-LEVEL-2-STYLE]

次の例では、vlinks がユーザーが訪れたリンクを取得する。悪意を持った製作者はここから URI を取得し、悪用できる。

var vlinks = document.querySelectorAll(":visited");
for (var i = 0; i < vlinks.length; i++) {
  doSomethingEvil(vlinks[i].href);
}

セレクタ 仕様で定義されている ([SELECT], section 6.6.1) 通り、ユーザーエージェントはすべてのリンクを未訪問のリンクとして扱える (may)。実装には、サポートされるセレクタについて、その他の用途と一貫性を持たせた挙動が推奨される (recommended)。

6. API

メソッドの定義で使われる 最初 (first) とは、document order で最初のもの (first in document order) を表す。document order は、該当する DOM ツリーまたはそのサブツリーに対し、深さ優先の先行順走査 (depth-first pre-order traversal) を行ったもの表す。コンテキストノード (context node) は、メソッドが呼び出されるノードを表す。サブツリー (subtrees) は、コンテキストノード の子孫要素のコレクションを表す。マッチする Element ノード (matching Element node) は、セレクタの要素マッチング規則 [SELECT] に則り、メソッドに渡されたセレクタ (selectors) にマッチする Element ノードを表す。

6.1. インターフェース定義

partial interface Document {
  Element?  querySelector(DOMString selectors);
  NodeList  querySelectorAll(DOMString selectors);
};

partial interface DocumentFragment {
  Element?  querySelector(DOMString selectors);
  NodeList  querySelectorAll(DOMString selectors);
};

partial interface Element {
  Element?  querySelector(DOMString selectors);
  NodeList  querySelectorAll(DOMString selectors);
};

6.2. 要素の探索

querySelector メソッドと querySelectorAll メソッド selectors は引数に セレクタ文字列 (selector string) をとる。

Document, DocumentFragment, Element インターフェースの querySelector() メソッドは、コンテキストノードサブツリーのなかで、最初にマッチした Element ノードを返さなければならない (must)。マッチする Element ノードがない場合、メソッドは null を返さなければならない (must)。

Document, DocumentFragment, Element インターフェースの querySelectorAll() メソッドは コンテキストノードサブツリーのなかで、マッチした Element ノードすべてを document order で格納した NodeList を返さなければならない (must)。マッチする Element ノードがない場合、メソッドは空の NodeList を返さなければならない (must)。

querySelectorAll() メソッドから返される NodeList オブジェクトは 動的 (live) ではなく、静的 (static) でなければならない ([DOM-LEVEL-3-CORE], section 1.1.1) (must)。元文書の構造が変化しても、その変化を NodeList オブジェクトに反映することは許されない (must not)。つまり、返されるオブジェクトは、リストが生成された時点で文書に存在していたノードに対しクエリをかけ、マッチする Element ノードを取得することを意味する。

6.2. セレクタの処理

セレクタ文字列 (selector string) とは セレクタのグループ ([SELECT], section 5) を表す。渡されるセレクタは、selectors_group production ([SELECT], section 10) にマッチすべきだ (should)。ただし、セレクタの前後に 空白文字 ([SELECT], section 4) を含めることが許可されている。また、渡されるセレクタは、解決される必要のある名前空間接頭辞 を利用すべきでない (should not)。

selectors の値に nullundefined が渡された場合、実装者は Web IDL [WEBIDL] に従い処理するように望まれている。製作者は、これらの値を渡さないようにすることが望まれている。

擬似要素をセレクタに使うことは可能だが、これは文書中のどの要素にもマッチしないため、何も要素を返さないことになる。このため、製作者はこの使用で定義されるメソッドにおいて、擬似要素を含むセレクタを利用しないことが推奨される。

6.4. セレクタの処理

セレクタのパース (parse a selector) は次のステップで行われる。

  1. このアルゴリズムにおいて、セレクタ文字列selectors と定義する。

  2. セレクタ文字列dom_selectors_group の文法にマッチする場合、その文法に従い selectors をパースし、帰ってきた一連のセレクタを result とする。

  3. マッチしない場合、例外 SYNTAX_ERR を投げ ([DOM-LEVEL-3-CORE], section 1.4) た後にあこのアルゴリズムを終了する。

  4. result を返す。

セレクタの評価 (evaluate a selector) は次のステップで行われる。

  1. 評価される要素を element と定義する。

  2. このアルゴリズムに入力されたセレクタを selector group とする。

  3. selector group 中のセレクタがどれかひとつでも element にマッチした場合、true を返す。マッチしない場合は、false を返す。

セレクタが評価される文脈は、与えられた要素が存在する DOM ツリー全体となる。

CSS をサポートするユーザーエージェントにおいて、実装は CSS でサポートするセレクタと同じサポートを API に対しても行うべきだ (should)。

6.5. 名前空間の解決

セレクタが 解決される必要のある名前空間接頭辞 を含む場合、実装は 例外 SYNTAX_ERR を発生させる 必要がある ([DOM-LEVEL-3-CORE], section 1.4) (must)。

この仕様は現在のバージョンにおいて、名前空間接頭辞を解決するメカニズムをサポートしていない。しかし、将来的に追加することを検討している。

解決される必要のある名前空間接頭辞 (namespace prefix needs to be resolved) とは、名前空間コンポーネントが (null 名前空間を表す) 空の状態 (例: |div) であるものや、どの名前空間をも表すアスタリスク (例: *|div)、このどちらにも当てはまらないものを表す。アスタリスクや空名前空間接頭辞は解決される必要がないため、セレクタの名前空間構文をサポートする実装は、これら2つをサポートしなければならない [SELECT] (must)。

7. DOM Feature 文字列

DOM3 Core では、インターフェースのサポート状況を確かめたり、インターフェースの実装を得たりするため、feature 文字列 (feature strings) を利用するいくつかのメソッドを定義していいる ([DOM-LEVEL-3-CORE], section 1.3.6)。DOM アプリケーションはこのメソッドの引数 feature に "Selectors-API" を、そして version には "1.0" を指定することで利用できる。

これらの引数を hasFeature メソッドに与えたとき、適合する実装は true を返さなければならない (must)。しかし、true が返されたとしても、実装が完全に仕様に適合しているわけではなく、また false が返されたとしても、実装がサポートしている可能性もある。よって、このメソッドの仕様は奨励されない。

8.

このセクションで解説するコードは、次の XHTML 文書を利用している。

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Selectors API Example</title>
  </head>
  <body>
    <div id="foo">
      <p class="warning">This is a sample warning</p>
      <p class="error">This is a sample error</p>
    </div>
    <div id="bar">
      <p>...</p>
    </div>
  </body>
</html>

メソッドは、複数のセレクタ (カンマ区切り) を引数としてとれる。次の例は、class に "error" または "warning" を持つ p 要素すべてを選択する。

var alerts = document.querySelectorAll("p.warning, p.error");

querySelector() メソッドも複数のセレクタを引数にとれるが、返すのはマッチしたもののうち最初の要素のみとなる。

var x = document.querySelector("#foo, #bar");

x は、ID に foo または bar を指定された要素のうち、最初に現れたものを格納する。このセクションの先頭にあるサンプル文書に対しクエリーを実行すると、ID に foo を持つ div 要素が選択される。なぜなら、この要素は document order 上で最初にマッチするからだ。引数に複数のセレクタを渡しても、その順序は結果に何も影響を及ぼさない。次のように順番を逆にしても、おなじ結果を得られる。

var x = document.querySelector("#bar, #foo");

2つのメソッドは、要素からも呼び出せる。次の例では、イベントハンドラが要素に対して登録されているとする。なので、このメソッドはイベントのターゲットとなる要素から呼び出される。

function handle(evt) {
  var x = evt.target.querySelector("span");
  ...
  // Do something with x
}

メソッドは要素から呼び出されるが、セレクタは文書全体を評価する。次の例において、body 要素は div 要素の子孫でないにも関わらず、メソッドは div 要素の子である p にマッチする。

var div = document.getElementById("bar");
var p = bar.querySelector("body p");

次のようなナビゲーションメニューを持つ文書があるとする。

<ul class="nav">
  <li><a href="/">Home</a></li>
  <li><a href="/products">Products</a></li>
  <li><a href="/about">About</a></li>
</ul>

次の例は、すべての li 要素を選択し、その結果の NodeList をイテレートする様子を表す。

var lis = document.querySelectorAll("ul.nav>li");
for (var i = 0; i < lis.length; i++) {
  process(lis.item(i));
}

ECMAScript では、NodeList を配列として扱えるため、次のように書き換えられる。

for (var i = 0; i < lis.length; i++) {
  process(lis[i]);
}

メソッドから返される NodeList オブジェクトは動的ではないため、DOM に行われた変更はリストの内容に影響しない。たとえば、前の例で次の関数 process() を実行したとする。

function process(elmt) {
  elmt.parentNode.removeChild(elmt);
}

このコードは、DOM から選択された要素ひとつずつを削除するが、各要素は NodeList に残る。もしリストが動的な NodeList であれば、DOM から要素を削除したときにリストの要素も変更され、関連する要素のインデックスも調整されるだろう。結果として、ループにおいて意に反する効果が行わる。これは、すべての要素が処理されていないからだ。

複数の名前空間が混在する文書において、それぞれ異なる名前空間に属する要素が、同じローカル名を持つ可能性がある。この API はセレクタの名前空間を解決するメカニズムを備えていないため、特定の名前空間に属する要素を取得するには、何段階かのステップを踏むことになる。次の例は、SVG と XHTML の名前空間が混在する文書から、video 要素を取得するものだ。

<svg id="svg1" xmlns="http://www.w3.org/2000/svg"
               xmlns:xlink="http://www.w3.org/1999/xlink">
  <video id="svgvideo1" xlink:href="myvideo.ogg" width="320" height="240"/>
  <foreignObject width="100" height="100">
    <video id="htmlvideo1" src="myvideo.ogg" xmlns="http://www.w3.org/1999/xhtml">No video1</video>
  </foreignObject>
</svg>

次のスクリプトは、最初に video 要素すべてを取得し、次に名前空間でフィルタをかけ目的の要素のみを抽出する。

var elms = document.querySelectorAll("svg video");
var result = new Array();
var svgns = "http://www.w3.org/2000/svg"

for(var i = 0; i < elms.length; i++) {
  if(elms[i].namespaceURI == svgns) {
    result.push(elms[i]);
  }
}

References

Normative references

[DOM-LEVEL-3-CORE]
Gavin Nicol; et al. Document Object Model (DOM) Level 3 Core Specification. 7 April 2004. W3C Recommendation. URL: http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. Internet RFC 2119. URL: http://www.ietf.org/rfc/rfc2119.txt
[SELECT]
Tantek Çelik; et al. Selectors Level 3. 29 September 2011. W3C Recommendation. URL: http://www.w3.org/TR/2011/REC-css3-selectors-20110929/
[WEBIDL]
Cameron McCormack. Web IDL. 19 December 2008. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2008/WD-WebIDL-20081219

Informative references

[CSS21]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 7 June 2011. W3C Recommendation. URL: http://www.w3.org/TR/2011/REC-CSS2-20110607
[DOM-LEVEL-2-STYLE]
Chris Wilson; Philippe Le Hégaret; Vidur Apparao. Document Object Model (DOM) Level 2 Style Specification. 13 November 2000. W3C Recommendation. URL: http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113
[ECMA-262]
ECMAScript Language Specification, Third Edition. December 1999. URL: http://www.ecma-international.org/publications/standards/Ecma-262.htm

Acknowledgements

The editors would like to thank to the following people who have contributed to this specification (ordered on first name):

Adam van den Hoven, Alan Gresley, Alex Russell, Björn Höhrmann, Boris Zbarsky, Cameron McCormack, Charles McCathieNevile, Chris Wilson, Christophe Jolif, Daniel Glazman, Daniel Schierbeck, Dave Massy, David "liorean" Andersson, David Håsäther, Dean Jackson, Doug Schepers, Erik Dahlström, Francois Remy, Hallvord R. M. Steen, Ian Hickson, Ivan Enderlin, Jean-Yves Bitterlich, Jim Ley, João Eiras, John Resig, Jon Ferraiolo, Jonas Sicking, Jorgen Horstink, Karl Dubost, Kartikaya Gupta, L. David Baron, Maciej Stachowiak, Magnus Kristiansen, Martijn, Masataka Yakura, Mihai Sucan, Mohamed Zergaoui, Nicholas C. Zakas, Nicolas Mendoza, Philip Taylor, Robert Sayre, Robin Berjon, Sander, Sergey Ilinsky, Simon Pieters, Steven Pemberton, Tarquin Wilton-Jones, Travis Leithead, and William J. Edney

Thanks to all those who have helped to improve this specification by sending suggestions and corrections.