mozilla

Revision 286651 of QuerySelector

  • Revision slug: Code_snippets/QuerySelector
  • Revision title: QuerySelector
  • Revision id: 286651
  • Created:
  • Creator: Canuckistani
  • Is current revision? No
  • Comment 1 words removed

Revision Content

 {{ fx_minversion_header(3.5) }}

Along the lines of other frameworks such as jQuery or Prototype, shortening the "querySelector" name can be convenient.

function $ (selector, el) {
     if (!el) {el = document;}
     return el.querySelector(selector);
}
function $$ (selector, el) {
     if (!el) {el = document;}
     return el.querySelectorAll(selector);
     // Note: the returned object is a NodeList.
     // If you'd like to convert it to a Array for convenience, use this instead:
     // return Array.prototype.slice.call(el.querySelectorAll(selector));
}
alert($('#myID').id);

Both XUL and even XML can be easily made supportable (an alternative approach to the following would be to add ChromeWindow.prototype or Window.prototype, accessing this.document.querySelector, or following the jQuery style of chaining by returning 'this' within each prototype method of $()):

HTMLDocument.prototype.$ = function (selector) { // Only for HTML
    return this.querySelector(selector);
};

Example:

<h1>Test!</h1>
<script>
HTMLDocument.prototype.$ = function (selector) {
    return this.querySelector(selector); 
}; 
alert(document.$('h1')); // [object HTMLHeadingElement]
</script>
XULDocument.prototype.$ = function (selector) { // Only for XUL
    return this.querySelector(selector);
};

Example:

<label value="Test!"/>
<script type="text/javascript"><![CDATA[
XULDocument.prototype.$ = function (selector) { // Only for XUL
    return this.querySelector(selector);
};

alert(document.$('label')); // [object XULElement]
]]></script>
Document.prototype.$ = function (selector) { // Only for plain XML
    return this.querySelector(selector);
};
var foo = document.implementation.createDocument('someNS', 'foo', null); // Create an XML document <foo xmlns="someNS"/>
var bar = foo.createElementNS('someNS', 'bar'); // add <bar xmlns="someNS"/>
foo.documentElement.appendChild(bar);
alert(foo.$('bar').nodeName); // gives 'bar'
Element.prototype.$ = function (selector) { // Works for HTML, XUL, and plain XML
    return this.querySelector(selector);
};

HTML example:
<h1>Test!<a/></h1>
<script>
Element.prototype.$ = function (selector) {
    return this.querySelector(selector); 
};
alert(document.getElementsByTagName('h1')[0].$('a').nodeName); // 'A'

XUL example:
<hbox><vbox/></hbox>
<script type="text/javascript"><![CDATA[
Element.prototype.$ = function (selector) {
    return this.querySelector(selector); 
};
var XULNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
alert(document.getElementsByTagNameNS(XULNS, 'hbox')[0].$('vbox').nodeName); // vbox
]]></script>

XML example:
<foo xmlns="someNS"><bar/></foo> in document earlier
var foo = document.getElementsByTagNameNS('someNS', 'foo')[0];
alert(foo.$('bar'));

Note that for plain XML, the # 'id' selector will not work with an 'id' attribute (since a such-named attribute need not necessarily be of type ID in XML, though it is in HTML and XUL), nor will it work with xml:id. However, it will work with attribute selectors that target non-prefixed attributes (such as 'id', but not xml:id: http://www.w3.org/TR/selectors-api/#resolving) (even though CSS3 does support namespaced attribute selectors: http://www.w3.org/TR/css3-selectors/#attrnmsp and potentially xml:id as #: http://www.w3.org/TR/css3-selectors/#id-selectors ).

Revision Source

