Skip to content

Commit 16d11f8

Browse files
committed
minor
1 parent 97a4df7 commit 16d11f8

File tree

1 file changed

+38
-18
lines changed

1 file changed

+38
-18
lines changed

2-ui/1-document/11-coordinates/article.md

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,21 @@
44

55
Большинство соответствующих методов JavaScript работают в одной из двух указанных ниже систем координат:
66

7-
1. **Относительно окна браузера** - похоже на `position:fixed`, отсчёт идёт от верхнего левого угла окна браузера.
7+
1. **Относительно окна браузера** - как `position:fixed`, отсчёт идёт от верхнего левого угла окна.
88
- мы будем обозначать эти координаты как `clientX/clientY`, причина выбора таких имён будет ясна позже, когда мы изучим свойства событий.
9-
2. **Относительно документа** - похоже на `position:absolute` на уровне документа, отсчёт идёт от верхнего левого угла документа.
9+
2. **Относительно документа** - как `position:absolute` на уровне документа, отсчёт идёт от верхнего левого угла документа.
1010
- мы будем обозначать эти координаты как `pageX/pageY`.
1111

12-
Когда страница полностью прокручена наверх, то верхний левый угол окна совпадает с левым верхним углом документа, из чего следует, что обе системы координат тоже совпадают. Но если происходит прокрутка вниз, то координаты элементов в контексте окна меняются, так как они двигаются, но в то же время их координаты относительно документа остаются такими же.
12+
Когда страница полностью прокручена в самое начало, то верхний левый угол окна совпадает с левым верхним углом документа, при этом обе этих системы координат тоже совпадают. Но если происходит прокрутка, то координаты элементов в контексте окна меняются, так как они двигаются, но в то же время их координаты относительно документа остаются такими же.
1313

14-
На приведённой картинке слева показана ситуация до прокрутки страницы, а справа - после:
14+
На приведённой картинке взята точка в документе и показаны её координат до прокрутки (слева) и после (справа):
1515

1616
![](document-and-window-coordinates-scrolled.svg)
1717

18-
Поскольку документ сдвинулся вверх, то:
19-
- `pageY` - координата произвольной точки относительно документа осталась без изменений, так как отсчёт по-прежнему ведётся от верхней границы документа (сейчас она прокручена наверх).
18+
При прокрутке документа:
19+
- `pageY` - координата точки относительно документа осталась без изменений, так как отсчёт по-прежнему ведётся от верхней границы документа (сейчас она прокручена наверх).
2020
- `clientY` - координата точки относительно окна изменилась (стрелка на рисунке стала короче), так как точка стала ближе к верхней границе окна.
2121

22-
В этой главе мы увидим и другие примеры координат элементов относительно окна и документа.
23-
2422
## Координаты относительно окна: getBoundingClientRect
2523

