Статьи

Как мы это сделали — DZone доступен на вашем iPhone

В последнее время iPhone был в моде, от жалоб до похвал все было услышано. Ненавидите ли вы это или любите это, факт остается фактом, как разработчик, вы не можете игнорировать это. И здесь, в DZone, мы не могли игнорировать возможность предоставить еще больше средств, с помощью которых вы можете получить доступ к ссылкам для разработки. В этой статье я поделюсь с вами, как мы пошли о воссоздании DZone для iPhone.

Перво-наперво, настройте среду разработки. Я решил пойти со старым фаворитом, Aptana Studio . После того, как вы загрузили Aptana, продолжайте и установите инструменты для разработки iPhone, которые вы найдете на странице приветствия студии. После загрузки всех компонентов выберите «Установить все» и перезапустите рабочую среду. Теперь все готово для создания вашего первого приложения для iPhone.

Затем нажмите «Файл»> «Новый проект», а затем выберите проект iPhone. Дайте вашему проекту имя, и вы увидите экран параметров для импорта некоторых библиотек JavaScript. Для проекта DZone мы решили использовать iUI, но не стесняйтесь выбирать, какие библиотеки вам удобнее. Когда вы нажмете «Готово», вы увидите, что Aptana начинает создавать ваш проект. После завершения вам будет представлена ​​базовая HTML-страница, содержащая немного CSS и JavaScript. Это хорошая отправная точка и даст вам почувствовать новые инструменты. Вы также заметите, что в нижней части экрана, где раньше использовались источники, Firefox и IE, теперь у вас есть новая вкладка под названием iPhone. Когда HTML-страница все еще открыта, щелкните вкладку iPhone, чтобы увидеть эмуляцию того, как ваша страница будет выглядеть при просмотре на iPhone.

Вы также заметите, что при нажатии на любую из черных пустых областей вокруг iPhone телефон будет вращаться, и ваш макет также будет динамически меняться. Это изменение макета не является автоматическим, но стало возможным благодаря небольшому сценарию, автоматически добавленному на страницу Aptana, который выглядит следующим образом:

addEventListener("load", function(){
setTimeout(updateLayout, 0);
}, false);

var currentWidth = 0;

function updateLayout(){
if (window.innerWidth != currentWidth) {
currentWidth = window.innerWidth;

var orient = currentWidth == 320 ? "profile" : "landscape";
document.body.setAttribute("orient", orient);
setTimeout(function(){
window.scrollTo(0, 1);
}, 100);
}
}

setInterval(updateLayout, 1400);
console.info('iPhone logging initialized');

После того, как я закончил играть с новыми инструментами и, увидев, как работает эмулятор, я решил, что
первое, что я хочу сделать, это отделить структуру от стиля и презентации, я,
конечно, предлагаю вам сделать то же самое, это просто делает для гораздо более удобное в обслуживании приложение в долгосрочной
перспективе. Моим первым шагом было перенести CSS-код, встроенный в страницу, в собственный файл. Я создал новую
папку с именем, вы догадались, это CSS, и создал новый файл CSS и назвал его screen.css. Затем я скопировал весь
CSS со страницы HTML и вставил его в файл CSS. Последним шагом здесь было включить
CSS-файл в HTML-страницу. Так что вам нужно добавить следующий тег на страницу HTML.

<style type="text/css" media="screen">@import "/css/iphone.css";</style>

Далее оставьте следующую строку на странице:

<script type="text/javascript" src="lib/firebug/firebug.js"></script>

Но затем создайте новую папку с именем js и новый файл JavaScript с именем updateLayout.js. Далее идите вперед, скопируйте скрипт и сохраните. Вернувшись на страницу HTML, вам нужно добавить тег, чтобы включить этот новый файл JavaScript, который мы только что создали. Добавьте следующее:

<script type="text/javascript" src="js/updateLayout.js"></script>

Чтобы убедиться, что все по-прежнему работает, как прежде, нажмите на вкладку iPhone. Все должно выглядеть и работать одинаково. Теперь, когда мы подготовили сцену, давайте начнем собирать эту версию DZone для iPhone. Есть несколько сайтов, из которых было выбрано так много, потому что это значительно упрощает создание веб-приложений для iPhone, которые чувствуют себя намного больше • Создание навигационных меню и интерфейсов iPhone из стандартного HTML

  • Использование или знание JavaScript не требуется для создания основных страниц iPhone
  • Возможность обрабатывать изменения ориентации телефона
  • Обеспечьте более «похожий на iPhone» опыт для веб-приложений (на iPhone или без него)

Чтобы мы могли начать использовать iUI, нам нужно включить два файла в раздел head нашего документа. Итак, добавьте следующее:

