This commit is contained in:
Ilya Kantor 2019-07-19 23:43:28 +03:00
parent 746fe5f2b6
commit 5d549f537f
2 changed files with 12 additions and 36 deletions

View file

@ -74,31 +74,27 @@ Also:
- Coordinates may be negative. For instance, if the page is scrolled so that `elem` is now above the window, then `elem.getBoundingClientRect().top` is negative. - Coordinates may be negative. For instance, if the page is scrolled so that `elem` is now above the window, then `elem.getBoundingClientRect().top` is negative.
```smart header="Why derived properties are needed? Why does `top/left` exist if there's `x/y`?" ```smart header="Why derived properties are needed? Why does `top/left` exist if there's `x/y`?"
Mathematically, a rectangle is uniquely defined with its starting point `(x,y)` and the direction vector `(width,height)`. Mathematically, a rectangle is uniquely defined with its starting point `(x,y)` and the direction vector `(width,height)`. So the additional derived properties are for convenience.
So the additional derived properties are for convenience. Technically it's possible for `width/height` to be negative, that's useful for "directed" rectangles, e.g. to represent mouse selection with properly marked start and end.
Please note that technically it's possible for `width/height` to be negative. A rectangle starts at `(x,y)` and `(width,height)` is actually the direction vector where it goes.
Negative `width/height` may be useful for directed rectangles, e.g. to represent mouse selections with properly marked start and end.
Here's a rectangle with negative `width` and `height` (e.g. `width=-200`, `height=-100`): Here's a rectangle with negative `width` and `height` (e.g. `width=-200`, `height=-100`):
![](coordinates-negative.png) ![](coordinates-negative.png)
The rectangle above starts at its bottom-right corner and then spans left/up. The rectangle starts at its bottom-right corner and then spans left/up, as negative `width/height` lead it backwards by coordinates.
As you can see, `left/top` are not `x/y` here. So these are actually not duplicates. The formula can be adjusted to cover negative `width/height`. That's simple enough to do, but rarely needed, as the result of `elem.getBoundingClientRect()` always has positive width/height. As you can see, `left/top` are not `x/y` here. So these are actually not duplicates. Their formula can be adjusted to cover negative `width/height`, that's simple enough, but rarely needed, as the result of `elem.getBoundingClientRect()` always has positive width/height.
``` ```
```warn header="Internet Explorer and Edge: no support for `x/y`" ```warn header="Internet Explorer and Edge: no support for `x/y`"
Internet Explorer and Edge don't support `x/y` properties for historical reasons. Internet Explorer and Edge don't support `x/y` properties for historical reasons.
So we can either make a polywill (add getters in `DomRect.prototype`) or just use `top/left`, as they are always the same for `elem.getBoundingClientRect()`. So we can either make a polywill (add getters in `DomRect.prototype`) or just use `top/left`, as they are always the same as `x/y` for `elem.getBoundingClientRect()`.
``` ```
```warn header="Coordinates right/bottom are different from CSS position properties" ```warn header="Coordinates right/bottom are different from CSS position properties"
If we compare window coordinates versus CSS positioning, then there are obvious similarities to `position:fixed`, it's also relative to the viewport. There are obvious similarities between window-relative coordinates and CSS `position:fixed`.
But in CSS positioning, `right` property means the distance from the right edge, and `bottom` property means the distance from the bottom edge. But in CSS positioning, `right` property means the distance from the right edge, and `bottom` property means the distance from the bottom edge.
@ -134,8 +130,6 @@ The method `document.elementFromPoint(x,y)` only works if `(x,y)` are inside the
If any of the coordinates is negative or exceeds the window width/height, then it returns `null`. If any of the coordinates is negative or exceeds the window width/height, then it returns `null`.
In most cases such behavior is not a problem, but we should keep that in mind.
Here's a typical error that may occur if we don't check for it: Here's a typical error that may occur if we don't check for it:
```js ```js
@ -147,7 +141,7 @@ elem.style.background = ''; // Error!
``` ```
```` ````
## Using for position:fixed ## Using for "fixed" positioning
Most of time we need coordinates to position something. In CSS, to position an element relative to the viewport we use `position:fixed` together with `left/top` (or `right/bottom`). Most of time we need coordinates to position something. In CSS, to position an element relative to the viewport we use `position:fixed` together with `left/top` (or `right/bottom`).
@ -198,7 +192,7 @@ The reason is obvious: the message element relies on `position:fixed`, so it rem
To change that, we need to use document-based coordinates and `position:absolute`. To change that, we need to use document-based coordinates and `position:absolute`.
## Document coordinates ## Document coordinates [#getCoords]
Document-relative coordinates start from the upper-left corner of the document, not the window. Document-relative coordinates start from the upper-left corner of the document, not the window.
@ -206,24 +200,6 @@ In CSS, window coordinates correspond to `position:fixed`, while document coordi
We can use `position:absolute` and `top/left` to put something at a certain place of the document, so that it remains there during a page scroll. But we need the right coordinates first. We can use `position:absolute` and `top/left` to put something at a certain place of the document, so that it remains there during a page scroll. But we need the right coordinates first.
For clarity we'll call window coordinates `(clientX,clientY)` and document coordinates `(pageX,pageY)`.
When the page is not scrolled, then window coordinate and document coordinates are actually the same. Their zero points match too:
![](document-window-coordinates-zero.png)
And if we scroll it, then `(clientX,clientY)` change, because they are relative to the window, but `(pageX,pageY)` remain the same.
Here's the same page after the vertical scroll:
![](document-window-coordinates-scroll.png)
- `clientY` of the header `"From today's featured article"` became `0`, because the element is now on window top.
- `clientX` didn't change, as we didn't scroll horizontally.
- `pageX` and `pageY` coordinates of the element are still the same, because they are relative to the document.
## Getting document coordinates [#getCoords]
There's no standard method to get the document coordinates of an element. But it's easy to write it. There's no standard method to get the document coordinates of an element. But it's easy to write it.
The two coordinate systems are connected by the formula: The two coordinate systems are connected by the formula:

View file

@ -12,9 +12,9 @@ We can define them with a special class, and then use as if they were always a p
There are two kinds of custom elements: There are two kinds of custom elements:
1. **Autonomous custom elements** -- "all-new" elements, extending the abstract `HTMLElement` class. 1. **Autonomous custom elements** -- "all-new" elements, extending the abstract `HTMLElement` class.
2. **Customized built-in elements** -- extending built-in elements, like customized `HTMLButtonElement` etc. 2. **Customized built-in elements** -- extending built-in elements, like a customized button, based on `HTMLButtonElement` etc.
First we'll create autonomous elements, and then customized built-in ones. First we'll cover autonomous elements, and then move to customized built-in ones.
To create a custom element, we need to tell the browser several details about it: how to show it, what to do when the element is added or removed to page, etc. To create a custom element, we need to tell the browser several details about it: how to show it, what to do when the element is added or removed to page, etc.
@ -30,12 +30,12 @@ class MyElement extends HTMLElement {
} }
connectedCallback() { connectedCallback() {
// browser calls it when the element is added to the document // browser calls this method when the element is added to the document
// (can be called many times if an element is repeatedly added/removed) // (can be called many times if an element is repeatedly added/removed)
} }
disconnectedCallback() { disconnectedCallback() {
// browser calls it when the element is removed from the document // browser calls this method when the element is removed from the document
// (can be called many times if an element is repeatedly added/removed) // (can be called many times if an element is repeatedly added/removed)
} }