Joyquery

Javascript library implementing emulation of CSS selectors lookup, as document.querySelector.

View the Project on GitHub jeremiah-shaulov/joyquery

Home
Features
Selectors
API reference
Adding extensions
Benchmark

See also:
Joyquery for PHP

Selectors in joyquery are regular standard CSS selectors, with some features missing, and some features added (see Features).

Selector expression consists of one or more alternatives separated by commas.

alt1
/* OR */
alt1, alt2, alt3

Each alternative expresses path to follow to find desired elements.

section div a

This means, find element called "section", then inside it find "div", and then inside div find "a". So "a" elements will be returned if found.

In this case "div" can be placed anywhere inside section: as it's direct child, or as a far descendant.

If we want "div" to be related to "section" in some other way, we use axises.

Axises

There are 4 axises in standard CSS: descendant, child, following-sibling and , first-following-sibling.

section div /* descendant */
section > div /* child */
section ~ div /* following-sibling */
section + div /* first-following-sibling */

The joyquery library introduces more axises, inspired by XPATH axises.

section self::*.en /* self */

section > div /* child */
section child::div /* also child */

section div /* descendant */
section descendant::div /* also descendant */

section descendant-or-self::*.en /* descendant-or-self */

section parent::* /* parent */

section ancestor::* /* ancestor */

section ancestor-or-self::* /* ancestor-or-self */

section ~ div /* following-sibling */
section following-sibling::div /* also following-sibling */

section + div /* first-following-sibling */
section first-following-sibling::div /* also first-following-sibling */

section preceding-sibling::* /* preceding-sibling */

section first-preceding-sibling::* /* first-preceding-sibling */

Axis: self

Specifies another conditions for the current element.

Axis: child

Potential matches are children of current element.

Axis: descendant

Potential matches are children of current element, and all elements inside them, no matter the depth.

Axis: descendant-or-self

Among potential matches are the current element itself, and children of the current element, and all elements inside them, no matter the depth.

Axis: parent

Selects parent of current element.

Axis: ancestor

Selects parent and all grandparents of current element.

Axis: ancestor-or-self

Selects current element, it's parent and all it's grandparents.

Axis: following-sibling

Selects elements belonging to the same parent as the current element, only those following the current element.

Axis: first-following-sibling

Selects one element belonging to the same parent as the current element, which follows the current element (if any).

Axis: preceding-sibling

Selects elements belonging to the same parent as the current element, only those preceding the current element.

Axis: first-preceding-sibling

Selects one element belonging to the same parent as the current element, which precedes the current element (if any).

Simple selectors

Each part in complex selector is called simple selector. For example there are 3 simple selectors in "section div a".

Each simple selector consists of element name and conditions. To match any element name, "*" can be used, or name may be omitted. There can be any number of conditions.

[href^="https:"][alt].link

*

Selects element with any name.

*.cls

E

Selects element with specified name.

div.cls

E[foo]

Selects element that has attribute "foo" (possible empty).

option[selected]

E[foo="bar"]

Selects element that has attribute "foo" with value "bar".

a[target="_blank"]

E[foo!="bar"]

Selects element that either don't have attribute "foo", or have it but with value other than "bar".

a[target!="_self"]

E[foo~="bar"]

Selects element whose "foo" attribute value is a list of whitespace-separated values, one of which is exactly equal to "bar".

a[class~="external"]

Element <a class="first external highlighted">...</a> will match.

E[foo^="bar"]

Element whose "foo" attribute value begins with string "bar".

a[target^="_bla"]

E[foo$="bar"]

Element whose "foo" attribute value ends with string "bar".

a[target$="ank"]

E[foo*="bar"]

Element whose "foo" attribute value contains string "bar".

a[target*="bla"]

E[foo|="en"]

Element whose "foo" attribute has a hyphen-separated list of values beginning with "en"

a[lang|="en"]

E:root

Matches if E is the root element, that is document.documentElement (the <html> tag in HTML documents)

*:root

E:nth-child(n), E:nth-child(2n+1)

An E element, the n-th child of its parent. N can be complex number like 2n+1. In this case will select each 2nd matching element with offset +1. In place of 2 and 1 can be any integer number.

