И еще раз про анимированные ссылки

Вячеслав Гринин, February 20, 2009

Не так давно наш веб-дизайнер в своей статье Трюк со ссылкой – показываем картинку рассказал нам о том, как сделать красивую анимированную ссылку. Однако предложенное решение обладает одним недостатком – клик на подобной ссылке не срабатывает в IE. Ну, не воспринимает он SPAN вложенный в ссылку, так как нам хотелось бы. Клик на такой ссылке не срабатывает, даже курсор мыши остается обычной “умолчательной стрелкой”.

Ну, допустим, с курсором справиться проще всего, задав SPAN’у стиль cursor:pointer. Остается заставить IE правильно отрабатывать клики на подобных конструкциях.

Решение оказалось достаточно простым, правда чтобы сделать это нужно быть немного программистом. Для этого ссылка вместо конструкции <a href=”portfolio.html”>, приобретает чуть более сложный вид: <a href=”javascript:void(0)” onclick=”window.location=’portfolio.html'”>.

Как видим, здесь все очень просто. Событие onclick браузер отрабатывает нормально, а мы этим и воспользовались, по щелчку мыши свойству window.location присваивается значение ‘portfolio.html’, то есть как раз та самая ссылка, переход на которую нужно обеспечить. Атрибут href содержит теперь значение javascript:void(0), по сути, это пустой оператор, который в данном случае блокирует стандартное поведение браузера при переходе по ссылке.

А вот и весь текст этого трюка:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<title>Анимированная ссылка</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />
<style type=”text/css”>
img {
border: 0px;
}

a span {
display: none;
}

a:hover #port1 {
display: inline;
position: absolute;
margin-left: -1px;
margin-top: -1px;
}

#port1 {
cursor: pointer;
}
</style>
</head>
<body>
<div id=”img1″><a href=”javascript:void(0)” onclick=”window.location=’portfolio.html'”><span id=”port1″><img src=”portfolio_big.png” alt=”” /></span><img src=”portfolio.png” alt=”” /></a></div>
</body>
</html>

AJAX. 2 – Подробнее об XMLHttpRequest

Вячеслав Гринин, January 30, 2009

В статье AJAX. 1 – Что это такое? я рассказал про то, в каких случаях можно использовать AJAX и привел тестовый пример использования AJAX в веб-разработке. Теперь я хочу немного углубиться в подробности работы с объектом XMLHttpRequest и расскажу про его основные свойства и методы. Итак…

Методы объекта XMLHttpRequest:

  • abort() – Прекращает исполнение текущего запроса. При этом объект XMLHttpRequest возвращет readyState=4 и status=0.
  • getAllResponseHeaders()– Возвращает HTTP-заголовки ответа в
    виде строки. Эта строка может выглядеть, например, так:

    Date: Fri, 30 Jan 2009 13:57:48 GMT Server: Apache/2.2.4 (Win32) mod_ssl/2.2.4 OpenSSL/0.9.8d PHP/5.2.4 X-Powered-By: PHP/5.2.4 Content-Length: 91 Keep-Alive: timeout=5, max=98 Connection: Keep-Alive Content-Type: text/xml
  • getResponseHeader(“header-name”) – Возвращает заголовок “header-name” ответа. Для случая getResponseHeader(‘Content-Type’) она вернет
    text/xml
  • open(“method”, “URL”, async-flag, “user-name”, “password”) – Инициализирует параметры запроса. Если в качестве “method” используется строка “POST”, то метод send(‘content’) в качестве параметра должен принимать данные, передаваемые методом POST. Если же “method”=”GET”, то параметры обработчику передаются в параметре “URL” метода open()
  • send(“content”) – Выполняет HTTP-запрос.
  • setRequestHeader(“header-name”, “header-value”) – Добавляет в запрос HTTP-заголовок.

Свойства объекта XMLHttpRequest::

  • onreadystatechange – Установка функции обратного вызова, которая будет обслуживать изменение состояния запроса.
  • readyState – Возвращает состояние запроса
    0 – не инициализирован
    1 – идет отправка запроса
    2 – запрос отправлен
    3 – идет обмен
    4 – обмен завершен
  • responseText – Содержит ответ сервера в виде строки
  • responseXML – Содержит ответ сервера в виде XML-документа
  • status – Возвращает код состояния запроса
  • statusText – Возвращает сообщение о состоянии запроса

Здесь расположен архив с исходными кодами тестового примера, который демонстрирует использование всех вышеприведенных свойств и методов.

AJAX. 1 – Что это такое?

Вячеслав Гринин, January 23, 2009

