На этом занятии
мы рассмотрим метрики, используемые для позиционирования элементов и их
содержимого на экране браузера. Чтобы лучше их понять, предположим, что у нас
есть вот такой документ:
<!DOCTYPE html>
<html>
<head>
<title>Уроки по JavaScript</title>
<style>
body {
margin: 0;
}
.message {
border: 20px solid #007700;
width: 300px;
height: 200px;
overflow: auto;
padding: 10px;
background: #eee;
font-size: 24px;
margin: 50px 0 0 100px;
}
</style>
</head>
<body>
<div class="message">
<h3>Уроки по JavaScript</h3>
<p>На этом занятии мы рассмотрим метрики, используемые для
позиционирования элементов и их содержимого
на экране браузера. Чтобы лучше их понять, рассмотрим такой рисунок.</p>
</div>
<script>
</script>
</body>
</html>
Который на
экране браузера выглядит так. Обратите внимание, что в документе обязательно
должен быть указан
который говорит
браузеру, что HTML-страницу
следует воспринимать по стандарту HTML 5.x. От этого могут
зависеть значения метрик, о которых здесь пойдет речь.
Теперь смотрите,
у нашего блока div реальные размеры составляют 360 на 260 пикселей и
имеется множество различных отступов: margin, border и padding. Так вот, ко
всем этим параметрам блока div можно получить доступ из JavaScript. Они и
называются метриками. Рассмотрим их по порядку. Начнем со свойств:
-
elem.clientWidth – содержит
ширину клиентской области (в пикселах);
-
elem.clientHeight
– содержит высоту клиентской области (в пикселах).
Выведем их в консоль:
let elem = document.querySelector("div.message");
console.log(elem.clientWidth, elem.clientHeight);
Увидим значения:
305 и 220 пикселей. Откуда взялись такие числа? Изначально мы задавали ширину,
равную 300 пикселей. К этому значению прибавляются отступы padding по 10 пикселей
и вычитается ширина полосы прокрутки, которая в данном случае съедает 15
пикселей, получаем:
clientWidth = 300+10+10-15
= 305
Аналогично
вычисляется размер клиентской области по вертикали: в ней учитывается базовая
высота блока div в 200 пикселей и
по 10 пикселей отступы padding, имеем:
clientHeight = 200+10+10 =
220
Обратите
внимание, что эти свойства доступны только для чтения, изменять их, например,
вот так:
не получится. Если
нам нужно изменить высоту элемента, то следует использовать соответствующие
свойства из style:
elem.style.height = 100+"px";
с обязательным
указанием единиц измерения (в данном случае – пиксели). Аналогично через
свойство width
меняется
ширина блока.
Следующие
метрики:
-
elem.scrollTop – высота
прокрутки содержимого блока;
-
elem.scrollLeft – величина
прокрутки содержимого в левую сторону блока;
-
elem.scrollWidth – ширина
содержимого с учетом прокрутки;
-
elem.scrollHeight – высота
содержимого с учетом прокрутки.
Все эти свойства
для наглядности изображены на этом рисунке.
Чтобы увидеть значения
изменения этих величин, преобразуем немного наш документ, поместим внутрь
нашего блока еще один блок
<div style="width: 500px">
и будем
отображать величины каждую секунду:
let elem = document.querySelector("div.message");
setInterval(function() {
console.log(elem.scrollTop, elem.scrollLeft, elem.scrollWidth, elem.scrollHeight);
}, 1000);
Как видите, при
прокрутке содержимого, у нас меняются значения scrollLeft и scrollTop. Остальные два
параметра остаются без изменений, как это и должно быть.
Величины scrollLeft и scrollTop можно менять и
осуществлять программный скроллинг содержимого. Например, если мы пропишем вот
такой код:
то при
обновлении документа увидим смещение содержимого по вертикали. Аналогично и для
мы его здесь ему
присвоили значение через оператор +=, то есть, к предыдущему значению добавили
еще 20 пикселей. Так тоже можно делать.
А вот свойства scrollWidth
и scrollHeight менять уже
нельзя, они доступны только для чтения.
Следующие свойства:
-
elem.offsetLeft –
содержит смещение блока от левого края;
-
elem.offsetTop – содержит смещение
блока от верхнего края.
Данные свойства
обычно отсчитывают смещения относительно окна браузера (элемента body), но в общем
случае относительно своего предка, указанного в свойстве offsetParent:
console.log(elem.offsetParent);
В данном случае
увидим элемент body. Визуально их можно представить так:
Выведем их в консоль
console.log(elem.offsetLeft, elem.offsetTop);
и убедимся, что
они принимают заданные в CSS-стилях значения. На этом же
рисунке отмечены еще два свойства:
-
elem.clientLeft – смещение
слева внутренней части области от края элемента (в данном случае блока div);
-
elem.clientTop – смещение
сверху внутренней части области от края элемента (в данном случае блока div).
В нашем примере
эти свойства будут равны 20 пикселам – толщине рамки, указанной в CSS-свойстве border. Выведем их в
консоль:
console.log(elem.clientLeft, elem.clientTop);
и видим значения
20.
Наконец,
последние две метрики:
-
elem.offsetWidth – ширина
элемента с учетом всех отступов;
-
elem.offsetHeight – высота
элемента с учетом всех отступов.
То есть, в нашем
случае – это будут полные размеры блока div. Выведем их в
консоль:
console.log(elem.offsetWidth, elem.offsetHeight);
и видим значения
360 на 260 пикселей.
Вот мы с вами
рассмотрели метрики DOM-элементов и теперь вы знаете как их использовать.
Однако, может возникнуть вопрос: можно ли брать эти же значения непосредственно
из стилей объекта, которые можно получить с помощью функции:
let styles = getComputedStyle(elem, [pseudo]);
о которой мы
говорили на предыдущем занятии? В действительности нет, так как реальные
значения элементов в окне браузера могут отличаться от значений свойств,
указанных в CSS. Кроме того, в CSS свойства могут
быть вообще не указаны, например, высота элемента – она часто определяется
реальным содержимым. Или же, ширина заданная как auto:
width: auto;
не может быть
переведена в пиксели функцией getComputedStyle: мы там так auto и увидим.
Поэтому, если вам нужны актуальные значения метрик элемента, то следует
использовать свойства, рассмотренные на этом занятии.