You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 2-ui/1-document/11-coordinates/article.md
+38-18Lines changed: 38 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,23 +4,21 @@
4
4
5
5
Большинство соответствующих методов JavaScript работают в одной из двух указанных ниже систем координат:
6
6
7
-
1.**Относительно окна браузера** - похоже на `position:fixed`, отсчёт идёт от верхнего левого угла окна браузера.
7
+
1.**Относительно окна браузера** - как `position:fixed`, отсчёт идёт от верхнего левого угла окна.
8
8
- мы будем обозначать эти координаты как `clientX/clientY`, причина выбора таких имён будет ясна позже, когда мы изучим свойства событий.
9
-
2.**Относительно документа** - похоже на`position:absolute` на уровне документа, отсчёт идёт от верхнего левого угла документа.
9
+
2.**Относительно документа** - как`position:absolute` на уровне документа, отсчёт идёт от верхнего левого угла документа.
10
10
- мы будем обозначать эти координаты как `pageX/pageY`.
11
11
12
-
Когда страница полностью прокручена наверх, то верхний левый угол окна совпадает с левым верхним углом документа, из чего следует, что обе системы координат тоже совпадают. Но если происходит прокрутка вниз, то координаты элементов в контексте окна меняются, так как они двигаются, но в то же время их координаты относительно документа остаются такими же.
12
+
Когда страница полностью прокручена в самое начало, то верхний левый угол окна совпадает с левым верхним углом документа, при этом обе этих системы координат тоже совпадают. Но если происходит прокрутка, то координаты элементов в контексте окна меняются, так как они двигаются, но в то же время их координаты относительно документа остаются такими же.
13
13
14
-
На приведённой картинке слева показана ситуация до прокрутки страницы, а справа - после:
14
+
На приведённой картинке взята точка в документе и показаны её координат до прокрутки (слева) и после (справа):
15
15
16
16