Эта статья открывает целый цикл статей, посвященных загадочной и очень увлекательной теме AJAX. Я постараюсь донести до вас, дорогие читатели, что же это за зверь такой, и как это можно использовать в веб-разработке для создания веб-приложений, написанных на ASP.NET, PHP, а может и каких других языках и платформах.
Когда некий узкий круг лиц узнал про AJAX и начал его использовать в своих приложениях, вокруг него поднялась такая шумиха, что казалось, будто об этом говорят все вокруг, не исключая бабушек на лавочке у подъезда. Я сам впервые услышал этот термин, когда ехал на трамвае в универ. Рядом со мной стояла парочка, и молодой, но уже бородатый парнишка с всклокоченными волосами рассказывал своей подружке об аяксе. Использовал он при этом такие высокопарные выражения, что я бы не удивился, если б узнал, что он втихомолку по вечерам строчит нервною рукою в тетрадь с пожелтевшими страницами оды или, как минимум, сонеты. В общем, «погиб поэт, невольник чести… стал программистом он, увы».
Но лирическое вступление слишком затянулось.
Так что же такое AJAX? Расшифровывается это слово, как Asynchronous JavaScript and XML, то есть «Асинхронный JavaScript и XML». Отсюда можно понять, что для успешного использования этой технологии, никуда не деться, нужно хоть немного знать JavaScript и уметь на нем писать. А вот XML позволительно и не знать, ибо можно обойтись и без него.
Так вот AJAX – это технология, позволяющая веб-страницам на клиентской стороне, то есть прямиком из браузера пользователя, в фоновом режиме обращаться к серверу и получать от него некоторые необходимые данные. А это значит, что для обновления части страницы браузеру не нужно перезагружать всю страницу целиком. И обращение это может происходить незаметно для пользователя, не заставляя его дожидаться перезагрузки страницы. При грамотном применении эта технология позволит вам, как программисту, сэкономить время пользователя и его трафик. А мы знаем, что пользователи – жутко нервные и обидчивые создания. Не дай бог заставить юзера ждать обновления страницы слишком долго, и он тут же переметнется к вашим конкурентам. Причем это совсем не шутки.
Чтобы увидеть один из аспектов применения технологии AJAX, зайдите на http://www.yandex.ru/ или на http://www.google.ru/ , введите в строке поиска что-нибудь, например букву «п», и тут же под полем ввода откроется список наиболее популярных поисковых запросов, начинающихся с буквы «п». Откуда взялся этот список? В тот момент, когда вы отпустили клавишу «п», ваш веб-браузер в фоновом режиме отправил запрос серверу вот такого вида: http://suggest.yandex.ru/suggest-ya.cgi?ct=text/html&part=%D0%BF , а в ответ очень быстро получил вот такую строку:
suggest.apply([“п”, [“погода”, “переводчик”, “поздравления с днем рождения”, “почта”, “переводчик онлайн”, “приколы”, “прогноз погоды”, “погода в москве”, “поздравления с новым годом”, “поздравления”], []], []) , где в квадратных скобочках можно увидеть все эти наиболее популярные поисковые запросы. JavaScript в браузере быстренько добавил к этому списочку HTML-разметку и отобразил ее на вашей странице в абсолютно позиционированном DIV-е.
Сайт http://maps.google.com/ вообще весь целиком и полностью построен на AJAX. Именно поэтому, когда вы двигаете мышью карту, ваша страница не перезагружается.
Посмотрим теперь из чего состоит AJAX. В его основе лежат 4 базовые вещи:

  1. JavaScript. Если вы профессионал в веб-разработке, то без него здесь никуда. Именно на нем реализована функциональность на стороне клиента. И даже если вы используете готовые AJAX-решения, вам не избежать того, что придется еще кое-что писать ручками.
  2. Объектная модель документа(DOM). Знание этой модели нужно, чтобы отобразить на странице в браузере ту информацию, что пришла в ответ на асинхронный запрос серверу от браузера.
  3. Объект XMLHttpRequest. Именно он позволяет из JavaScript организовать асинхронный доступ к серверу. Без этого объекта AJAX – мертв!
  4. Ну и, наконец, любая из серверных технологий, будь то PHP, ASP, ASP.NET, JSP, Ruby on Rails и т.д. и т.п. Вы можете использовать здесь то, что вам больше по душе.

