Разработка приложений Web 2.0 при помощи PHP и DHTML, Часть 1: "Приготовьте" свои страницы с помощью данных рецептов

Модное словечко сезона 2006 года - Web 2.0. Значение этого слова широко обсуждается, но, кажется, его можно отнести к популярным динамическим web-приложениям. В этих приложениях - обычно создаваемых на PHP - используется динамический HTML (DHTML) для создания страниц, которые можно обновлять без обращения к серверу. Автор Джэк Хэррингтон в цикле статей "Разработка приложений Web 2.0 при помощи PHP и DHTML" объясняет, как взяться за дело.

Джэк Хэррингтон, старший инженер по программному обеспечению, Studio B

Джэк Д. Хэррингтон (Jack D. Herrington) - старший инженер по программному обеспечению с более чем двадцатилетним стажем. Он является автором трех книг: Code Generation in Action, Podcasting Hacks и PHP Hacks. Также им написано более тридцати статей.



15.06.2007

DHTML - это HTML, который включает код JavaScript, изменяющий содеражние или формат страницы в браузере без обращения к серверу. Когда вы пишете страницу HTML, на самом деле вы создаете разветвленную систему объектов. Все теги - небольшие таблицы <table> и абзацы <p> - становятся объектами в пространстве JavaScript. Используя JavaScript, вы можете изменять их содержание, дизайн Каскадных Таблиц Стилей (CSS) и местонахождение - все без обращения к серверу. DHTML - это сочетание HTML, CSS и JavaScript.

Технология использования DHTML известна с добавления поддержки JavaScript-кода в браузере, но эта поддержка была неполная. В Microsoft® Internet Explorer сразу была проделана отличная работа , в то время как у Netscape V4 чувствуется недостаток поддержки этой технологии. В последнее время Mozilla и Firefox далеко шагнули в поддержке DHTML, и, как полагают некоторые, совершили такой скачок, за которым Internet Explorer не поспеть.

DHTML: за и против

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

Тем не менее, есть причина, усложняющая использование JavaScript, - совместимость с браузером. На заре возникновения HTML Internet Explorer и Netscape представляли страницы по-разному. Эта проблема была устранена, но при добавлении поддержки CSS возникли сложности с совместимостью. Сейчас большая часть вопросов с CSS разрешена, однако остаются проблемы с совместимостью JavaScript.

У этих проблем совместимости нет простого решения. Вам придется взвесить с одной стороны преимущества использования JavaScript, с другой - множество браузеров, которые вам придется тестировать и поддерживать.

Вот некоторые рекомендации:

  • Используйте настолько простой JavaScript, насколько можете.
  • Столкнувшись с проблемой совместимости, поищите лучшее решение в интернете. В большинстве случаев вы найдете хорошие решения.
  • У вас должна быть копия страницы на HTML для браузеров, которые вы не поддерживаете.
  • У вас должен быть список браузеров (и номера их версий), которые вы поддерживаете.
  • Проверьте Internet Explorer на Mac и Microsoft Windows®.

Приведенные примеры предельно просты и понятны. Тем не менее, они проверены только на Firefox, поэтому возникают кое-какие проблемы с совместимостью. Статья предупреждает вас о проблемах совместимости, чтобы вы могли научиться на собственном опыте.

Простейший способ реализовать DHTML - это сначала написать его в виде простой HTML-страницы без PHP или любого другого серверного языка (server-side language), затем использовать этот код как шаблон для PHP-кода, чтобы создать DHTML. Тогда вы сможете проверить основные решения и отделить проблемы сервера и клиента. В каждом примере данная статья сначала показывает HTML, а затем - тот же код, используемый с PHP.


Рекламные окна

Первый пример простой и совместимый: плавающее рекламное окно. Рисунок 1 показывает рекламное окно с кнопкой "закрыть", расположенное поверх страницы.

Рисунок 1. Плавающее рекламное окно
Плавающее рекламное окно

Пользователь может нажать кнопку "закрыть", чтобы удалить рекламное окно, как показано на рисунке 2.

Рисунок 2. Страница после удаления рекламного окна
Страница после удаления рекламного окна

Листинг 1 показывает код для этой страницы.

Листинг 1. Код рекламного окна
<html>
<head>
<title>Ad box demonstration</title>
<style>
body {
  width: 800px;
}
.ad-box {
  background: #eee;
  border: 1px solid black;
  padding: 5px;
  position: absolute;
  left: 50px;
  top: 50px;
  width: 600px;
}
.ad-box-title {
  background: #ccc;
  padding: 5px;
  font-weight: bold;
  font-size: large;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.2em;
}
</style>
<script>
function closead()
{
  var obj = document.getElementById( "ad" );
  obj.style.visibility = "hidden";
}
</script>
</head>
<body>
<div class="ad-box" id="ad">
<div class="ad-box-title">
Special offer
</div>
<p>
You have been selected for our special offer. Can you imagine? What
are the odds? Just buy five hundred or more of our product and we
will give you a 1% discount on additional orders. Only the Department
of Defense gets deals like that!
</p>
<p style="text-align: right;">
<a href="javascript:closead();">close</a>
</p>
</div>
<p>This is our home page. Welcome to it. Here we talk about all of
our great products.</p>
<h1>Products</h1>
<p>This is a list of our products:</p>
<ul>
<li>The amazing all in one toothpix holder and axe grinder.</li>
<li>The complete Jean Claude Van Damme DVD collection.</li>
</ul>
</body>
</html>

Большая часть работы в этом примере выполнена с помощью CSS. Используя атрибут CSS position, можно расположить окно поверх текста страницы. Атрибуты left и top располагают элемент относительно левого верхнего угла страницы.

Чтобы окно исчезало, нужно закрепить JavaScript-код за якорным тэгом close. Вместо использования протокола http мы используем javascript протокол и запускаем функцию closead. Функция JavaScript closead получает ссылку объекта на ad <div> и изменяет стиль CSS visibility с visible на hidden, и вот рекламное окно исчезает.

Этот пример демонстрирует некоторые основные моменты DHTML. Первый - это использование атрибутов id. Чтобы сделать динамическую ссылку на элемент, дайте ему уникальный ID через атрибут id. В данном случае значением атрибута ID является ad. Затем вы используете метод document.getElementById, чтобы получить ссылку на объект <div> для рекламного окна.

Этот пример также демонстрирует псевдо-URL javascript, который вы можете использовать в якорных тэгах. С его помощью вы можете запустить JavaScript везде, где установите ссылку.

Эти методики совместимы с другими браузерами. Все современные браузеры поддерживают JavaScript, CSS, абсолютное позиционирование и настройку динамических элементов типа атрибута visibility во время выполнения программы.


Рекламные окна в PHP

Теперь, когда у вас есть код рекламного окна в DHTML, вы можете посмотреть, как выполнить его в PHP (см. листинг 2). Единственный выбор относительно рекламного окна - следует ли его показывать. Код PHP описывает рекламное окно с единственной функцией вызова, которую страница может вызывать или не вызывать в зависимости от обстоятельств.

Листинг 2. Рекламное окно с PHP
<?php
function place_ad( $title )
{
?>
<div class="ad-box" id="ad">
<div class="ad-box-title">
<?php echo( $title ); ?>
</div>
<p>
You have been selected for our special offer. Can you imagine? What
are the odds? Just buy five hundred or more of our product and we
will give you a 1% discount on additional orders. Only the Dept.
of Defense gets deals like that!
</p>
<p style="text-align: right;">
<a href="javascript:closead();">close</a>
</p>
</div>
<?php
}
?>
<html>
<head>
<title>Ad box demonstration</title>
<style>
body {
  width: 800px;
}
.ad-box {
  background: #eee;
  border: 1px solid black;
  padding: 5px;
  position: absolute;
  left: 50px;
  top: 50px;
  width: 600px;
}
.ad-box-title {
  background: #ccc;
  padding: 5px;
  font-weight: bold;
  font-size: large;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.2em;
}
</style>
<script>
function closead()
{
  var obj = document.getElementById( "ad" );
  obj.style.visibility = "hidden";
}
</script>
</head>
<body>
<?php place_ad( "Today's Special Offer!" ); ?>
<p>This is our home page. Welcome to it. Here we talk about all of
our great products.</p>
<h1>Products</h1>
<p>This is a list of our products:</p>
<ul>
<li>The amazing all in one toothpix holder and axe grinder.</li>
<li>The complete Jean Claude Van Damme DVD collection.</li>
</ul>
</body>
</html>

Новая PHP функция place_ad выводит рекламное окно на страницу с гибкой строкой заголовка. Чтобы иметь возможность поместить рекламу на несколько страниц, вы можете взять эту функцию и поместить ее в отдельный файл, который вы будете включать при необходимости вставить рекламу в страницу.


Всплывающие окна

Еще один вид подвижных окон - это всплывающие окна. Вы можете использовать всплывающие окна для приведения дополнительной информации, когда пользователь запросит ее. Рассмотрите текст, показанный на рисунке 3.

Рисунок 3. Простая текстовая страница о животных
Простая текстовая страница о животных

Разве не лучше, если пользователь узнает больше информации о жирафе? Текст содержит удобную ссылку: если вы выберете ее, то увидите всплывающее окно, показанное на рисунке 4.

Рисунок 4. Подробнее о жирафах
Подробнее о жирафах

Здесь вы открываете окно по запросу и располагаете его относительно текста документа. Код показан в листинге 3.

Листинг 3. Всплывающее окно в HTML
<html>
<head>
<title>Pop up Example</title>
<style type="text/css">
body { font-family: arial, verdana, sans serif; }
#popup {
  position: absolute;
  padding: 5px;
  border: 1px solid black;
  background: #eee;
  left: 0px;
  top: 0px;
  visibility: hidden;
}
</style>
<script>
function popup( id )
{
  var obj = document.getElementById( id );
  var popup = document.getElementById( 'popup' );
  if ( popup.style.visibility == 'visible' )
  {
    popup.style.visibility = 'hidden';
  }
  else
  {
    popup.style.left = obj.offsetLeft + "px";
    popup.style.top = ( obj.offsetTop + 20 ) + "px";
    popup.style.visibility = 'visible';
  }
}
</script>
</head>
<body>
<div id="popup">
An animal with a very long neck.
</div>
<h2>Animals</h2>
A <a href="javascript:popup('word')" id="word">giraffe</a>
is a very interesting animal.
</body>
</html>

В данном примере popup <div>, содержащий информацию всплывающего окна, сначала определен как hidden и абсолютно расположен в левом верхнем углу страницы. Затем якорный тег, прикрепленный к слову giraffe, вызывает JavaScript для вывода всплывающего окна.

Метод popup JavaScript находит текст giraffe, используя идентификатор word. Далее, он использует значения offsetLeft и offsetTop, чтобы расположить всплывающее окно сразу под текстом. Если всплывающее окно уже отображается, оно прячется.

Вы можете настроить содержимое всплывающего окна до того, как оно станет видимым, установив член innerHTML на объект popup <div>.

Это довольно совместимый код. Однако могут возникнуть несоответствия из-за разницы в значениях offsetLeft и offsetTop от браузера к браузеру, особенно в страницах со сложным вложенным содержимым. Чтобы получить более точную позицию при чтении сложной страницы, вам может понадобиться рекурсивно добавлять значения offsetLeft и offsetTop, используя объект offsetParent чтобы получить родительский объект для каждого объекта при движении вверх по дереву HTML объектов.


Всплывающие окна в PHP

Имея код DHTML, вам будет проще пользоваться всплывающими окнами в PHP приложениях. PHP код показан в листинге 4.

Листинг 4. PHP код всплывающего окна
<?php
function popup_header()
{
?>
<style type="text/css">
body { font-family: arial, verdana, sans serif; }
#popup {
  position: absolute;
  padding: 5px;
  border: 1px solid black;
  background: #eee;
  left: 0px;
  top: 0px;
  visibility: hidden;
}
</style>
<script>
function popup( id, info )
{
  var obj = document.getElementById( id );
  var popup = document.getElementById( 'popup' );
  if ( popup.style.visibility == 'visible' )
  {
    popup.style.visibility = 'hidden';
  }
  else
  {
    popup.innerHTML = info;
    popup.style.left = obj.offsetLeft + "px";
    popup.style.top = ( obj.offsetTop + 20 ) + "px";
    popup.style.visibility = 'visible';
  }
}
</script>
<?php
}

function popup( $id, $text, $info )
{
?>
<a href="javascript:popup('<?php echo($id) ?>','<?php echo($info) ?>')"
  id="<?php echo($id) ?>"><?php echo($text) ?></a>
<?php
}
?>
<html>
<head>
<title>Pop up Example</title>
<?php popup_header(); ?>
</head>
<body>
<div id="popup">
</div>
<h2>Animals</h2>
A
<?php popup( 'word', 'giraffe',
   'An animal with a very long neck.' ) ?>
is a very interesting animal.
</body>
</html>

tml>

Здесь вы разделяете генерацию заголовка и расположение каждого всплывающего окна. Страница должна вызвать popup_header внутри тэга head, затем добавить тэг <div> со значением id равным popup. Далее, страница вызывает PHP функцию popup там, где требуется всплывающее окно.

Эта PHP функция popup получает три параметра: идентификатор всплывающего окна, версию с простым текстом и текст, который должен всплыть, когда выбран элемент. Затем функция формирует изображение якорного тэга, которое выглядит почти также как оригинал в версии DHTML.

Так как на одной странице может появиться сразу несколько всплывающих окон, добавлен третий параметр - текст, который появляется внутри всплывающего окна. Это можно выполнить, добавив дополнительный параметр к JavaScript функции popup. Содержимое этого нового параметра затем присваивается атрибуту InnerHTML тэга <div>.


Счетчики

Еще одна опция для скрытия и отображения данных на странице - это счетчик. В данной модели страница разбита на две секции, которые можно спрятать или показать по отдельности, используя счетчик. Рисунок 5 показывает страницу с двумя секциями со счетчиком, каждая из которых изначально закрыта.

Рисунок 5. Секции страницы с закрытыми счетчиками
Секции страницы с закрытыми счетчиками

Выбор ссылки Open в секции Level One отображает содержимое этой секции, как показано на рисунке 6.

Рисунок 6. Страница с открытым первым счетчиком
Страница с открытым первым счетчиком

Вместо слов open и closed вы можете использовать графические объекты. По традиции, эти графические объекты обычно представляют собой треугольники, которые указывают направо для closed, или вниз для open; или знаки плюса и минуса, где плюс означает closed, а минус - open. (Мнения о том, какой подход лучше, восходит к спору между Mac и Windows. Счетчики на двух платформах соответствуют двум разным вариантам.)

Код в листинге 5 показывает, как работают эти счетчики:

Листинг 5. Счетчики в HTML
<html>
<head>
<title>Spinner Example</title>

<style type="text/css">
body { font-family: arial, verdana, sans serif; width: 800px; }
.item-header a { font-size: small; }
.item-header {
  font-weight: bold; border-bottom: 1px solid black;
  font-size: x-large;
}
.item-body {
  margin: 0px; font-size: small;
  visibility: hidden; height: 0px;
}
</style>

<script>
function spin( obj )
{
  var spinner = document.getElementById( obj );
  var spinner_content = document.getElementById( obj+"_body" );
  if ( spinner_content.style.visibility == 'visible' )
  {
    spinner.innerHTML = 'open';
    spinner_content.style.visibility = 'hidden';
    spinner_content.style.height = '0px';
    spinner_content.style.margin = '0px';
  }
  else
  {
    spinner.innerHTML = 'close';
    spinner_content.style.visibility = 'visible';
    spinner_content.style.height = 'auto';
    spinner_content.style.margin = '20px 0px 20px 50px';
  }
}
</script>

</head>
<body>

<div class="item-header">
<a href="javascript:spin('lev1')" id="lev1">open</a> Level One
</div>

<div class="item-body" id="lev1_body">
This is the content of level one.
</div>

<div class="item-header">
<a href="javascript:spin('lev2')" id="lev2">open</a> Level Two
</div>

<div class="item-body" id="lev2_body">
This is the content of level two.
</div>

</body>
</html>

Две группы <div> определяют каждую секцию и ее содержимое. По традиции, заголовку дается идентификатор lev, плюс цифра (например, lev2), а телу дается тот же идентификатор с суффиксом _body. Lev2 - это ссылка на счетчик, а lev2_body - это тело данного элемента.

Механизм счетчика реализован в функции spin, которая учитывает видимость тела счетчика и инвертирует ее, меняя видимый на скрытый, а скрытый на видимый.

Вы устанавливаете атрибут height на 0px, когда элемент невидим, и на auto - когда видим. В Internet Explorer когда элемент невидим, окружающее пространство сжимается. Но в Firefox когда содержимое невидимо, для него остается пустое пространство. Вам нужно установить height на 0px, чтобы пространство должным образом сжалось.

Чтобы использовать графические элементы вместо текста, чтобы выразить открытое или закрытое состояние, переделайте код, который изменяет значение innerHTML объекта счетчика, чтобы задать тэг-рисунок вместо текстового тэга.


Счетчики в PHP

Чтобы выполнить счетчики в PHP, необходимо следовать стандартной модели создания DHTML кода с позиций сервера, заключая сегменты HTML в функциях начало и конец. PHP код показан в листинге 6.

Листинг 6. Счетчик в PHP
<?php
function start_spinner( $id, $title )
{
?>
<div class="item-header">
<a href="javascript:spin('<?php echo( $id ); ?>')"
  id="<?php echo( $id ); ?>">open</a> <?php echo( $title ); ?>
</div>

<div class="item-body" id="<?php echo( $id ); ?>_body">
<?php
}

function end_spinner()
{
?>
</div>
<?php
}
?>
<html>
<head>
<title>Spinner Example</title>

<style type="text/css">
body { font-family: arial, verdana, sans serif; width: 800px; }
.item-header a { font-size: small; }
.item-header {
  font-weight: bold; border-bottom: 1px solid black;
  font-size: x-large;
}
.item-body {
  margin: 0px; font-size: small;
  visibility: hidden; height: 0px;
}
</style>

<script>
function spin( obj )
{
  var spinner = document.getElementById( obj );
  var spinner_content = document.getElementById( obj+"_body" );
  if ( spinner_content.style.visibility == 'visible' )
  {
    spinner.innerHTML = 'open';
    spinner_content.style.visibility = 'hidden';
    spinner_content.style.height = '0px';
    spinner_content.style.margin = '0px';
  }
  else
  {
    spinner.innerHTML = 'close';
    spinner_content.style.visibility = 'visible';
    spinner_content.style.height = 'auto';
    spinner_content.style.margin = '20px 0px 20px 50px';
  }
}
</script>

</head>
<body>

<?php start_spinner( 'lev1', "Level One" ); ?>
This is the content of level one.
<?php end_spinner( ); ?>

<?php start_spinner( 'lev2', "Level Two" ); ?>
This is the content of level two.
<?php end_spinner( ); ?>

</body>
</html>

Каждая секция содержимого заключена в скобки с вызовом к start_spinner и end_spinner. Функция start_spinner учитывает два аргумента: идентификатор счетчика и его заголовок. Вызов end_spinner закрывает тэг<div>, открытый в start_spinner, чтобы скрыть содержимое счетчика.

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


Закладки

Закладки - это еще один распространенный способ представления различных частей содержимого. На сайте MetaCritic (см. Ресурсы) появилась облегченная версия закладок, которая использует закладки для переключения просмотра списка игр по имени или по набранному счету, без возвращения к серверу. Рисунок 7 показывает упрощенный пример списка игр.

Рисунок 7. Игры, отсортированные по имени
Игры, отсортированные по имени

Чтобы увидеть игры, отсортированные по счету, выберите ссылку By Score. Список изменится так, как показано на рисунке 8.

Рисунок 8. Игры, отсортированные по счету
Игры, отсортированные по счету

Вместо выполнения сложной сортировки со стороны клиента, сайт использует эквивалент флэш карт: В одной карте содержится список, отсортированный по именам, в другой - по счету. Выбор ссылок прячет одну карту и показывает другую. Код показан в листинге 7.

