И еще раз про анимированные ссылки
Не так давно наш веб-дизайнер в своей статье Трюк со ссылкой – показываем картинку рассказал нам о том, как сделать красивую анимированную ссылку. Однако предложенное решение обладает одним недостатком – клик на подобной ссылке не срабатывает в 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), по сути, это пустой оператор, который в данном случае блокирует стандартное поведение браузера при переходе по ссылке.
А вот и весь текст этого трюка:
<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
В статье 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 – Что это такое?
Эта статья открывает целый цикл статей, посвященных загадочной и очень увлекательной теме 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 базовые вещи:
- JavaScript. Если вы профессионал в веб-разработке, то без него здесь никуда. Именно на нем реализована функциональность на стороне клиента. И даже если вы используете готовые AJAX-решения, вам не избежать того, что придется еще кое-что писать ручками.
- Объектная модель документа(DOM). Знание этой модели нужно, чтобы отобразить на странице в браузере ту информацию, что пришла в ответ на асинхронный запрос серверу от браузера.
- Объект XMLHttpRequest. Именно он позволяет из JavaScript организовать асинхронный доступ к серверу. Без этого объекта AJAX – мертв!
- Ну и, наконец, любая из серверных технологий, будь то PHP, ASP, ASP.NET, JSP, Ruby on Rails и т.д. и т.п. Вы можете использовать здесь то, что вам больше по душе.
Как это работает?
- Страница (конечно же, посредством JavaScript) в браузере пользователя, по какому-либо событию (нажатие клавиши, таймер) с помощью объекта XMLHttpRequest подает запрос серверу, обращаясь к некоему серверному обработчику, передавая ему некоторые параметры, например, значения, введенные пользователем в поле «Имя пользователя» на форме регистрации.
- Обработчик принимает этот запрос и обрабатывает его. Чаще всего, это некий поиск базе данных, и формирование результатов в виде структуры данных, а может и в виде готовой HTML-разметки. Собственно, в результате выполнения запроса на выходе получается некая строка, в которой упакованы данные. По завершению обработки данных, обработчик выдает эти данные обратно браузеру пользователя. Упаковка чаще всего производится либо с использованием JSON, либо XML.
- Браузер принимает эту строку, распаковывает ее, и использует для отображения на загруженной странице. В нашем случае, рядом с полем «Имя пользователя» появится надпись «имя свободно» или «имя занято». Кстати, в качестве первого примера использования AJAX мы напишем собственное веб-приложение, которое будет отвечать на вопрос, занято или свободно выбранное имя пользователя.
Ну что ж, а теперь попробуем создать свое первое веб-приложение, использующее технологию AJAX. Для этого вам понадобится локальный веб-сервер с поддержкой PHP, и если вы не знаете, откуда его взять, то зайдите сюда , и уже спустя несколько минут у вас будет свой собственный локальный веб-сервер.
А теперь создадим наше первое AJAX-приложение.
- Создайте страницу регистрации пользователя 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> - Создайте файл 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;
}
} - Создайте файл 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>');
?>
- А теперь введите в браузере http://localhost/index.html и протестируйте ваше приложение.
Здесь расположен архив со всеми необходимыми файлами. Просто распакуйте его в корневую директорию вашего веб-сервера и выполните в браузере http://localhost/index.html.
Позиционирование элементов на JavaScript.
Сегодня я расскажу о том, как правильно позиционировать элементы страницы друг относительно друга.
Зачем это нужно? Например, чтобы создать красивый выпадающий список. Сегодня мы зададимся целью создать некий пользовательский комбо-бокс. И стандартные возможности HTML нас не устраивают. То есть, мы хотим получить нечто более сложное, чем вот это.
<option>Item 1</option>
<option>Item 2</option>
<option>Item 3</option>
</select>
А получить хотели бы нечто вроде этого:
<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) подойдет вот такая функция:
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>.
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};
}
Ну а вот и сама функция позиционирования:
// 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 нужна, чтобы кроссбаузерно определить текущий стиль элемента:
if(!el) return null;
var s=el.currentStyle;
if(!s) s=document.defaultView.getComputedStyle(el,null); // Для FireFox
return s;
}
А вот здесь находится весь скрипт. Пользуйтесь на здоровье.
Ну а вызов этой функции может выглядеть так:
————————————-