Как это работает?

  1. Страница (конечно же, посредством JavaScript) в браузере пользователя, по какому-либо событию (нажатие клавиши, таймер) с помощью объекта XMLHttpRequest подает запрос серверу, обращаясь к некоему серверному обработчику, передавая ему некоторые параметры, например, значения, введенные пользователем в поле «Имя пользователя» на форме регистрации.
  2. Обработчик принимает этот запрос и обрабатывает его. Чаще всего, это некий поиск базе данных, и формирование результатов в виде структуры данных, а может и в виде готовой HTML-разметки. Собственно, в результате выполнения запроса на выходе получается некая строка, в которой упакованы данные. По завершению обработки данных, обработчик выдает эти данные обратно браузеру пользователя. Упаковка чаще всего производится либо с использованием JSON, либо XML.
  3. Браузер принимает эту строку, распаковывает ее, и использует для отображения на загруженной странице. В нашем случае, рядом с полем «Имя пользователя» появится надпись «имя свободно» или «имя занято». Кстати, в качестве первого примера использования AJAX мы напишем собственное веб-приложение, которое будет отвечать на вопрос, занято или свободно выбранное имя пользователя.

Ну что ж, а теперь попробуем создать свое первое веб-приложение, использующее технологию AJAX. Для этого вам понадобится локальный веб-сервер с поддержкой PHP, и если вы не знаете, откуда его взять, то зайдите сюда , и уже спустя несколько минут у вас будет свой собственный локальный веб-сервер.
А теперь создадим наше первое AJAX-приложение.

  1. Создайте страницу регистрации пользователя index.html. На ней расположены поле ввода имени пользователя, кнопка «Проверить имя» и DIV, в котором будут выводиться результаты проверки.
    <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>
    <html xmlns=”http://www.w3.org/1999/xhtml“>
    <head>
    <title> Простой пример на AJAX</title>
    <script type=”text/javascript” src=”ajax.js”></script>
    </head>
    <body>
    Имя пользователя: <input type=”text” id=”username”><input type=”button” onclick=”checkName()” value=”проверить имя”>
    <div id=”umess”>…</div>
    </body>
    </html>
  2. Создайте файл ajax.js, содержащий в себе клиентский скрипт на JavaScript. Его функциональность подробно прокомментирована в самом тексте.
    // Это и есть объект XmlHttpRequest
    var xmlHttp=createXmlHttpRequest();
    // синоним для getElementById
    function gebi(id) {
    return document.getElementById(id);
    }
    // функция кроссбраузерно создает объект XmlHttpRequest
    function createXmlHttpRequest() {
    var xmlHttp;
    try {
    if(window.ActiveXObject) // для IE
    xmlHttp=new ActiveXObject(“Microsoft.XMLHTTP”);
    else // для остальных браузеров
    xmlHttp=new XMLHttpRequest();
    }
    catch(e) {
    xmlHttp=false;
    alert(“Объект XMLHttpRequest не создан!”);
    }
    return xmlHttp;
    }
    // вызывается по клику на кнопке “Проверить имя”
    function checkName() {
    // проверяем, завершил ли объект XMLHttpRequest прошлый вызов
    if(xmlHttp.readyState==4 || xmlHttp.readyState==0) {
    // получаем строку, введенную пользователем
    usname=encodeURIComponent(gebi(“username”).value);
    // говорим объекту XMLHttpRequest куда и как он должен обратиться
    xmlHttp.open(“GET”, “handler.php?username=”+usname, true);
    // говорим объекту XMLHttpRequest какую функцию он должен вызывать при изменении своего статуса
    xmlHttp.onreadystatechange=handleResponse;
    // посылаем асинхронный запрос серверу
    xmlHttp.send(null);
    }
    }
    // вызывается при изменении статуса объекта XMLHttpRequest
    function handleResponse() {
    // проверяем по readyState завершена ли транзакция
    if(xmlHttp.readyState==4) {
    // проверяем по status успешность транзакции
    if(xmlHttp.status==200) {
    // если все порядке, читаем возвращенный XML документ
    xmlResponse=xmlHttp.responseXML;
    xmlElement=xmlResponse.documentElement;
    res=xmlElement.firstChild.data;
    var umess=gebi(“umess”);
    // в соответствии с возвращенным результатом, выводим на страницу нужное сообщение
    if(res==’true’)
    umess.innerHTML=”Имя свободно”;
    else
    umess.innerHTML=”Имя занято”;
    }
    else
    alert(“Ошибка при обращении к серверу. “)+xmlHttp.statusText;
    }
    }
  3. Создайте файл handler.php. Именно с этим серверным скриптом будет взаимодействовать страница в браузере пользователя. По хорошему, здесь должная быть настоящая проверка на существование в базе MySQL пользователя с введенным именем. В демонстрационных целях здесь реализована фиктивная проверка по первой букве имени.
    <?php
    // возвращать будем XML
    header("Content-Type: text/xml");
    // создаем заголовок XML и элемент response
    echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
    echo ('<response>');
    // из GET-строки получаем имя пользователя
    $username=$_GET['username'];
    // Фиктивная проверка на существование такого пользователя БД
    if(substr($username,0,1)=='a')
    echo('true');
    else
    echo('false');
    // закрываем элемент response
    echo('</response>');
    ?>
  4. А теперь введите в браузере http://localhost/index.html и протестируйте ваше приложение.