<style type="text/css" media="screen">@import "lib/iUI/iui.css";</style>
<script type="application/x-javascript" src="lib/iUI/iui.js"></script>

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

<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">

В библиотеке iUI используется несколько соглашений об именах, которые позволяют использовать правила сценариев и стилей. Сначала мы рассмотрим панель инструментов. Внутри тега body добавьте следующее:

<div class="toolbar"></div>

Если вы теперь щелкните на вкладке iphone в Aptana, вы увидите панель, добавленную в верхней части экрана эмулятора:

[Img_assist | NID = 4543 | название = | убывание = | ссылка = нет | Align = нет | ширина = 300 | Высота = 272]

Это стиль по умолчанию, предоставляемый библиотекой iUI для класса CSS панели инструментов. Это было не совсем то, к чему мы стремились, поэтому нам пришлось переопределить это правило стиля в нашем собственном файле iphone.css. С учетом сказанного становится важным, чтобы порядок включенных таблиц стилей был правильным. Как мы знаем, каскад CSS работает сверху вниз, внешний по отношению к встроенному, поэтому важно, чтобы вы включили таблицы стилей следующим образом:

<style type="text/css" media="screen">@import "lib/iUI/iui.css";</style>
<style type="text/css" media="screen">@import "css/iphone.css";</style>

Таким образом, любое правило стиля с тем же именем переопределит то, что было определено в iui.css. Чтобы почувствовать, что мы были после того, как мы изменили стиль панели инструментов следующим образом:

body > .toolbar 
{
background-color:#3366aa;
background-image:none;
box-sizing:border-box;
-moz-box-sizing:border-box;
border-bottom:1px solid #fff;
border-top:1px solid #000;
padding:10px;
height:25px;
}

После того, как вы добавили это правило стиля в файл CSS, вернитесь на вкладку iphone. Теперь вы должны увидеть следующее:

[Img_assist | NID = 4544 | название = | убывание = | ссылка = нет | Align = нет | ширина = 300 | высота = 240]

Теперь нам нужно добавить некоторые элементы в нашу панель инструментов. Давайте добавим логотип DZone на панель инструментов. Для этого мы добавили следующую строку внутри панели инструментов div:

<div class="toolbar">
<a href="/iphone"><h1 id="pageTitle"></h1></a>
<div>

К H1 мы добавили идентификатор с именем pageTitle и применили следующее правило стиля:

#pageTitle
{
background:transparent url('../media/DZone-iphone-137x30.png') top left no-repeat;
margin:0;
padding:0;
background-position:0 0;
height:30px;
}

Теперь, если вы нажмете на вкладку iphone в Aptana, вы не найдете никакой разницы. Почему это? К сожалению, я не имею ни малейшего представления о том, что эмулятор работает лучше, и мне нужно было найти альтернативный подход.
Находясь в Windows, у меня не было возможности установить iPhone SDK от Apple, поскольку в настоящее время он доступен только для Mac, поэтому, за исключением установки VirtualBox и запуска операционной системы Mac внутри него,
мне пришлось искать другую альтернативу. Поскольку Safari — это браузер, который работает на iPhone, а Safari теперь доступен для Windows, я перешел на использование браузера Safari для дальнейшего тестирования.

Однако мне нужно посмотреть, как выглядит макет при том же соотношении сторон экрана iPhone, поэтому я искал веб-эмулятор iPhone. Я нашел iPhoneTester.com, и по большей части он работал
довольно хорошо, но я не мог быть уверен, что то, что этот эмулятор показал мне, было точным. К счастью, один из разработчиков, который работал со мной над этим проектом, имел Mac и установил iPhone SDK. Ситуация не была
идеальной, хотя мы работали удаленно, поэтому мне пришлось отправить ему краткий отчет о проделанной мной работе, а он должен был прислать мне снимки экрана и отзывы о том, что он видел.

Начиная с Safari на Windows, мне нужно немного поболтать и спросить: почему, Apple, у нас нет iPhone SDK для Windows. Если оставить в стороне мою напыщенную речь, это путь, по которому мы пошли дальше. Я просматриваю приложение в Safari для Windows и отправляю ему код, чтобы проверить, было ли то, что я вижу, то, что увидят пользователи с помощью iPhone. Но у нас есть еще одна проблема: простого просмотра приложения в Safari недостаточно, поскольку размер области просмотра браузера на рабочем столе и область просмотра на реальном iPhone сильно отличаются.

Добрые люди из Manning Publishing дали нам главу, чтобы предложить читателям этой статьи бесплатно. Эта глава взята из еще неопубликованной книги «iPhone в действии», которая будет опубликована в декабре 2008 года. Загрузить SDK Programming для веб-разработчиков

Чтобы преодолеть это, я снова загрузил iPhoneTester.com и изменил размер моего браузера Safari до размера экрана эмулятора.

 

[Img_assist | NID = 4545 | название = | убывание = | ссылка = нет | Align = нет | ширина = 300 | высота = 437]

Итак, теперь у нас есть Windows SDK для iPhone под Windows, который может быть не на 100% точным, но дает нам базовое представление о том, чего ожидать, и, надеюсь, менее циклический прием с моим коллегой-разработчиком, на котором установлен настоящий SDK. С нашей настройкой среды давайте добавим еще два элемента на нашу панель инструментов. Затем мы добавляем ссылку для входа на нашу панель инструментов, которая откроет диалоговое окно, в которое пользователи могут войти. Итак, внутри вашей панели инструментов div добавьте:

<a class="login" href="login.html">Login</a>

После добавления CSS в таблицу стилей обновите Safari, чтобы увидеть нашу новую ссылку для входа:

.login
{
position:absolute;
top:0;
right:5px;
-webkit-border-radius:0;
border-width:0 5px 0 5px;
padding:6px 10px;
height:28px;
line-height:28px;
font-size:14px;
font-weight:bold;
color:#fff;
text-shadow:rgba(0, 0, 0, 0.6) 0px -1px 0;
text-decoration:none;
background:none;
}

Идите дальше и нажмите на ссылку для входа. Вы должны быть представлены с этим:

[Img_assist | NID = 4546 | название = | убывание = | ссылка = нет | Align = нет | ширина = 300 | Высота = 339]

Вау! Теперь здесь вы видите некоторую магию iUI, действительно красивого диалогового окна в стиле iPhone. Одна вещь, о которой вы можете подумать: откуда взялась форма? Ну, вам нужно создать и ссылку на него.
Если вы посмотрите на строку, которую мы добавили для ссылки для входа, вы увидите, что она ссылается на страницу с именем login.html. Вот:

<form id="loginForm" class="dialog" method="post" action="/login">
<fieldset>
<h1>Login</h1>
<label class="inside" id="username-label" for="username">
Username...
</label>
<input type="text" id="username" name="side-username" />
<label class="inside" id="password-label" for="password">
Password...
</label>
<input type="password" id="password" name="side-password" /><input class="submitButton" type="submit" value="Login" /><input type="hidden" name="processlogin" value="1" /><input type="hidden" name="returnpage" value="/iphone" />
</fieldset>
</form>

Один важный момент. Страница login.html содержит именно то, что представлено выше, ни больше, ни меньше. Когда вы нажмете на поля имени пользователя или пароля, вы увидите, что фоновый текст остается прямо там Не беспокойтесь, мы рассмотрим это чуть позже. А сейчас давайте продолжим и добавим еще один элемент на панель инструментов. Поскольку существуют различные категории / теги, ссылки публикуются, так как мы хотим, чтобы пользователь мог сузить свой вид только до тех категорий товаров, которые ему интересны. Поэтому далее мы добавляем ссылку категории на панель инструментов. К этому мы добавляем еще одну строку в нашу панель инструментов div, чтобы в итоге:

<div class="toolbar">
<a href="/iphone"><h1 id="pageTitle"></h1></a>
<a class="showPage login" href="login.html">Login</a>
<a class="showPage tags" href="categories.html">Tags</a>
<div>

Здесь мы добавляем класс с именем tags, чтобы разместить нашу новую ссылку там, где мы хотим. Для этого добавьте в свой CSS-файл следующее:

.toolbar .tags {
position: absolute;
top: 0;
right:65px;
-webkit-border-radius: 0;
border-width: 0 5px 0 5px;
padding: 6px 10px;
height: 28px;
line-height: 28px;
font-size: 14px;
font-weight: bold;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0;
text-decoration: none;
background: none;
}

Продолжите и обновите Safari, но перед тем, как щелкнуть ссылку, создайте страницу HTML с именем category.html и добавьте в нее следующий код:

<form id="categoryForm" class="dialog" method="get" action="/iphone">
<fieldset>
<h1>Tags</h1>
<select id="topic" name="topic">
<option value="all" selected="selected">All Stories</option>
<option value="technology">Technology</option>
<option value="apple">Apple</option>
<option value="design">Design</option>
<option value="gadgets">Gadgets</option>
<option value="hardware">Hardware</option>
<option value="tech_news">Tech Industry News</option>
<option value="linux_unix">Linux/Unix</option>
<option value="microsoft">Microsoft</option>
<option value="mods">Mods</option>
<option value="programming">Programming</option>
<option value="security">Security</option>
</select>
<input class="submitButton" type="submit" value="Go" />
</fieldset>
</form>