.cls:nth-child(3)
.cls:nth-child(4n-1)

E:nth-last-child(n), E:nth-last-child(2n+1)

An E element, the n-th child of its parent, counting from the last one. N can be complex number like 2n+1. In this case will select each 2nd matching element with offset +1. In place of 2 and 1 can be any integer number.

.cls:nth-last-child(3)
.cls:nth-last-child(4n-1)

E:nth-of-type(n), E:nth-of-type(2n+1)

An E element, the n-th child of its parent, counting only elements with the same name as E. N can be complex number like 2n+1. In this case will select each 2nd matching element with offset +1. In place of 2 and 1 can be any integer number.

div:nth-of-type(3)
div:nth-of-type(4n-1)

E:nth-last-of-type(n), E:nth-last-of-type(2n+1)

An E element, the n-th child of its parent, counting from the last one, counting only elements with the same name as E. N can be complex number like 2n+1. In this case will select each 2nd matching element with offset +1. In place of 2 and 1 can be any integer number.

div:nth-last-of-type(3)
div:nth-last-of-type(4n-1)

E:first-child

An E element, first child of its parent.

div:first-child

E:last-child

An E element, last child of its parent.

div:last-child

E:first-of-type

An E element, first child name E of it's parent.

div:first-of-type

E:last-of-type

An E element, last child name E of it's parent.

div:last-of-type

E:only-child

An E element, only child of its parent.

div:only-child

E:only-of-type

An E element, only child named E of its parent.

div:only-of-type

E:empty

Element E that doesn't have element children, and nonempty text children. A text child is considered non-empty if it contains spaces.

div:empty

E:focus

Element currently focused in document (as result of user interaction).

input:focus

E:target

Element whose id attribute equals to text after "#" sign in URL of current page.

div:target

E:enabled

Enabled element, that means element on which interaction with user has not been disabled by doing element.disabled=true. I found that this selector works differently in Chrome and Firefox. Chrome considers <a> tags to be "active", while Firefox doesn't. Joyquery emulated algorythm behaves like Firefox.

*:enabled

E:disabled

Disabled element, which was disabled by doing element.disabled=true.

*:disabled

E:checked

Only <input type="radio">, <input type="checkbox"> and <option> can be "checked".

*:checked

E.class-name

Class. Same as E[class~="class-name"].

*.class-name

E#value

Id. Same as E[id="value"].

#header

E:not(s)

Element that doesn't match any another selector "s". The "s" can be complex selector. It's default axis is self::*. Joyquery implementation is compatible with standard, but extends it (standard says that "s" must be simple selector). But it's not the same as jQuery implementation.

#header:not(.compact + #footer.compact)

Means #header that doesn't have class .compact, and is not followed by #footer.compact. The default self::* axis can be overriden:

#header:not(parent::body[lang="en"])

Means #header, which is not a child of "body[lang="en"]".

E:has(s)

Element E, which also matches selector "s". The "s" can be complex selector. It's default axis is self::*. This implementation is not the same as jQuery's one.

#header:has(* p)

Means #header, that contains p inside it. Without asterisk, it can also match p#header (because of the default axis).

E:any(s1, s2, ...)

Element E, which also matches any of given selectors s1, s2, ... The selectors can be complex selector. Their default axis is self::*.

*:any(input, textarea, select, button)

E:hidden

Element that doesn't occupy space (display:none, type="hidden", etc...).

*:hidden

E:input

Matches <input>, <select>, <textarea> and <button> elements.

*:input

:from(n)

From result set of current simple selector, select results starting from number n. Number n is 1-based, that is :from(1) is default for every simple selector. :from(2) means to skip first result. This is not the same as :nth-child(n) because result of simple selector can include elements belonging to different parent elements.

img:from(3)

:limit(n)

From result set of current simple selector, select no more than n results.

img:from(3):limit(10)

If :from(n) and/or :limit(n) specified several times the last occurance wins, so it's meaningless. In other words, joyquery's :from(n) and :limit(n) work not the same way as jQuery's :gt(n) and :lt(n) do.