Здесь расположен архив со всеми необходимыми файлами. Просто распакуйте его в корневую директорию вашего веб-сервера и выполните в браузере http://localhost/index.html.

Позиционирование элементов на JavaScript.

Вячеслав Гринин, January 13, 2009

Сегодня я расскажу о том, как правильно позиционировать элементы страницы друг относительно друга.
Зачем это нужно? Например, чтобы создать красивый выпадающий список. Сегодня мы зададимся целью создать некий пользовательский комбо-бокс. И стандартные возможности HTML нас не устраивают. То есть, мы хотим получить нечто более сложное, чем вот это.

<select>
<option>Item 1</option>
<option>Item 2</option>
<option>Item 3</option>
</select>

А получить хотели бы нечто вроде этого:

<input type=’text’ style=’width: 100px;’ id=’textbox1’/>
<div style=’border: 1px solid #072; background-color: #59E75D; width: 100px;’ id=’list1′>
<ul>
<li><a href=’#’>Item 1</a></li>
<li><a href=’#’>Item 2</a></li>
<li><a href=’#’>Item 3</a></li>
</ul>

То есть мы хотим отпозиционировать DIV так, чтобы он прикрепился к одному из углов другого элемента на странице. 

Вообще, для позиционирования элемента в координатах, заданных своими величинами (X, Y) подойдет вот такая функция:

function setPosXY(obj,x,y) {
  if(obj) {
    obj.style.position=’absolute’;
    obj.style.left=x+’px’;
    obj.style.top=y+’px’;
  }
}

Эта функция проста и особых пояснений не требует. Осталось только правильно определить координаты того элемента(E1), относительно которого хочется спозиционировать заданный элемент(E2), да еще и в соответствии с тем, к какому именно углу E1 будет пристыкован E2.  Углов у любого прямоугольника всего 4. Соответственно и вариантов позиционирования будет 4.

Вот они:

Функция getBounds определяет параметры left, top, width, height объекта. Цикл while нужен для того, чтобы определить абсолютные координаты объекта относительно контейнера <body>.

function getBounds(obj){
  var w=obj.offsetWidth;
  var h=obj.offsetHeight;
  var x=y=0;
  while(obj){
    x+=obj.offsetLeft;
    y+=obj.offsetTop;
    obj=obj.offsetParent;
  }
  return{x:x,y:y,width:w,height:h};
}

 Ну а вот и сама функция позиционирования:

function setPos(anc_id,obj_id,corner,margin){
// anc_id – id элемента, относительно которого будем позиционировать
// obj_id – id элемента, который будем позиционировать
// corner – номер угла (смотрите Рис.1)
// margin – отступ между элементами, чтобы они не “слипались”
  if(!corner)corner=1;
  var obj=document.getElementById(obj_id);
  var anc=document.getElementById(anc_id);
  if(!obj||!anc) return;
  var b=getBounds(anc);
  var c=getBounds(obj);
  var xs=0,ys=0; // координаты left и top родительского элемента (на случай, если кто-то из родителей абсолютно позиционирован)
  var par=obj;
  for(var i=0;i<50;i++){
    par=par.parentNode;
    if(!par||par.tagName==’BODY’) break;
    var s=getCurrentStyle(par);
    if(par.tagName==’DIV’&&s&&s.position==’absolute’){
      var p=getBounds(par);
      xs+=p.x
      ys+=p.y;
      break;
    }
  }
  var xc=0,yc=0; // Дополнительные отступы, учитывающие номер угла
  switch(corner){
    case 2:
      yc=-c.height-b.height;
      break;
    case 3:
      yc=-c.height-b.height;
      xc=-c.width;
      break;
    case 4:
      xc=-c.width+b.width;
      break;
  }
  var xm=0;ym=0; // Дополнительные отступы, учитывающие параметр margin
  if(margin){
    xm=margin.x;
    ym=margin.y;
  }
  SetPosXY(obj,b.x-xs+xc+xm,b.y+b.height-ys+yc+ym);
}

И чуть не забыл, функция getCurrentStyle нужна, чтобы кроссбаузерно определить текущий стиль элемента:

function getCurrentStyle(el){
  if(!el) return null;
  var s=el.currentStyle; 
  if(!s) s=document.defaultView.getComputedStyle(el,null); // Для FireFox
  return s;
}

А вот здесь находится весь скрипт.  Пользуйтесь на здоровье.
Ну а вызов этой функции может выглядеть так:

setPos(‘textbox1′,’list1’,1,{‘x’:2, ‘y’:2});

————————————-

Поиск по блогу:
Подписаться:
Популярные:
Облако тегов:
Разное:
Счетчик: