Skip to content

Instantly share code, notes, and snippets.

@jonathantneal
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonathantneal/8f9071982c94d36773ba to your computer and use it in GitHub Desktop.
Save jonathantneal/8f9071982c94d36773ba to your computer and use it in GitHub Desktop.
Position Queries

Position Queries

A position query is a simple expression used to filter elements by their position on the screen.

An expression is made up of a property and a value. The property describes the measured edge of the element by using top, bottom, left, or right. The value describes the measured edge and position of the screen by adding before or after.

For example, the following query checks if the element is above the screen. It does this by checking if the bottom of the element comes before the top of the screen.

<div position="(bottom: before-top)"></div>

The and operator is used to link multiple queries. For example, the following query checks if the element is on screen. It does this by checking if the top of the element comes before the bottom of the screen and also if the bottom of the element comes after the top of the screen.

<div position="(top: before-bottom) and (bottom: after-top)"></div>

The or (,) operator is used to separate queries. For example, the following query checks if the element is off screen. It does this by checking if the top of the element comes after the bottom of the screen or if the bottom of the element comes before the top of the screen.

<div position="(top: after-bottom), (bottom: before-top)"></div>

A preceding measurement is used to modify the measured edge of the screen. For example, the following query checks if the end of the element is nearing the bottom of the screen. It does this by checking if the bottom of the element is -100px before the bottom of the screen.

<div position="(bottom: -100px before-bottom)"></div>

A second preceding measurement is used to modify the measured edge of the element. For example, the following query also checks if the halfway end of the element is nearing the bottom of the screen. It does this by checking if the bottom 50% of the element is -100px before the bottom of the screen.

<div position="(bottom: 50% -100px before-bottom)"></div>
(function () {
var
EDGE = '(bottom|left|right|top)',
POSITION = '(?:(after|before)-' + EDGE + ')',
VALUE = '([0-9-][0-9.]*)(%|cm|em|in|mm|pc|pt|px|rem)',
MEASUREMENT = '(?:' + VALUE + '\\s+)?',
QUERY = '\\(\\s*' + EDGE + '\\s*:\\s*' + MEASUREMENT + MEASUREMENT + POSITION + '\\s*\\)',
AND = '\\s+(and)\\s+',
OR = '\\s*(,)\\s*',
REGEX = '^' + QUERY + '|^' + AND + '|^' + OR;
function parsePositionQueries(selector) {
var
groups = [],
group = [],
query = {},
match;
groups.push(group);
group.push(query);
while (match = selector.match(REGEX)) {
if (match[8]) {
group.push(query = {});
}
else if (match[9]) {
groups.push(group = [query = {}]);
}
else {
query.elementEdge = match[1] || 'top';
query.elementOffset = match[2] ? [match[2], match[3]] : [0, 'px'];
query.containerOffset = match[4] ? [match[4], match[5]] : [0, 'px'];
query.containerPosition = match[6] || 'before';
query.containerEdge = match[7] || 'top';
}
selector = selector.slice(match[0].length);
}
return groups;
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment