Рубрика «JavaScript»

Работа с cookies. Часть 2

Установка cookie

Установка cookie-наборов средствами JavaScript равнозначна установке свойства cookie объекта document. При этом очень важно использовать тот же самый формат протокола HTTP, что и при отправке cookie-набора клиенту. В обычных cookie-наборах, т.е. таких наборах, у которых отсутствует срок действия или другие ограничения, имя и значение cookie должны ббыть разделены знаком равенства. Кроме того, в имени cookie не должно быть таких специальных сиволов, как пробелы и точки с запятой. Специальные символы в значении cookie должны быть закодированы в формате URL, например, пробел обозначается как %20, т.е. в шестнадцатеричном представлении его кода ASCII.

Как показано в приведенном ниже листинге, для установки нескольких cookie достаточно задать соответствующее число значений свойства document.cookie. Следовательно, запись очередного значения в свойстве document.cookie не приводит к перезаписи всех предыдущих cookie, а лишь к добавлению еще одного cookie. Единственное исключение из этого правила: если cookie с этим же именем уже существует, клиент попытается перезаписать его.

<script type="text/javascript">
document.cookie = "myLanguage=JavaScript";
document.cookie = "myOtherLanguage=PHP:%20Hypertext%20Preprocessor"
</script>

Чтение cookie

При доступе к свойству document.cookie в коде JavaScript извлекается список всех cookie, которые браузер должен отправить обратно текущему серверу. К сожалению, такой доступ возможен только в формате строки, но не массива. Например, приведенный выше пример кода формирует следующее значение свойства document.cookie:

myLanguage=JavaScript;myOtherLanguage=PHP:%20Hypertext%20Preprocessor

Следовательно, для того, чтобы извлечь cookie из этого значения, необходимо предпринять определенные шаги.

  1. Разделить строку cookie по символу “;”, чтобы получить отдельные cookie.
  2. Определить первый знак равенства (=) в каждом cookie в качестве разделителя имени и значения.

Значения cookie могут содержать знаки равенства, поэтому следует использовать первре вхождение знака равенства. В следующем фрагменте кода выводятся все cookie в форме HTML-таблицы.

<script type="text/javascript">
document.write("<table><tr><th>Name</th><th>Value</th></tr>");
var cookies = document.cookie.split(/; /g);
for (var i=0; i<cookies.length; i++) {
  var cookie = cookies[i];
  if (cookie.indexOf("=") == -1) {
    continue;
  }
  var name = cookie.substring(0, cookie.indexOf("="));
  var value = cookie.substring(cookie.indexOf("=") + 1);
  document.write("<tr><td>" +
                 HtmlEscape(name) +
                 "</td><td>" +
                 HtmlEscape(unescape(value)) +
                 "</td></tr>");
}
document.write("</table>");