Конечно, все это жестко запрограммировано, и вы можете захотеть подключить это к своему серверному решению для динамической генерации опций. Теперь идите дальше и нажмите на ссылку «Теги». Как и в форме входа в систему, вы видите диалог запуска:

[Img_assist | NID = 4553 | название = | убывание = | ссылка = нет | Align = нет | ширина = 300 | высота = 436]

Кстати, если вы новичок в этом, вы можете задаться вопросом, теперь, как мне избавиться от диалога? Легко, нажав на любую часть темной области за пределами диалога, вы выйдете из диалогового режима. Итак, теперь, когда у нас есть законченная панель инструментов, нам нужно начать работать над областью содержимого приложения. Мы в основном хотим отобразить список ссылок в популярной очереди, который вы увидите, когда перейдете на dzone.com с помощью браузера на своем компьютере. Однако из-за размера экрана мы должны ограничивать количество ссылок на страницу, и вместо «бесконечной прокрутки», используемой в DZone, нам нужно было осуществлять разбиение на страницы между каждым набором ссылок.

Чтобы начать создавать наш контент, добавьте следующее в ваш файл index.html после заключительного div нашей панели инструментов:

<ul id="stories" selected="true">
<li>
<a href="#6983724" class="zone-count">141</a>
<a href="#6983724" class="link">Redefining Anti-Virus Software</a>
</li>
</ul>

После добавления этого вперед и обновите браузер. Вы должны увидеть следующее:

[Img_assist | NID = 4548 | название = | убывание = | ссылка = нет | Align = нет | ширина = 300 | высота = 238]

Это базовый стиль, применяемый инструментарием iUI для неупорядоченных списков. Как упоминалось ранее, это отражает естественный внешний вид других приложений на iPhone. Основы этого хороши, но нам нужно было немного подстроить их под наши нужды. Первая остановка — переопределить стиль, применяемый iUI для ссылок внутри элемента списка. Добавьте следующее в ваш файл iphone.css:

body > ul > li > a 
{
display: block;
margin: -8px 0 -8px -10px;
padding: 8px 32px 8px 15px;
text-decoration: none;
color: inherit;
font-size:70%;
background: url(../lib/iUI/listArrow.png) no-repeat right center;
height:30px;
}

Это изменяет размер текста нашей ссылки на более управляемый размер и позволяет нам добавлять больше ссылок на страницу, как мы могли бы с большим размером текста. Далее нам нужно добавить правила стиля для нашего класса count-count:

li .zone-count
{
background:transparent url('http://dzone.com//links/themes/iphone/media/vwidget2_bkgd_on.gif') top left no-repeat;
color:#000;
float:left;
margin-right:3px;
padding-top:7px;
text-align:center;
font-size:70%;
font-weight: bold;
text-decoration: none;
width:29px;
height:40px;
}

ПРИМЕЧАНИЕ. Если вы читаете эту статью, используя iPhone SDK на Mac, вам может потребоваться немного изменить размеры в пикселях, поскольку Safari на рабочем столе не отображает элементы точно так же, как Safari на iPhone. Это была одна из головных болей, с которыми нам пришлось столкнуться, так как я делал интерфейс на Windows и не имел доступа к SDK.

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

body > ul > li > a 
{
display: block;
padding: 15px 32px 8px 15px;
text-decoration: none;
color: inherit;
font-size:70%;
background: url(../lib/iUI/listArrow.png) no-repeat right center;
height:23px;
}

Также продолжайте, и внутри вашего HTML-файла создайте около пяти копий текущего элемента списка. Обновите свой браузер, вы должны увидеть следующее:

[Img_assist | NID = 4549 | название = | убывание = | ссылка = нет | Align = нет | ширина = 300 | высота = 336]

Теперь это не выглядит плохо на всех. Прежде чем мы перейдем к переходу на страницу истории, давайте добавим нумерацию страниц, о которой я говорил ранее. Добавьте следующее в конец нашего текущего неупорядоченного списка:

<li class="pagination">
<a class="next" target="_self" href="?p=2">Page 2</a>
</li>

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

<a class="previous" target="_self" href="?p=1" class="next">Page 1</a>

Ваш список нумерации страниц теперь должен выглядеть так:

<li class="pagination">
<a class="previous" target="_self" href="?p=1" class="next">Page 1</a>
<a class="next" target="_self" href="?p=2">Page 2</a>
</li>

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

body > ul > li.pagination 
{
position: relative;
margin:5px 0;
border-bottom:none;
padding: 8px 0 8px 10px;
font-size: 20px;
font-weight: bold;
list-style: none;
}

Для предыдущей ссылки нам нужно добавить следующее в наш CSS-файл:

