Выполняя обход цепочки, образуемой ссылками
<b>offsetParent</b>
, и накапливая смещения, эта функция вычисляет координаты указанного элемента относительно начала документа. (Напомню, что метод
<b>getBoundingClientRect(),</b>
напротив, возвращает координаты относительно начала видимой области.) Однако на этом тему позиционирования элементов нельзя считать исчерпанной - функция
<b>getElementPosition()</b>
не всегда вычисляет правильные значения, и ниже будет показано, как исправить эту ошибку.
В дополнение к множеству свойств
<b>offset</b>
все элементы документа определяют еще две группы свойств; имена свойств в первой группе начинаются с приставки
<b>client</b>
, а во второй группе - с приставки
<b>scroll</b>
. То есть каждый HTML-элемент имеет все свойства, перечисленные ниже:
<b>offsetWidth</b>
<b>offsetHeight</b>
<b>offsetLeft</b>
<b>offsetTop</b>
<b>offsetParent</b>
<b>clientWidth</b>
<b>clientHeight</b>
<b>clientLeft</b>
<b>clientTop</b>
<b>scrollWidth</b>
<b>scrollHeight</b>
<b>scrollLeft</b>
<b>scrollTop</b>
Чтобы понять разницу между группами свойств
<b>client</b>
и
<b>scroll</b>
, необходимо уяснить, что объем содержимого HTML-элемента может не умещаться в прямоугольную область, выделенную для этого содержимого, и поэтому отдельные элементы могут иметь собственные полосы прокрутки (смотрите описание CSS-атрибута
<b>overflow</b>
в разделе 16.2.6). Область отображения содержимого - это видимая область, подобная видимой области в окне броузера, и когда содержимое элемента не умещается в видимой области, необходимо принимать в учет позиции полос прокрутки элемента.
Свойства
<b>clientWidth</b>
и
<b>clientHeight</b>
похожи на свойства
<b>offsetWidth</b>
и
<b>offsetHeight</b>
, за исключением того, что они включают только область содержимого и отступы и не включают размер рамки. Кроме того, если броузер добавляет между рамкой и отступами полосы прокрутки, то свойства
<b>clientWidth</b>
и
<b>clientHeight</b>
не включают ширину полос прокрутки в возвращаемые значения. Обратите внимание, что для строчных элементов, таких как
<b><i>, <code></b>
и
<b><span></b>
, свойства
<b>clientWidth</b>
и
<b>clientHeight</b>
всегда возвращают 0.
Свойства
<b>clientWidth</b>
и
<b>clientHeight</b>
использовались в методе
<b>getViewportSize()</b>
из примера 15.9. В том случае, когда эти свойства применяются к корневому элементу документа (или телу элемента в режиме совместимости), они возвращают те же значения, что и свойства
<b>innerWidth</b>
и
<b>innerHeight</b>
окна.
Свойства
<b>clientLeft</b>
и
<b>clientTop</b>
не имеют большой практической ценности: они возвращают расстояние по горизонтали и вертикали между внешней границей отступов элемента и внешней границей его рамки. Обычно эти значения просто определяют ширину левой и верхней рамки. Однако если элемент имеет полосы прокрутки и если броузер помещает эти полосы прокрутки вдоль левого или верхнего края (что весьма необычно), значения свойств
<b>clientLeft</b>
и
<b>clientTop</b>
также будут включать ширину полос прокрутки. Для строчных элементов свойства
<b>clientLeft</b>
и
<b>clientTop</b>
всегда возвращают 0.
Свойства
<b>scrollWidth</b>
и
<b>scrollHeight</b>
определяют размер области содержимого элемента, плюс его отступы, плюс ширину и высоту области содержимого, выходящую за видимую область. Когда содержимое целиком умещается в видимой области, значения этих свойств совпадают со значениями свойств
<b>clientWidth</b>
и
<b>clientHeight</b>
. В противном случае они включают ширину и высоту области содержимого, выходящую за видимую область, и возвращают значения, превосходящие значения свойств
<b>clientWidth</b>
и
<b>clientHeight</b>
.
Наконец, свойства
<b>scrollLeft</b>
и
<b>scrollTop</b>
определяют позиции полос прокрутки элемента. Мы использовали эти свойства корневого элемента документа в методе
<b>getScrollOffsets()</b>
(пример 15.8), но они также присутствуют в любом другом элементе. Обратите внимание, что свойства
<b>scrollLeft</b>
и
<b>scrollTop</b>
доступны для записи и им можно присваивать значения, чтобы прокрутить содержимое элемента. (HTML-элементы не имеют метода
<b>scrollTo(),</b>
как объект
<b>Window</b>
.)
Когда документ содержит прокручиваемые элементы, содержимое которых не умещается в видимой области, объявленный выше метод
<b>getElementPosition()</b>
дает некорректные результаты из-за того, что он не учитывает позиции полос прокрутки. Ниже приводится исправленная версия, которая вычитает позиции полос прокрутки из накопленных смещений, т. е. преобразует координаты относительно начала документа в координаты относительно видимой области:
<b>function getElementPos(elt) { var х = 0, у = 0;</b>