17
17
18
-
Поскольку документ сдвинулся вверх, то:
19
-
-`pageY` - координата произвольной точки относительно документа осталась без изменений, так как отсчёт по-прежнему ведётся от верхней границы документа (сейчас она прокручена наверх).
18
+
При прокрутке документа:
19
+
-`pageY` - координата точки относительно документа осталась без изменений, так как отсчёт по-прежнему ведётся от верхней границы документа (сейчас она прокручена наверх).
20
20
-`clientY` - координата точки относительно окна изменилась (стрелка на рисунке стала короче), так как точка стала ближе к верхней границе окна.
21
21
22
-
В этой главе мы увидим и другие примеры координат элементов относительно окна и документа.
23
-
24
22
## Координаты относительно окна: getBoundingClientRect
25
23
26
24
Метод `elem.getBoundingClientRect()` возвращает координаты в контексте окна для минимального по размеру прямоугольника, который заключает в себе элемент `elem`, в виде объекта встроенного класса [DOMRect](https://www.w3.org/TR/geometry-1/#domrect).
@@ -38,7 +36,7 @@
38
36
```online
39
37
Кликните на кнопку, чтобы увидеть её координаты относительно окна:
40
38
41
-
<input id="brTest" type="button" value="Показать результат вызова button.getBoundingClientRect() для этой кнопки" onclick='showRect(this)'/>
39
+
<p><input id="brTest" type="button" value="Показать результат вызова button.getBoundingClientRect() для этой кнопки" onclick='showRect(this)'/></p>
42
40
43
41
<script>
44
42
function showRect(elem) {
@@ -55,20 +53,20 @@ right:${r.right}
55
53
}
56
54
</script>
57
55
58
-
Если вы прокрутите страницу, то расположение кнопки в окне поменяется, и, соответсвенно, её координаты в контексте окна тоже (при вертикальной прокрутке - `y/top/bottom`).
56
+
Если вы прокрутите страницу, то расположение кнопки в окне поменяется, и, соответственно, её координаты в контексте окна тоже (при вертикальной прокрутке - `y/top/bottom`).
59
57
```
60
58
61
59
Вот картинка с результатами вызова `elem.getBoundingClientRect()`:
62
60
63
61

64
62
65
-
Как вы видите, `x/y` и `width/height`полностью описывают прямоугольник. Остальные свойства могут быть легко вычислены на их основе:
63
+
Как вы видите, `x/y` и `width/height`уже точно задают прямоугольник. Остальные свойства могут быть легко вычислены на их основе:
66
64
-`left = x`
67
65
-`top = y`
68
66
-`right = x + width`
69
67
-`bottom = y + height`
70
68
71
-
Также:
69
+
Заметим:
72
70
73
71
- Координаты могут считаться с десятичной частью, например `10.5`. Это нормально, ведь браузер использует дроби в своих внутренних вычислениях. Мы не обязаны округлять значения при установке `style.position.left/top`.
74
72
- Координаты могут быть отрицательными. Например, если страница прокручена так, что элемент `elem` ушёл вверх за пределы окна, то вызов `elem.getBoundingClientRect().top` вернёт отрицательное значение.
@@ -78,25 +76,27 @@ right:${r.right}
78
76
79
77
Так что дополнительные зависимые свойства существуют лишь для удобства.
80
78
81
-
Технически, значения `width/height` могут быть отрицательными, это удобно, чтобы задавать "направленные" прямоугольники, например, для выделения мышью с отмеченным началом и концом.
79
+
Технически, значения `width/height` могут быть отрицательными, это позволяет задать "направленный" прямоугольник, например, для выделения мышью с отмеченным началом и концом.
82
80
83
81
Вот прямоугольник с отрицательными `width` и `height` (например, `width=-200`, `height=-100`):
84
82
85
83

86
84
87
-
Он начинается в своём правом-нижнем углу, и затем "разворачивается" влево-вверх, так как отрицательные width/height ведут его назад по координатам.
85
+
Он начинается в своём правом-нижнем углу, и затем "растёт" влево-вверх, так как отрицательные `width/height` ведут его назад по координатам.
88
86
89
87
Как вы видите, свойства `left/top` здесь не равны `x/y`. То есть они не дублируют друг друга. Формулы выше могут быть исправлены с учётом возможных отрицательных значений `width/height`. Это достаточно просто сделать, но редко требуется, так как результат вызова `elem.getBoundingClientRect()` всегда возвращает положительные значения для ширины/высоты.
88
+
89
+
Здесь мы упомянули отрицательные `width/height` лишь для того, чтобы вы поняли, почему эти с виду дублирующие свойства на самом деле не являются дубликатами.
90
90
```
91
91
92
92
```warn header="Internet Explorer и Edge: не поддерживают `x/y`"
93
93
Internet Explorer и Edge не поддерживают свойства `x/y` по историческим причинам.
94
94
95
-
Таким образом, мы можем либо сделать полифил (добавив соответствующие геттеры в `DomRect.prototype`), либо использовать `top/left`, так как это всегда то же, что и `x/y`, в результате `elem.getBoundingClientRect()`.
95
+
Таким образом, мы можем либо сделать полифил (добавив соответствующие геттеры в `DomRect.prototype`), либо использовать `top/left`, так как это всегда одно и то же при положительных `width/height`, в частности - в результате вызова `elem.getBoundingClientRect()`.
96
96
```
97
97
98
98
```warn header="Координаты right/bottom отличаются от одноимённых CSS-свойств"
99
-
Есть очевидное сходство между координатами относительно окна и CSS `position:fixed`. Ведь такое CSS-позиционирование тоже происходит относительно окна браузера (или его видимой части).
99
+
Есть очевидное сходство между координатами относительно окна и CSS `position:fixed`.
100
100
101
101
Но в CSS свойство `right` означает расстояние от правого края, и свойство `bottom` означает расстояние от нижнего края окна браузера.
Чаще всего нам нужны координаты для позиционирования чего-либо. В CSS для позиционирования элемента относительно окна браузера используется свойство `position:fixed` вместе со свойствами `left/top` (или `right/bottom`).
148
+
Чаще всего нам нужны координаты для позиционирования чего-либо.
149
149
150
-
Мы можем вызвать `getBoundingClientRect`, чтобы получить координаты элемента, а затем показать что-то около него.
150
+
Чтобы показать что-то около нужного элемента, мы можем вызвать `getBoundingClientRect`, чтобы получить его координаты элемента, а затем использовать CSS-свойство `position` вместе с `left/top` (или `right/bottom`).
151
151
152
152
Например, функция `createMessageUnder(elem, html)` ниже показывает сообщение под элементом `elem`:
153
153
@@ -222,6 +222,26 @@ function getCoords(elem) {
222
222
}
223
223
```
224
224
225
+
Если бы в примере выше мы использовали её вместе с `position:absolute`, то при прокрутке сообщение оставалось бы рядом с элементом.
0 commit comments