2624
Метод `elem.getBoundingClientRect()` возвращает координаты в контексте окна для минимального по размеру прямоугольника, который заключает в себе элемент `elem`, в виде объекта встроенного класса [DOMRect](https://www.w3.org/TR/geometry-1/#domrect).
@@ -38,7 +36,7 @@
3836
```online
3937
Кликните на кнопку, чтобы увидеть её координаты относительно окна:
4038
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>
4240
4341
<script>
4442
function showRect(elem) {
@@ -55,20 +53,20 @@ right:${r.right}
5553
}
5654
</script>
5755
58-
Если вы прокрутите страницу, то расположение кнопки в окне поменяется, и, соответсвенно, её координаты в контексте окна тоже (при вертикальной прокрутке - `y/top/bottom`).
56+
Если вы прокрутите страницу, то расположение кнопки в окне поменяется, и, соответственно, её координаты в контексте окна тоже (при вертикальной прокрутке - `y/top/bottom`).
5957
```
6058

6159
Вот картинка с результатами вызова `elem.getBoundingClientRect()`:
6260

6361
![](coordinates.svg)
6462

65-
Как вы видите, `x/y` и `width/height` полностью описывают прямоугольник. Остальные свойства могут быть легко вычислены на их основе:
63+
Как вы видите, `x/y` и `width/height` уже точно задают прямоугольник. Остальные свойства могут быть легко вычислены на их основе:
6664
- `left = x`
6765
- `top = y`
6866
- `right = x + width`
6967
- `bottom = y + height`
7068

71-
Также:
69+
Заметим:
7270

7371
- Координаты могут считаться с десятичной частью, например `10.5`. Это нормально, ведь браузер использует дроби в своих внутренних вычислениях. Мы не обязаны округлять значения при установке `style.position.left/top`.
7472
- Координаты могут быть отрицательными. Например, если страница прокручена так, что элемент `elem` ушёл вверх за пределы окна, то вызов `elem.getBoundingClientRect().top` вернёт отрицательное значение.
@@ -78,25 +76,27 @@ right:${r.right}
7876

7977
Так что дополнительные зависимые свойства существуют лишь для удобства.
8078

81-
Технически, значения `width/height` могут быть отрицательными, это удобно, чтобы задавать "направленные" прямоугольники, например, для выделения мышью с отмеченным началом и концом.
79+
Технически, значения `width/height` могут быть отрицательными, это позволяет задать "направленный" прямоугольник, например, для выделения мышью с отмеченным началом и концом.
8280

8381
Вот прямоугольник с отрицательными `width` и `height` (например, `width=-200`, `height=-100`):
8482

8583
![](coordinates-negative.svg)
8684

87-
Он начинается в своём правом-нижнем углу, и затем "разворачивается" влево-вверх, так как отрицательные width/height ведут его назад по координатам.
85+
Он начинается в своём правом-нижнем углу, и затем "растёт" влево-вверх, так как отрицательные `width/height` ведут его назад по координатам.
8886

8987
Как вы видите, свойства `left/top` здесь не равны `x/y`. То есть они не дублируют друг друга. Формулы выше могут быть исправлены с учётом возможных отрицательных значений `width/height`. Это достаточно просто сделать, но редко требуется, так как результат вызова `elem.getBoundingClientRect()` всегда возвращает положительные значения для ширины/высоты.
88+
89+
Здесь мы упомянули отрицательные `width/height` лишь для того, чтобы вы поняли, почему эти с виду дублирующие свойства на самом деле не являются дубликатами.
9090
```
9191
9292
```warn header="Internet Explorer и Edge: не поддерживают `x/y`"
9393
Internet Explorer и Edge не поддерживают свойства `x/y` по историческим причинам.
9494
95-
Таким образом, мы можем либо сделать полифил (добавив соответствующие геттеры в `DomRect.prototype`), либо использовать `top/left`, так как это всегда то же, что и `x/y`, в результате `elem.getBoundingClientRect()`.
95+
Таким образом, мы можем либо сделать полифил (добавив соответствующие геттеры в `DomRect.prototype`), либо использовать `top/left`, так как это всегда одно и то же при положительных `width/height`, в частности - в результате вызова `elem.getBoundingClientRect()`.
9696
```
9797

9898
```warn header="Координаты right/bottom отличаются от одноимённых CSS-свойств"
99-
Есть очевидное сходство между координатами относительно окна и CSS `position:fixed`. Ведь такое CSS-позиционирование тоже происходит относительно окна браузера (или его видимой части).
99+
Есть очевидное сходство между координатами относительно окна и CSS `position:fixed`.
100100
101101
Но в CSS свойство `right` означает расстояние от правого края, и свойство `bottom` означает расстояние от нижнего края окна браузера.
102102
@@ -145,9 +145,9 @@ elem.style.background = ''; // Ошибка!
145145
146146
## Применение для fixed позиционирования
147147
148-
Чаще всего нам нужны координаты для позиционирования чего-либо. В CSS для позиционирования элемента относительно окна браузера используется свойство `position:fixed` вместе со свойствами `left/top` (или `right/bottom`).
148+
Чаще всего нам нужны координаты для позиционирования чего-либо.
149149
150-
Мы можем вызвать `getBoundingClientRect`, чтобы получить координаты элемента, а затем показать что-то около него.
150+
Чтобы показать что-то около нужного элемента, мы можем вызвать `getBoundingClientRect`, чтобы получить его координаты элемента, а затем использовать CSS-свойство `position` вместе с `left/top` (или `right/bottom`).
151151
152152
Например, функция `createMessageUnder(elem, html)` ниже показывает сообщение под элементом `elem`:
153153
@@ -222,6 +222,26 @@ function getCoords(elem) {
222222
}
223223
```
224224
225+
Если бы в примере выше мы использовали её вместе с `position:absolute`, то при прокрутке сообщение оставалось бы рядом с элементом.
226+
227+
Модифицированная функция `createMessageUnder`:
228+
229+
```js
230+
function createMessageUnder(elem, html) {
231+
let message = document.createElement('div');
232+
message.style.cssText = "*!*position:absolute*/!*; color: red";
233+
234+
let coords = *!*getCoords(elem);*/!*
235+
236+
message.style.left = coords.left + "px";
237+
message.style.top = coords.bottom + "px";
238+
239+
message.innerHTML = html;
240+
241+
return message;
242+
}
243+
```
244+
225245
## Итого
226246
227247
Любая точка на странице имеет координаты:

0 commit comments

Comments
 (0)