Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

CSS и DHTML для сайтостроительства. Выпуск 3 - Движение


Выпуск 3

Здравствуйте, дорогие читатели! В этом выпуске мы рассмотрим, как можно управлять расположением элементов на страничке. Разговор, как и в предыдущих выпусках, идёт в контексте совместимости скриптов в разных браузерах.

Движение

Как правило проблемы совместимости не возникают при назначении некому CSS-P элементу нового расположения. Например, для перемещения элемента myelement в точку (100, 50) вы просто устанавливаете соответсвующие значения у свойств left и top: myelement.left = 100
myelement.top = 50
Не забывайте, что myelement это указатель, определённый, например, таким образом: function init() {
    if (ns4) myelement = document.myelementDiv
    if (ie4) myelement = myelementDiv.style
}

Как уже было сказано выше, назначение нового местоположения происходит гладко во обоих браузерах. Проблемы возникают с определением текущих координат элемента. Это касается в первую очередь IE, который представляет все координаты с px на конце (см. пример в предыдущем выпуске). Дабы избавиться от этих буковок, необходимо значение координат перевести в целочисленное значение. Иными словами, вместо myelement.left, вы должны написать parseInt(myelement.left). Например, если вы хотите информировать пользователя о координатах элемента, вы можете сделать это так: alert(parseInt(myelement.left) + ", " + parseInt(myelement.top))

Добавление новых свойств

"Всё время теперь придётся писать parseInt()?" - спросите вы. Как тоскливоооооо! К счастью, существует метод оптимизации этой проблемы. Этот метод называется добавление новых свойств к указателям, или объектам, как я буду называть их далее по тексту. Иными словами, можно сохранять текущее местоположение элемента в свойствах, определённых нами же. Для создания этих свойств, нужно просто присвоить им некие значения. Для начала, мы сохраним текущие координаты элемента так: myelement.xpos = parseInt(myelement.left)
myelement.ypos = parseInt(myelement.top)
И теперь, каждый раз, когда вам понадобятся значения свойств left и top, вы обращаетесь к myelement.xpos и myelement.ypos соответсвенно. Например, новая версия alert() будет выглядеть так: alert(myelement.xpos + "," + myelement.ypos)

Так как насчёт определения текущей координаты?

Если вы хотите изменить текущие координаты элемента, ПРЕЖДЕ ВСЕГО вы должны изменить значения переменных xpos и ypos.А ЗАТЕМ, вы можете установить значения свойств left и top равными соответсвенно xpos и ypos. Например, function move() {
    myelement.xpos = 200
    myelement.ypos = -40
    myelement.left = myelement.xpos
    myelement.top = myelement.ypos
}
Значения переменных xpos и ypos должны быть всегда синхронизированы со значениями свойств left и top. Это гарантирует равенство, например, myelement.xpos и myelement.left.

Рассмотрим простой пример на движение.

Скрипт: <SCRIPT language=JavaScript>
<!--

ns4 = (document.layers)? true:false
ie4 = (document.all)? true:false

function init() {
    if (ns4) block = document.blockDiv
    if (ie4) block = blockDiv.style
    block.xpos = parseInt(block.left)
    block.ypos = parseInt(block.top)
}

function move1() {
    block.xpos = 100
    block.ypos = 80
    block.left = block.xpos
    block.top = block.ypos
}

function move2() {
    block.xpos = 200
    block.ypos = 160
    block.left = block.xpos
    block.top = block.ypos
}

function move3() {
    block.xpos = 300
    block.ypos = 240
    block.left = block.xpos
    block.top = block.ypos
}


//-->
</SCRIPT>
HTML: <BODY bgColor=#ffffff onload=init() />
Move the block to:
<A href="javascript:move1()">(100,80)</A> -
<A href="javascript:move2()">(200,160)</A> -
<A href="javascript:move3()">(300,240)</A><br>
<A href="javascript:alert(block.xpos + ', ' + block.ypos)">check location</A>
<DIV id=blockDiv style="LEFT: 50px; WIDTH: 30px; CLIP: rect(0px 30px 30px 0px); xPOSITION: absolute; TOP: 100px; HEIGHT: 30px; BACKGROUND-COLOR: red; layer-background-color: red"></DIV>
</BODY>
Результирующая страница будет такая: Move the block to: (100,80) - (200,160) - (300,240)
check location

где красный квадрат перемещается так, что его левый верхний угол имеет координату (100,80), (200,160), (300,240) если пользователь нажимает одноимённый линк, и сообщение с информацией о местоположении красного квадрата появляется при нажатии на линк check location. Всё очень просто, не так ли?

Идея дополнительных свойств будет использоваться и дальше. Хотя дополнительные свойства и могут показаться странными, вы обнаружите, что они помогают оптимизировать код.