.previous
{
float:left;
background:transparent url('http://dzone.com//links/themes/iphone/media/nav_left_blue_36.png') top left no-repeat;
margin-left:5px;
padding:6px 5px 0 40px;
font-size:110%;
height:36px;
}

И для нашей следующей кнопки нам нужно следующее:

.next
{
float:right;
background:transparent url('http://dzone.com/links/themes/iphone/media/nav_right_blue_36.png') top right no-repeat;
margin-right:15px;
padding:6px 45px 0 5px;
font-size:110%;
height:36px;
}

После всего этого обновите ваш браузер, и вы должны увидеть следующее:

[Img_assist | NID = 4550 | название = | убывание = | ссылка = нет | Align = нет | ширина = 300 | высота = 437]

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

Теперь давайте добавим историю. Сначала мы создали страницу story.html и связались с этой страницей, чтобы отобразить содержание истории, но в итоге мы решили вернуться к стилю одной страницы, который используется большинством других сайтов iPhonized.
придерживались. Мы можем изменить это по мере продвижения вперед или нет. Во всяком случае, для целей этой статьи я буду придерживаться концепции одной страницы. Внутри вашего index.html после закрывающего тега неупорядоченного списка добавьте следующее:

<div id="103776" title="">                               
<div class="story-body">
<h3><a target="_self" href="http://timeago.yarp.com/">timeago: a jQuery plugin</a></h3>
<p class="details">Timeago is a jQuery plugin that makes it easy to support automatically updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").</p>
</div>
</div>

Убедитесь, что ссылка на ваш сайт ссылается на # 103776, чтобы ваши ссылки работали как положено. Давай, я знаю, ты хочешь. Нажмите на одну из ссылок и посмотрите, что произойдет. Довольно круто, я думаю, мне нравится эффект скользящего перехода благодаря iUI. Прежде чем мы добавим наш стиль для страницы истории, давайте посмотрим, как именно работает этот переход. В строке 150 файла iui.js, расположенного в lib> iUI, вы увидите следующую строку:

addEventListener("click", function(event)

Итак, вот где слушатель событий добавляется для событий щелчка, например, когда вы нажимаете на ссылку. Когда щелчок произошел, этот слушатель был уведомлен, и он вступил в действие. Первое, что нам нужно, это хеш текущего узла, который инициировал событие click:

var link = findParent(event.target, "a");

Здесь мы присваиваем значение, возвращаемое функцией findParent ссылке на переменную. Вот как выглядит функция:

function findParent(node, localName)
{
while (node && (node.nodeType != 1 || node.localName.toLowerCase() != localName))
node = node.parentNode;
return node;
}

Когда мы входим в эту функцию из события click, возникшего в результате привязки ссылки, первая проверка в цикле while пройдет, но наш текущий nodeType равен 1, а наше localName равно «a», поэтому оба условия внутри скобок не будут выполнены, что приведет к скрипт, чтобы выскочить из цикла while и просто вернуть узел и присвоить его ссылке var. Далее мы перепрыгиваем через первое выражение if, но переходим ко второму:

if (link.href && link.hash && link.hash != "#")
{
link.setAttribute("selected", "true");
iui.showPage($(link.hash.substr(1)));
setTimeout(unselect, 500);
}

Первое, что делает этот скрипт, устанавливает значение атрибута selected в true. Если вы выполните этот сценарий, вы увидите, что после выполнения этой строки цвет фона ссылки изменится на синий. Следующая строка вызывает функцию, которая создает эффект скользящего перехода. Мы вызываем функцию showPage, передавая элемент, с которого мы ссылаемся. Мы вызываем небольшую служебную функцию, чтобы получить этот элемент для нас на основе идентификатора. Так что в нашем случае мы делаем следующее:

iui.showPage($(103776));

Функция полезности выглядит так и не требует пояснений:

function $(id) { return document.getElementById(id); }

Это вернет наш DIV, содержащий историю, на которую мы ссылаемся. Далее мы передаем эту функцию showPage, перечисленную ниже:

showPage: function(page, backwards)
{
if (page)
{
if (currentDialog)
{
currentDialog.removeAttribute("selected");
currentDialog = null;
}

if (hasClass(page, "dialog"))
showDialog(page);
else
{
var fromPage = currentPage;
currentPage = page;

if (fromPage)
setTimeout(slidePages, 0, fromPage, page, backwards);
else
updatePage(page, fromPage);
}
}
}

Когда мы введем скрипт, здесь «назад» будет не определено, а «страница» будет содержать содержимое нашего DIV. Наше первое условие проходит, и мы входим в блок условий и следующий условный оператор. Если вы посмотрите на верхнюю часть файла uiu.js, вы увидите, что ‘currentDialog’ инициализируется нулем, и, поскольку мы не запускаем здесь диалог, это то, чем он все еще будет, поэтому это условие не будет выполнено, и мы переместимся к следующему условию. Это условие снова не будет выполнено, так как наш текущий узел не содержит класс с именем ‘dialog’, после чего мы переходим к другому.

Когда мы переходим в блок else, первой задачей скрипта является инициализация переменной fromPage со значением currentPage. Затем мы перезаписываем значение currentPage значением нашей страницы истории. Затем скрипт проверяет, является ли fromPage нулевым и, если нет, перемещается в функцию setTimeout, вызывающую функцию slidePages. Поскольку вызов setTimeout вызывается с временем ожидания 0 миллисекунд, сценарий slidePages будет ожидать выполнения до тех пор, пока текущий стек вызовов не завершит свое выполнение. Отсюда мы возвращаемся к слушателю событий и выполняем следующую строку:

setTimeout(unselect, 500);

Функция отмены выбора выглядит следующим образом:

function unselect() { link.removeAttribute("selected"); }

Поэтому после 500 миллисекундного ожидания функция отмены выбора удалит наш атрибут selected и вызовет следующую функцию, чтобы остановить действие по умолчанию, которое браузер предпринял бы для этого события:

event.preventDefault();

Покинув обработчик события, вызывается функция, которая проверит, изменилась ли ориентация и / или местоположение, и внесет необходимые изменения. Эта служебная функция выглядит следующим образом:

function checkOrientAndLocation()
{
if (window.innerWidth != currentWidth)
{
currentWidth = window.innerWidth;
var orient = currentWidth == 320 ? "profile" : "landscape";
document.body.setAttribute("orient", orient);
setTimeout(scrollTo, 100, 0, 1);
}

if (location.hash != currentHash)
{
var pageId = location.hash.substr(hashPrefix.length)
iui.showPageById(pageId);
}
}

В нашем текущем сценарии оба условных блока пропускаются, и функция checkOrientAndLocation закрывается без выполнения какого-либо кода. Когда мы выходим из этого блока кода, текущий стек вызовов завершается, а функция slidePages и выполняется, вот как выглядит эта функция:

function slidePages(fromPage, toPage, backwards)
{
var axis = (backwards ? fromPage : toPage).getAttribute("axis");
if (axis == "y")
(backwards ? fromPage : toPage).style.top = "100%";
else
toPage.style.left = "100%";

toPage.setAttribute("selected", "true");
scrollTo(0, 1);
clearInterval(checkTimer);

var percent = 100;
slide();
var timer = setInterval(slide, slideInterval);

function slide()
{
percent -= slideSpeed;
if (percent <= 0)
{
percent = 0;
if (!hasClass(toPage, "dialog"))
fromPage.removeAttribute("selected");
clearInterval(timer);
checkTimer = setInterval(checkOrientAndLocation, 300);
setTimeout(updatePage, 0, toPage, fromPage);
}

if (axis == "y")
{
backwards
? fromPage.style.top = (100-percent) + "%"
: toPage.style.top = percent + "%";
}
else
{
fromPage.style.left = (backwards ? (100-percent) : (percent-100)) + "%";
toPage.style.left = (backwards ? -percent : percent) + "%";
}
}
}

Это, наконец, сценарий, который будет вызывать приятный переходный эффект скольжения в нашем новом контенте вместо загрузки новой страницы или, в нашем случае, перехода к контенту, как это обычно бывает с якорными ссылками. После выполнения первой строки ось var равна нулю. Это означает, что наш первый условный блок будет пропущен, так как «ось» не равна «у», вместо этого «toPage», который является нашей историей DIV, получает левую позицию, которая на 100% левее нашего экрана. Это поместит наш DIV только на экране справа от нашего списка ссылок. Контенту присваивается выбранный атрибут и устанавливается значение true, после чего контент прокручивается вверх, чтобы получить его в позиции для перехода.

Когда документ был загружен изначально, мы вызвали функцию checkOrientAndLocation с помощью setTimeout и присвоили идентификатор этого таймера переменной checkTimer, теперь мы используем этот идентификатор, чтобы очистить интервал таймеров и предотвратить запуск таймера сценарием. Затем мы инициализируем «процент» равным 100 и вызываем функцию slide (). Функция slide делает для нас две вещи: с каждой итерацией она уменьшает значение процентов на 20% и увеличивает значение style.left, установленное для fromPage, на 20%. Это означает, что после пяти итераций мы бы поменялись ссылками с содержанием истории. Единственное, чего не следует делать, это то, что после первой итерации мы запускаем таймер для выполнения функции слайда со временем ожидания 0, помните, что это значит.

В последний раз, когда мы выполняем метод slide и процент равен 0, мы выполняем этот блок:

if (percent <= 0)
{
percent = 0;
if (!hasClass(toPage, "dialog"))
fromPage.removeAttribute("selected");

clearInterval(timer);

checkTimer = setInterval(checkOrientAndLocation, 300);

setTimeout(updatePage, 0, toPage, fromPage);
}

Здесь происходит кое-что действительно умное. Итак, первое, что iUI делает для нас после столь изящного перемещения контента историй на место, — это остановка таймера, который выполнял функцию слайда. Затем он повторно инициализирует функцию checkOrientAndLocation для выполнения каждые 300 миллисекунд и сохраняет идентификатор в переменной checkTimer. Наконец, он запускает новый таймер, вызывающий функцию updatePage с временем ожидания 0 секунд. Итак, как и прежде, помните, что это значит, текущий исполняющий стек завершится, после чего будет выполнена функция updatePage. Когда страница обновления выполняется, это код, который выполняется:

function updatePage(page, fromPage)
{
if (!page.id)
page.id = "__" + (++newPageCount) + "__";

location.href = currentHash = hashPrefix + page.id;
pageHistory.push(page.id);

var pageTitle = $("pageTitle");
if (page.title)
pageTitle.innerHTML = page.title;

if (page.localName.toLowerCase() == "form" && !page.target)
showForm(page);

var backButton = $("backButton");
if (backButton)
{
var prevPage = $(pageHistory[pageHistory.length-2]);
if (prevPage && !page.getAttribute("hideBackButton"))
{
backButton.style.display = "inline";
backButton.innerHTML = prevPage.title ? prevPage.title : "Back";
}
else
backButton.style.display = "none";
}
}

Еще одна причина использования iUI заключается в том, что он помогает нам сохранить нашу историю нетронутой и позволяет пользователям свободно использовать кнопку «Назад» на телефоне для целей навигации, если никакие другие средства не предусмотрены или пользователь просто предпочитает это. И это в updatePage, где это происходит. Первое, что он делает в нашем случае, это обновляет href в адресной строке до #_ и идентификатора нашей текущей страницы, которая в настоящее время равна 103776. Затем добавляется этот идентификатор страницы в pageHistory []. Затем он будет искать идентификатор pageTitle и установить для заголовка нового документа значение заголовка этого элемента или пропустить его, если нет элемента с таким идентификатором или он пуст. И это все, остальное пропускается, так как мы не работаем с формой или не используем ссылку с идентификатором backButton.

Теперь, когда наш контент проскальзывает в поле зрения, когда мы нажимаем на ссылку, нам нужно стилизовать наш контент и добавить некоторые дополнительные поля и обратную ссылку, чтобы вернуться к нашим ссылкам. Сначала давайте стилизуем контент, который уже присутствует. Добавьте следующее в свою таблицу стилей CSS для стилизации H3 и абзаца:

.story-body h3 
{
margin:10px auto 7px 10px;
font-size:22px;
line-height:1em;
}
.story-body h3 a
{
margin:0;
padding:0;
text-decoration:none;
}
.details, .details p
{
margin:0;
margin-left:10px;
padding:0 5px 10px 0;
font-size:90%;
line-height:140%;
}

Далее давайте добавим еще некоторые подробности о публикации, такие как дата, просмотры, отправитель и т. Д. Для этого мы будем использовать неупорядоченный список, поэтому добавим следующее в основной текст статьи DIV:

<ul class="news-details">
<li>Published: Aug 16 / 11:44.</li>
<li>Views: 327, Clicks: 161, Score: 21.1</li>
<li>Via: <a href="/links/search.html?query=domain:timeago.yarp.com">timeago.yarp.com</a></li>
<li>Tags: <a href="/links/iphone?t=frameworks" target="_self" class="tags" rel="tag">frameworks</a>, <a href="/links/iphone?t=javascript" target="_self" class="tags" rel="tag">javascript</a></li>
<li>Submitter: <a class="user" href="/links/users/profile/111696.html">bloid</a></li>
</ul>

И следующее для вашего CSS-файла, чтобы стилизовать наш список:

.news-details
{
background-color:#fff;
color:#666;
margin:15px 0 0 10px;
padding:0;
font-size:12px;
line-height:150%;
list-style-type:none;
}

Если вы сейчас вернетесь к истории и перезагрузите ее, вы увидите нечто похожее на следующее:

[Img_assist | NID = 4551 | название = | убывание = | ссылка = нет | Align = нет | ширина = 300 | Высота = 326]

Хорошо смотритесь! Нам все еще нужно добавить кнопку «Назад» на этот экран, поэтому давайте продолжим и сделаем это сейчас. После закрывающего тега DIV для body-body, но до заключительного закрывающего DIV добавьте следующее:

<p><a href="#stories" target="_self" class="previous">Back to Links</a></p>

Больше ничего не нужно, стиль уже был добавлен ранее, когда мы добавили предыдущую ссылку на наши элементы навигации по страницам. Прежде чем закрыть эту статью, я хочу кое-что вам рассказать. Нажмите на ссылку для входа еще раз, а затем щелкните внутри текстового поля, чтобы добавить свое имя пользователя и / или пароль. Что здесь не так? Да, точка вставки почти на половину длины текстовой области, и текст «фона» не исчезает при нажатии или даже вводе текста в этом поле. Давайте решим эти проблемы, и пока мы это делаем, давайте ужесточим внешний вид обоих наших диалогов.

Добавьте следующие стили для набора полей и набора полей H1 наизнанку:

fieldset 
{
box-sizing:border-box;
width:100%;
margin:0;
border:none;
padding:10px 6px;
background-color:#7388a5;
}
fieldset > h1 {
margin: 0 10px 0 10px;
padding: 0;
font-size: 20px;
font-weight: bold;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0;
text-align: center;
}

Чтобы позаботиться о наших ярлыках и полях ввода, нам нужно следующее CSS:

label 
{
font-size: 14px;
text-align: left;
display: block;
margin: 5px 0 2px 4px;
font-weight: bold;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0;
}
label.inside
{
position: absolute;
margin: 14px 0 0 15px;
color: #BBB;
text-shadow: none;
}
input[type='text'], input[type='password']
{
width:95%;
font-size: 16px;
}
input
{
padding:5px 0 5px 3px;
box-sizing: border-box;
margin-right:20px;
font-size: 17px;
font-weight: normal;
}

На этом этапе вы можете обновить браузер и проверить поля ввода логина. Намного лучше, верно? Фоновый текст все еще там, хотя, мы позаботимся об этом через секунду. Давайте уточним остальные элементы диалога. Для бутонов и выпадающего списка добавьте следующее в ваш CSS файл:

select
{
margin-right:20px;
width:90%;
font-size:16px;
}
input[type='submit']
{
float: right;
margin-top: 0;
margin-right: 20px;
width:100px;
}

Ваш диалог не должен выглядеть намного лучше и напоминать следующий экран: (помните, если вы используете реальный iPhone или SDK на Mac, вам может потребоваться настроить некоторые размеры, чтобы получить тот же результат)

[Img_assist | NID = 4547 | название = | убывание = | ссылка = нет | Align = нет | ширина = 300 | высота = 267]

Осталось только одно — избавиться от раздражающего фонового текста внутри полей имени пользователя и пароля. Для этого мы добавим JQuery совершенство. Создайте новый файл в папке js и назовите его iphone.js. Добавьте следующий фрагмент кода в этот файл и нажмите «Сохранить»:

$(document).ready(function(){
$('#username, #password').focus(function(){
$('#' + $(this).attr('id') + '-label').hide();
})
});

Теперь в заголовке страницы index.html добавьте следующее, чтобы добавить файл JavaScript на нашу страницу:

<script type="application/x-javascript" src="js/iphone.js"></script>

Если у вас еще нет jQuery, тогда скачайте jQuery , сохраните файл в папку js и добавьте в заголовок следующее перед строкой iphone.js:

<script type="application/x-javascript" src="js/jquery.js"></script>

Теперь обновите браузер, запустите диалог входа в систему и протестируйте эти элементы формы. Какая? Это все еще не уходит? Не волнуйтесь, есть две маленькие вещи, которые мы должны изменить в нашей текущей настройке, чтобы заставить это работать. В разделе панели инструментов страницы index.html измените ссылку на форму входа следующим образом:

<a class="login" href="#loginForm">Login</a>

Скопируйте код из файла login.html в index.html сразу после закрытия DIV истории. Сохраните все и обновите браузер снова. На этот раз, когда вы щелкаете внутри полей имени пользователя или пароля, фоновый текст исчезает. И это все! Вот как мы получили DZone на iPhone. Есть еще некоторые улучшения, которые мы хотели бы внести, и эта статья не охватывает, как серверная часть была подключена к этому интерфейсу, но я уверен, что большинство из вас может понять это, поскольку не должно быть большой разницы, если таковые имеются, то то, как вы в настоящее время делаете это с приложениями для настольного браузера. Надеюсь, вам понравилась эта статья, вы нашли ее полезной, узнали что-то новое и начнете создавать свои собственные версии для iPhone с использованием iUI. Мы рекомендуем вам использовать версию DZone для iPhone по адресуhttp://dzone.com/iphone и отправьте нам свой отзыв о том, как мы можем улучшить то, что у нас уже есть и что вы хотели
бы видеть в будущих версиях.