function HtmlEscape(s) {
  return s.replace(/&/, "&amp;")
          .replace(/</, "&lt;")
          .replace(/>/, "&gt;")
          .replace(/"/, "&quot;")
          .replace(/'/, "
&apos;");
}
</script>

Если же требуется значение одного конкретного cookie, для этой цели можно использовать приведенную ниже вспомогательную функцию. Эта функция осуществляет поиск заданного имени cookie и возвращает его значение, т.е. все, что находится справа от имени cookie вплоть до следующей точки с запятой или конца строки.

<script type="text/javascript">
function getCookie(name) {
  var pos = document.cookie.indexOf(name + "=");
  if (pos == -1) {
    return null;
  } else {
    var pos2 = document.cookie.indexOf(";", pos);
    if (pos2 == -1) {
      return unescape(
        document.cookie.substring(pos + name.length + 1));
    } else {
      return unescape(
        document.cookie.substring(pos + name.length + 1, pos2));
    }
  }
}

alert(getCookie("myLanguage"));
alert(getCookie("myOtherLanguage"));
</script>

Плагин FancyBox для библиотеки jQuery

В одной из предыдущих заметок я писал про то, как организовать удобный просмотр изображений на сайте. Lightbox использует библиотеки Prototype и Scriptaculous. Сегодня рассмотрим плагин FancyBox для библиотеки jQuery. Плагин позволяет

  • просматривать отдельные изображения;
  • организовать просмотр группы фотографий (фотогалерея);
  • спрятать за одной миниатюрой целую галерею фотографий;
  • выводить контент, находящийся на странице — например видеоролики с YouTube;
  • выводить произвольный контент в плавающем фрейме iframe.

Для начала нам потребуется подключить в разделе head HTML-страницы четыре JavaScript-файла:

  • jquery.js — библиотека jQuery;
  • jquery.fancybox.js — плагин FancyBox;
  • jquery.pngFix.js — позволит устранить проблему использования png-файлов в IE;
  • jquery.metadata.js — позволит использовать атрибуты class для передачи параметров плагину.

Первые два из них обязательны, а без двух остальных можно обойтись.

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.fancybox.js"></script>
<script type="text/javascript" src="js/jquery.pngFix.js"></script>
<script type="text/javascript" src="js/jquery.metadata.js"></script>

Далее необходимо подключить стиль отображения для окна просмотра:

<link rel="stylesheet" href="css/fancy.css" type="text/css" media="screen">

Добавляем на страницу картинку-миниатюру, заключенную в тэг <a>, который ссылается на полноразмерное изображение. Заголовок, если таковой требуется, можно разместить в атрибуте title.

<a href="image_big.jpg" title="my caption"><img src="image_small.jpg" alt=""/></a>

Если необходимо разместить несколько логически связанных изображений и организовать навигацию между ними в окне просмотра, то нужно добавить атрибут rel для каждого связанного изображения. Например:

<p id="gallery">
<a href="/example/fancybox/04.jpg" rel="fancy-tour">
<img src="/example/fancybox/04-thumb.jpg" />
</a>
<a href="/example/fancybox/05.jpg" rel="fancy-tour">
<img src="/example/fancybox/05-thumb.jpg" />
</a>
<a href="/example/fancybox/06.jpg" rel="fancy-tour">
<img src="/example/fancybox/06-thumb.jpg" />
</a>
</p>

На странице может быть размещено несколько фотогалерей и каждая из них может содержать любое число изображений.

Теперь JavaScript-код:

$(document).ready(function(){
  $("#gallery a").fancybox();
});

Мы отбираем все нужные нам элементы <a> и передаем этот набор плагину FancyBox, который проделывает всю остальную работу. Можно использовать дополнительные опции:

  • hideOnContentClick — скрывать контент по клику на полноразмерном изображении. Может принимать значения true или false. По умолчанию false.
  • zoomSpeedIn — указывается скорость эффекта (в миллисекундах) при открытии полноразмерного изображения. По умолчанию — 0, т.е. без эффекта.
  • zoomSpeedOut — указывается скорость эффекта (в миллисекундах) при закрытии полноразмерного изображения. По умолчанию — 0, т.е. без эффекта.
  • overlayShow — показывать или нет дополнительный слой, который “затемняет” основное содержимое страницы. Может принимать значения true или false. По умолчанию false.
  • overlayOpacity — прозрачность для overlayShow, если конечно он true. Изменяется от 0 до 1.
  • frameWidth — определяет ширину контейнера, если выводится iframe и inline содержимое (см. пример).
  • frameHeight — определяет высоту контейнера, если выводится iframe и inline содержимое (см. пример).
  • itemLoadCallback — определяет пользовательскую функцию, которая выбирает группу фотографий для отображения (см. пример).

А теперь посмотрим, как за одной миниатюрой скрывается целый набор полноразмерных изображений.

HTML:

<a id="custom" href="javascript:;"><img src="/example/fancybox/07-thumb.jpg" alt="" /></a>

JavaScript:

$("a#custom").fancybox({
  'itemLoadCallback': getGroupItems
});

var imageList = [
  {url: "/example/fancybox/07-1.jpg", title: "Первая картинка"},
  {url: "/example/fancybox/07-2.jpg", title: "Вторая картинка"},
  {url: "/example/fancybox/07-3.jpg", title: "Третья картинка"}
];

function getGroupItems(opts) {
  jQuery.each(imageList, function(i, val) {
    opts.itemArray.push(val);
  });
}

Здесь мы создаем массив imageList, каждым элементом которого является объект, состоящий из пар ключ-значение:

  • url — URL полноразмерного изображения;
  • title — содержит комментарий к изображению.

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

HTML:

<a href="#testube" id="video" class="{frameWidth: 425, frameHeight: 355}"><img src="images/08-thumb.jpg"  alt="" /></a>

<div style="display:none" id="testube">
<object width="425" height="344">
<param name="movie" value="http://www.youtube.com/v/...&hl=en&fs=1"></param>
<param name="allowFullScreen" value="true"></param>
<param name="wmode" value="transparent"></param>
<embed src="http://www.youtube.com/v/...&hl=en&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" wmode="transparent" width="425" height="344"></embed>
</object>
</div>

JavaScript:

$("a#video").fancybox({
  zoomSpeedIn: 0,
  zoomSpeedOut:0,
  frameWidth: 425,
  frameHeight: 344
});

И последнее — вывод любого контента через iframe.

HTML:

<a id="frame" href="http://www.google.ru/"><img src="/example/fancybox/09-thumb.jpg" alt="" /></a>

JavaScript:

$("a#frame").fancybox({
  zoomSpeedIn: 0,
  zoomSpeedOut:0,
  frameWidth: 800,
  frameHeight: 600
});

Ссылки по теме:

Работа с cookies. Часть 1

Cookie представляют собой механизм, применяемой в модели “клиент-сервер” для преодоления одного из ограничений протокола HTTP. Этот протокол не сохраняет свое состояние, т.е. у него нет памяти. Клиент устанавливает соединение, получает документ (текст, изображение или любые другие данные), затем разрывает соединение. Если затем сервер отправляет данные этому клиенту, он не распознает его.

Cookie-наборы позволяют обойти подобное ограничение. В частности, сервер может послать клиенту краткую текстовую информацию, называемую cookie-набором. Эта информация принимается и сохраняется локально, а клиент отправляет ее обратно этому же серверу при каждом запросе. Это дает возможность серверному приложению возможность вновь распознать пользователя.

В JavaScript имеются средства для получения (т.е. чтения) и установки (т.е. записи) cookie, не прибегая к протоколу HTTP. Это позволяет добиться результатов, которые трудно достижимы только средствами HTTP серверной технологии.

Общее представление о cookie

Когда Web-сервер посылает cookie-набор клиенту, используется HTTP-заголовок следующего вида:

Set-Cookie: session=absd1234; expires=Tue, 20-Feb-2008 12:10:52 GMT; path=/; domain=.example.com

Затем клиент получает данный cookie-набор и в соответствии со своей конфигурацией и/или возможностями предпринимает одно из следующих действий:

  • игнорирует cookie-набор;
  • принимает cookie-набор;
  • запрашивает пользователя, следует ли принять cookie-набор;
  • отклоняет сookie-набор.

Первое и последнее действия, по существу, означают одно и то же. Web-сервер не в состоянии определить, был ли cookie-набор отвергнут пользователем, отклонен конфигурацией клиента или же проигнорирован клиентом из-за отсутствия поддержки cookie.

Если cookie-наборы принимаются, они затем отправляются обратно серверу, при условии, что выполняется определенный ряд требований. А соответствующий HTTP-заголовок принимает следующий вид:

Cookie: session=abcd1234

Cookie-набор может быть связан с определенным доменом или путем. Поэтому cookie-набор обычно посылается обратно только тому серверу, от которого он был первоночально получен. В cookie-наборе можно перезаписать значение домена, но после этого некоторые браузеры автоматически отклоняют такой cookie-набор.

Кроме того, для cookie-наборов установлены определенные ограничения. Не все браузеры поддерживают их одинаково, но для такой поддержки должны быть выполнены следующие минимальные требования:

  • объем памяти на каждый cookie-набор — 4 Кбайт (4096 байт);
  • число cookie-наборов на каждый домен — 20;
  • общее число cookie-наборов — 300;