Вы можете удивиться, почему я использую xpos и ypos вместо x и y. Это имеет вполне серьёзное обоснование. Мало кто знает, что Netscape уже включил эти свойства (x и y) в свою имплементацию CSS-P. Если вы их будете использовать в примерах выше, они будут содержать значения целого типа. "Ну и что?" скажете вы. В примерах этого выпуска ничего. Но могут встретиться примеры, в которых необходимо хранить не целочисленные значения и это будет невозможно из-за использования x и y.

Общая функция движения

Только что мы рассмотрели пример, где для каждого перемещения была создана отдельная функция. Однако, если вы хотите создать движение нескольких слоёв в нескольких направлениях, написание скриптов для такого разнообразного множества движений - задача воистину трудная. Единственное, что мы можем сделать, - создать некую общую функцию, которая заботится о разнотипных движениях слоёв.

Функция moveTo()

Эта функция принимает в качестве параметра слой/объект и перемещает его непосредственно в другое место: function moveTo(obj,x,y) {
    obj.xpos = x
    obj.left = obj.xpos
    obj.ypos = y
    obj.top = obj.ypos
}
Используется эта функция очень просто: всё что вы должны передать в неё - слой/объект и его новые координаты x и y. Наример, если инициализация слоя происходит так: if (ns4) mysquare = document.mysquareDiv
if (ie4) mysquare = mysquareDiv.style
mysquare.xpos = parseInt(mysquare.left)
mysquare.ypos = parseInt(mysquare.top)
то для перемещения квадрата в точку (50,100) достаточно написать: moveTo(mysquare,50,100)

Функция moveBy()

Эта функция имеет те же самые принципы работы, что и предыдущая, за исключением того, что слой/объект перемещается не в в точку (x,y), но смещается на (x,y) пикселов, относительно текущей координаты слоя: function moveBy(obj,x,y) {
    obj.xpos += x
    obj.left = obj.xpos
    obj.ypos += y
    obj.top = obj.ypos
}
Для смещения квадрата на 5 пикселов вправо и на 10 пикселов вверх нужно написать: moveBy(mysquare,5,-10)

Полный пример, который использует функции moveTo() и moveBy():

Скрипт: <SCRIPT language=JavaScript>
<!--

ns4 = (document.layers)? true:false
ie4 = (document.all)? true:false

function init() {
    if (ns4) block = document.blockDiv
    if (ie4) block = blockDiv.style
    block.xpos = parseInt(block.left)
    block.ypos = parseInt(block.top)
}

function moveTo(obj,x,y) {
    obj.xpos = x
    obj.left = obj.xpos
    obj.ypos = y
    obj.top = obj.ypos
}

function moveBy(obj,x,y) {
    obj.xpos += x
    obj.left = obj.xpos
    obj.ypos += y
    obj.top = obj.ypos
}

function showObject(obj) {
    if (ns4) obj.visibility = "show"
    else if (ie4) obj.visibility = "visible"
}

function hideObject(obj) {
    if (ns4) obj.visibility = "hide"
    else if (ie4) obj.visibility = "hidden"
}

//-->
</SCRIPT>
HTML: <BODY bgColor=#ffffff onload=init()>
Check Values:
    <A href="javascript:alert('X: ' + block.xpos)">xpos</A>,
    <A href="javascript:alert('Y: ' + block.ypos)">ypos</A> <BR>
Visibility:
    <A href="javascript:showObject(block)">show</A>,
    <A href="javascript:hideObject(block)">hide</A> <BR>
MoveTo:
    <A href="javascript:moveTo(block,100,100)">(100,100)</A>,
    <A href="javascript:moveTo(block,200,160)">(200,160)</A>,
    <A href="javascript:moveTo(block,300,240)">(300,240)</A> <BR>
MoveBy:
    <A href="javascript:moveBy(block,10,0)">(10,0)</A>,
    <A href="javascript:moveBy(block,-10,0)">(-10,0)</A>,
    <A href="javascript:moveBy(block,0,10)">(0,10)</A>,
    <A href="javascript:moveBy(block,0,-10)">(0,-10)</A>
<DIV id=blockDiv style="LEFT: 50px; WIDTH: 30px; CLIP: rect(0px 30px 30px 0px); xPOSITION: absolute; TOP: 100px; HEIGHT: 30px; BACKGROUND-COLOR: red; layer-background-color: red"></DIV>
</BODY>
Результат: Check Values: xpos, ypos
Visibility: show, hide
MoveTo: (100,80), (200,160), (300,240)
MoveBy: (10,0), (-10,0), (0,10), (0,-10)


В следующем выпуске речь пойдёт об анимированом движении, в том числе и по диагонали.


Дорогие читатели! Если у вас возникают вопросы по тексту рассылки, я с удовольствием на них отвечу. Мой почтовый адрес идёт последней строкой в данном выпуске (at означает @). Кроме того, присылайте мне интересующие вас темы, которые я могла бы осветить в рассылке, делитесь опытом или просто комментируйте. Я также буду рада и благодарна вам, если вы проголосуете за этот выпуск. Форма голосования находится внизу выпуска.

Всего доброго,
Наталия Македа
natalia.macheda at gmail.com


В избранное