Листинг 7. Закладки в HTML
<html>
<head>
<title>Tabs Example</title>
<style type="text/css">
body { font-family: arial,verdana,sans serif; }
.button-on, .button-off { padding: 3px; border: 1px solid black; }
.button-on { background: #333; color: white; font-weight: bold; }
.game-list { position: absolute; top: 0px; left: 0px; }
.container { padding: 5px; border: 1px solid black; margin: 5px;
  position: relative; height: 400px; width: 200px; }
</style>
<script>
function show( divid )
{
  var tos = [ "names", "score" ];
  for( var t in tos )
  {
    var to = document.getElementById( tos[t] );
    to.style.visibility = "hidden";
    to.style.height = "0px";

    var bo = document.getElementById( tos[t]+"-button" );
    bo.className = "button-off"
  }

  var to = document.getElementById( divid );
  to.style.visibility = "visible";
  to.style.height = "auto";

  var bo = document.getElementById( divid + "-button" );
  bo.className = "button-on";
}
</script>
</head>
<body onload="show('names')">
Sort by:
<a href="javascript:show('names')" id="names-button"
  class="button-on">By Name</a>
<a href="javascript:show('score')" id="score-button"
  class="button-off">By Score</a><br/>
<div class="container">
<div id="names" class="game-list">
<table width="100%">
<tr><td>Crank Shaft</td><td>22</td></tr>
<tr><td>Driver</td><td>42</td></tr>
<tr><td>Football 2006</td><td>72</td></tr>
<tr><td>Soccer 2006</td><td>99</td></tr>
<tr><td>Xevious</td><td>32</td></tr>
</table>
</div>
<div id="score" class="game-list">
<table width="100%">
<tr><td>Crank Shaft</td><td>22</td></tr>
<tr><td>Xevious</td><td>32</td></tr>
<tr><td>Driver</td><td>42</td></tr>
<tr><td>Football 2006</td><td>72</td></tr>
<tr><td>Soccer 2006</td><td>99</td></tr>
</table>
</div>
</div>
</body>
</html>

Два списка находятся в двух <div> тэгах: names и score. Names <div> содержит список игр, отсортированных по имени, score - по счету. Функция show, связанная со ссылками By Name и By Score, сначала делает все ссылки невидимыми, а затем делает видимым выбранный список.

Также происходят еще некоторые интересные вещи. Во-первых, вы динамически изменяете класс CSS, используя атрибут className. Таким образом, выбранная кнопка меняет цвет с белого на черный.

Во-вторых, найдите в CSS names и score. Оба <div>а расположены абсолютно вверху слева, но они не находятся в левом верхнем углу страницы. Это происходит потому, что они находятся в <div> со значением идентификатора container, которому присвоена позиция relative. Этот container <div> эффективно переставляет начальные места содержащихся в нем элементов. Закладки располагаются относительно контейнера, а не страницы.

Этот тип, будучи достаточно сложным и интересным, вдобавок еще и совместим почти с любым современным браузером.


Закладки в PHP

Другим инструментом при разработке DHTML в PHP является использование буферизации на выходе. Буферизация на выходе хранит текст, тэги и повтор материалов со страницы и возвращает их как строку для последующего использования. Для реализации закладок, вы используете буферизацию на выходе, чтобы сохранить содержимое закладки как строку перед визуализацией его на страницу (см. листинг 8).

Листинг 8. Закладки в PHP
<?php
$tabs = array();
$current_tab = null;

function start_tab( $id, $title )
{
  global $tabs, $current_tab;

  ob_start();
  $current_tab = $id;
  $tabs[ $id ] = array( 'title' => $title, 'html' => "" );
}

function end_tab()
{
  global $tabs, $current_tab;

  $tabs[ $current_tab ][ 'html' ] = ob_get_contents();
  ob_end_clean();
}

function get_tab_ids()
{
  global $tabs;

  $ids = array();
  foreach( $tabs as $tabid => $tab ) {
    $ids []= "'".$tabid."'";
  }
  return $ids;
}

function get_first_tab()
{
  $tabs = get_tab_ids();
  return $tabs[0];
}

function place_tab_buttons()
{
  global $tabs;

  foreach( $tabs as $tabid => $tab ) {
?>
<a href="javascript:show('<?php echo($tabid); ?>')"
  id="<?php echo($tabid); ?>-button"
  class="button-off"><?php echo( $tab['title'] ); ?></a>
<?php
  }
}

function place_tab_content()
{
  global $tabs;

  foreach( $tabs as $tabid => $tab ) {
?>
<div id="<?php echo($tabid); ?>" class="game-list">
<?php echo( $tab['html'] ); ?>
</div>
<?php
  }
}
?>
<?php start_tab( 'names', "By Name" ); ?>
<table width="100%">
<tr><td>Crank Shaft</td><td>22</td></tr>
<tr><td>Driver</td><td>42</td></tr>
<tr><td>Football 2006</td><td>72</td></tr>
<tr><td>Soccer 2006</td><td>99</td></tr>
<tr><td>Xevious</td><td>32</td></tr>
</table>
<?php end_tab( ); ?>
<?php start_tab( 'scores', "By Score" ); ?>
<table width="100%">
<tr><td>Crank Shaft</td><td>22</td></tr>
<tr><td>Xevious</td><td>32</td></tr>
<tr><td>Driver</td><td>42</td></tr>
<tr><td>Football 2006</td><td>72</td></tr>
<tr><td>Soccer 2006</td><td>99</td></tr>
</table>
<?php end_tab( ); ?>
<html>
<head>
<title>Tabs Example</title>
<style type="text/css">
body { font-family: arial,verdana,sans serif; }
.button-on, .button-off { padding: 3px; border: 1px solid black; }
.button-on { background: #333; color: white; font-weight: bold; }
.game-list { position: absolute; top: 0px; left: 0px; }
.container { padding: 5px; border: 1px solid black; margin: 5px;
  position: relative; height: 400px; width: 200px; }
</style>
<script>
function show( divid )
{
  var tos = [ <?php echo( join( ",", get_tab_ids() ) ); ?> ];
  for( var t in tos )
  {
    var to = document.getElementById( tos[t] );
    to.style.visibility = "hidden";
    to.style.height = "0px";

    var bo = document.getElementById( tos[t]+"-button" );
    bo.className = "button-off"
  }

  var to = document.getElementById( divid );
  to.style.visibility = "visible";
  to.style.height = "auto";

  var bo = document.getElementById( divid + "-button" );
  bo.className = "button-on";
}
</script>
</head>
<body onload="show(<?php echo( get_first_tab() ); ?>)">
Sort by:
<?php place_tab_buttons() ?>
<div class="container">
<?php place_tab_content() ?>
</div>
</body>
</html>

PHP код начинается с определения двух переменных: tabs и current_tab. Массив tabs содержит значения id, title и html для каждой закладки. current_tab указывает на закладку, создаваемую между вызовами к start_tab и end_tab. Функция start_tab учитывает два параметра: значение id закладки и значение title. Затем она начинает буферизацию на выходе.

Функция end_tab останавливает буферизацию на выходе и сохраняет результирующий HTML в значении html в current_tab массива tabs.

Если вы посмотрите дальше, то увидите, что вызовы функций start_tab и end_tab находятся вокруг содержимого закладок, которое отображается в закладке.

Важными функциями для визуализации закладок на странице являются place_tab_buttons и place_tab_content. Функция place_tab_buttons создает якорные тэги, имеющие те же имена, что и закладки и которые, будучи выбранными, переключают закладки. Функция place_tab_content создает тэги <div> с содержимым каждой закладки, сохраненным при помощи буферизации на выходе.

get_tab_ids и get_first_tab - это вспомогательные функции, используемые в создании JavaScript. Они возвращают полный список идентификаторов и идентификатор первой закладки соответственно.


Смотрите также

Следующая статья в серии "Разработка приложений Web 2.0 при помощи PHP и DHTML" рассматривает формирование динамических графиков при помощи JavaScript. Она научит, как создавать новые элементы HTML на ходу и располагать их возле страниц, представленных вашим PHP приложением.

Ресурсы

Научиться

  • Оригинал статьи Devise Web 2.0 applications with PHP and DHTML, Part 1.
  • PHP.net - отправной пункт в изучении PHP.
  • Блог Ajaxian - отличное место для поиска советов по пользовательскому программированию.
  • Ajax Freaks - еще один хороший сайт по пользовательскому программированию.
  • WebReference.com содержит хорошие статьи и ссылки на материалы по проблемам совместимости браузеров.
  • Dynamic HTML: The Definitive Reference O'Reilly - лучшая книга по динамическому HTML.
  • Чтобы найти образцы закладок, о которых мы говорили в этой статье, посетите сайт Metacritic.com.
  • Прочитайте статью developerWorks "A cross-browser DHTML table", чтобы узнать, как создавать межбраузерные таблицы при помощи DHTML и JavaScript, которые могут большинство тех вещей, что и табличные компоненты, написанные в Java.
  • Прочитайте "Создание приложений с использованием технологии AJAX (Asynchronous JavaScript with XML) (AJAX)", чтобы узнать, как разрабатывать веб приложения, основанные на AJAX, и заканчивающиеся валидацией в реальном времени и без обновления страниц, следуя конструкции примера приложения для подачи заказов.
  • Посетите сайт IBM developerWorks PHP project resources, чтобы больше узнать о PHP.
  • Будьте в курсе технических событий и веб-вещания developerWorks.
  • Посетите Раздел открытых ресурсов developerWorks для всесторонней информации о методах разработки, инструментах и усовершенствованных проектах, что поможет вам в разработке с использованием технологий открытых исходных текстов и использовании их вместе с продуктами IBM.

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source
ArticleID=231213
ArticleTitle=Разработка приложений Web 2.0 при помощи PHP и DHTML, Часть 1: "Приготовьте" свои страницы с помощью данных рецептов
publish-date=06152007