<p> {{ fx_minversion_header(3.5) }}</p>
<p>Along the lines of other frameworks such as jQuery or Prototype, shortening the "querySelector" name can be convenient.</p>
<pre class="brush: js">function $ (selector, el) {
     if (!el) {el = document;}
     return el.querySelector(selector);
}
function $$ (selector, el) {
     if (!el) {el = document;}
     return el.querySelectorAll(selector);
     // Note: the returned object is a NodeList.
     // If you'd like to convert it to a Array for convenience, use this instead:
     // return Array.prototype.slice.call(el.querySelectorAll(selector));
}
alert($('#myID').id);
</pre>
<p>Both XUL and even XML can be easily made supportable (an alternative approach to the following would be to add ChromeWindow.prototype or Window.prototype, accessing this.document.querySelector, or following the jQuery style of chaining by returning 'this' within each prototype method of $()):</p>
<pre class="brush: js">HTMLDocument.prototype.$ = function (selector) { // Only for HTML
    return this.querySelector(selector);
};

Example:

&lt;h1&gt;Test!&lt;/h1&gt;
&lt;script&gt;
HTMLDocument.prototype.$ = function (selector) {
    return this.querySelector(selector); 
}; 
alert(document.$('h1')); // [object HTMLHeadingElement]
&lt;/script&gt;
</pre>
<pre class="brush: js">XULDocument.prototype.$ = function (selector) { // Only for XUL
    return this.querySelector(selector);
};

Example:

&lt;label value="Test!"/&gt;
&lt;script type="text/javascript"&gt;&lt;![CDATA[
XULDocument.prototype.$ = function (selector) { // Only for XUL
    return this.querySelector(selector);
};

alert(document.$('label')); // [object XULElement]
]]&gt;&lt;/script&gt;
</pre>
<pre class="brush: js">Document.prototype.$ = function (selector) { // Only for plain XML
    return this.querySelector(selector);
};
var foo = document.implementation.createDocument('someNS', 'foo', null); // Create an XML document &lt;foo xmlns="someNS"/&gt;
var bar = foo.createElementNS('someNS', 'bar'); // add &lt;bar xmlns="someNS"/&gt;
foo.documentElement.appendChild(bar);
alert(foo.$('bar').nodeName); // gives 'bar'
</pre>
<pre class="brush: js">Element.prototype.$ = function (selector) { // Works for HTML, XUL, and plain XML
    return this.querySelector(selector);
};

HTML example:
&lt;h1&gt;Test!&lt;a/&gt;&lt;/h1&gt;
&lt;script&gt;
Element.prototype.$ = function (selector) {
    return this.querySelector(selector); 
};
alert(document.getElementsByTagName('h1')[0].$('a').nodeName); // 'A'

XUL example:
&lt;hbox&gt;&lt;vbox/&gt;&lt;/hbox&gt;
&lt;script type="text/javascript"&gt;&lt;![CDATA[
Element.prototype.$ = function (selector) {
    return this.querySelector(selector); 
};
var XULNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
alert(document.getElementsByTagNameNS(XULNS, 'hbox')[0].$('vbox').nodeName); // vbox
]]&gt;&lt;/script&gt;

XML example:
&lt;foo xmlns="someNS"&gt;&lt;bar/&gt;&lt;/foo&gt; in document earlier
var foo = document.getElementsByTagNameNS('someNS', 'foo')[0];
alert(foo.$('bar'));

</pre>
<p>Note that for plain XML, the # 'id' selector will not work with an 'id' attribute (since a such-named attribute need not necessarily be of type ID in XML, though it is in HTML and XUL), nor will it work with <a href="/en/xml/xml:id" title="en/xml/id">xml:id</a>. However, it will work with attribute selectors that target non-prefixed attributes (such as 'id', but not xml:id: <a class=" external" href="http://www.w3.org/TR/selectors-api/#resolving" rel="freelink">http://www.w3.org/TR/selectors-api/#resolving</a>) (even though CSS3 does support namespaced attribute selectors: <a class=" external" href="http://www.w3.org/TR/css3-selectors/#attrnmsp" rel="freelink">http://www.w3.org/TR/css3-selectors/#attrnmsp</a> and potentially xml:id as #: <a class=" external" href="http://www.w3.org/TR/css3-selectors/#id-selectors" rel="freelink">http://www.w3.org/TR/css3-selectors/#id-selectors</a> ).</p>
Revert to this revision