В этой серии мы разработаем клиент Twitter с использованием фреймворков jQuery Mobile и PhoneGap.  Этот проект будет развернут в среде Android и iOS как собственное приложение.   Пользовательский интерфейс приложения, называемый просто «твиты», будет построен с использованием jQuery Mobile, а PhoneGap будет использоваться для создания нативного приложения.  Мы также будем использовать PhoneGap Storage API для доступа к собственным функциям базы данных.  Все кодирование будет выполняться с использованием HTML и JavaScript с использованием библиотек jQuery, jQuery Mobile и PhoneGap. 
Также доступно в этой серии:
- Создание кроссплатформенного клиента Twitter: обзор
 - Создайте кроссплатформенный клиент Twitter: API Twitter и обзор кода
 - Создайте кроссплатформенный клиент Twitter: завершение обзора кода
 - Создание кроссплатформенного клиента Twitter: развертывание
 
Организация части III этой серии
 Во второй части мы начали рассмотрение приложения Tweets.  В «Обзоре index.html» основное внимание было уделено статической структуре кода HTML и jQuery Mobile, которые составляют экраны приложений.  Раздел под названием «Twitter API» дал обзор методов Twitter API user_timeline и search .  В следующем разделе «Проверка кода» был дан обзор кода JavaScript, который реализует функциональность приложения.  Во второй части обсуждались «Начальная загрузка страницы», «Функции утилит», «Функции доступа к базе данных» и началось обсуждение «Основных функций бизнес-логики». 
В части III мы продолжим проверку «основных функций бизнес-логики», начиная с того места, которое мы оставили в части II, и завершим проверку кода приложения Tweets, изучив «Обработчики событий» и «Функции отображения страницы».
Обзор кода — основные функции бизнес-логики (продолжение)
  Функция storeCurrentInput() 
  storeCurrentInput() отвечает за итерацию по текущему представлению списка поисковых терминов и имен экранов, создание разделенной запятыми строки, состоящей из этих записей, и передачу этих записей в putInputsIntoStorage() в качестве параметра.  Затем функция putInputsIntoStorage() использует API базы данных PhoneGap для хранения этих записей в локальной базе данных.  Ниже приведены константы, используемые в этой функции. 
| 
 1 
2 
3 
4 
5 
 | 
 var EMPTY = »; 
var LI = ‘li’; 
var ID = ‘id’; 
var COMMA = ‘,’; 
var PREFIX = ‘^’; 
 | 
Ниже приведен полный список функций.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
 | 
 function storeCurrentInput(){ 
  var tmp = EMPTY; 
  currentInputsVar.find(LI).each(function(){ 
    var plainId = $(this).attr(ID); 
    if(plainId.match(/_d_li_s$/)){ 
      tmp = tmp + COMMA + PREFIX +$(this).attr(ID).substring(5,$(this).attr(ID).length-7); 
    }else{ 
      tmp = tmp + COMMA + $(this).attr(ID).substring(5,$(this).attr(ID).length-5); 
    } 
  }); 
  if(tmp.length < 1){ 
    putInputsIntoStorage(tmp); 
  }else{ 
    putInputsIntoStorage(tmp.substring(1)); 
  } 
} 
 | 
  Переменная tmp будет хранить разделенный запятыми список имен и условий поиска.  Изначально это пустая строка.  Обратите внимание, что глобальная переменная currentInputsVar указывает либо на представление списка с id='currentInputs' (устройство с узким экраном) или id='currentInputsCell' (устройство с широким экраном).  Используя функции jQuery find() и each() , мы перебираем список.  Переменная plainId устанавливается plainId значению атрибута id текущего элемента списка.  Из обзора addInput() атрибут id всегда начинается с nput_ .  Если используется _d_li_s поиска, атрибут id заканчивается на _d_li_s , например, id='nput_fortlauderdale_d_li_s' .  Если имя экрана, оно заканчивается на _d_li , например, id='nput_SunSentinel_d_li' . 
  Если значение является поисковым термином, мы удаляем первые 5 символов nput_ и последние 7 символов _d_li_s из значения атрибута id , добавляем префикс ^ и добавляем полученную строку в переменную tmp после ‘,’.  Например, если id='nput_fortlauderdale_d_li_s' тогда мы добавляем ,^fortlauderdale к tmp .  Аналогично, если это экранное имя, мы удаляем первые 5 символов nput_ и последние 5 символов _d_li из значения атрибута id и добавляем полученную строку в переменную tmp после символа ‘,’.  Например, если id='nput_SunSentinel_d_li' , тогда мы добавляем ,SunSentinel в tmp . 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
 | 
 function storeCurrentInput(){ 
  var tmp = EMPTY; 
  currentInputsVar.find(LI).each(function(){ 
    var plainId = $(this).attr(ID); 
    if(plainId.match(/_d_li_s$/)){ 
      tmp = tmp + COMMA + PREFIX +$(this).attr(ID).substring(5,$(this).attr(ID).length-7); 
    }else{ 
      tmp = tmp + COMMA + $(this).attr(ID).substring(5,$(this).attr(ID).length-5); 
    } 
  }); 
  … 
 | 
  После того, как итерации завершены, у нас есть строковая переменная tmp для передачи в putInputsIntoStorage() .  Если tmp — пустая строка, то есть список поисковых терминов и имен экранов пуст, то мы передаем putInputsIntoStorage() в пустую строку (это все еще необходимо, потому что putInputsIntoStorage() очистит локальную базу данных при вызове с пустым строка).  Если значение не является пустой строкой, первым символом в tmp является ‘,’ и, следовательно, мы удаляем его перед передачей значения tmp в putInputsIntoStorage() . 
| 
 1 
2 
3 
4 
5 
6 
7 
 | 
   … 
  if(tmp.length < 1){ 
    putInputsIntoStorage(tmp); 
  }else{ 
    putInputsIntoStorage(tmp.substring(1)); 
  } 
} 
 | 
  Функция getTweets() 
  Функция getTweets() выполняет вызов ajax() API Twitter для получения твитов на временной шкале пользователя.  В функцию передаются два параметра: отображаемое имя пользователя, временная шкала которого будет запрошена, и имя функции для обработки ответа от вызова ajax() .  Список кодов для функции приведен ниже. 
| 
 1 
2 
3 
4 
5 
 | 
 function getTweets(varUsr,handler){ 
  var params = {screen_name:varUsr}; 
  requestObject = $.ajax({dataType: XML, url: TWEETS_URI, data: params, success: handler}); 
  return false; 
} 
 | 
  Первым шагом является создание массива, в котором экранное имя передается как значение параметра с именем screen_name .  Затем, используя функцию jQuery ajax() , мы вызываем API Twitter.  TWEETS_URI — это константа, которая определяется как: 
| 
 1 
 | 
 TWEETS_URI=’http://api.twitter.com/1/statuses/user_timeline.xml’ 
 | 
  Например, если параметр varUsr имеет значение SunSentinel , запрос get, соответствующий приведенному выше вызову ajax() становится: 
| 
 1 
 | 
 http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=SunSentinel 
 | 
  Функция возвращается после выполнения вызова ajax() .  Результат вызова ajax() , который по своей природе является асинхронным, будет обработан функцией-обработчиком, переданной в качестве значения handler параметра.  Глобальная переменная requestObject установлена для объекта jQuery XMLHttpRequest возвращаемого из вызова ajax() .  Переменная requestObject будет использоваться при необходимости для прерывания вызова ajax() (см. Обзор buttonProgShowInputsVar.click() ). 
  Функция getSearch() 
  Функция getSearch() похожа на getTweets() .  Он выполняет вызов ajax() в API поиска Twitter, чтобы получать твиты от любого пользователя, содержимое которого соответствует поисковому запросу.  В функцию передаются два параметра: поисковый запрос и имя функции для обработки ответа от вызова ajax() .  Список кода для функции приведен ниже: 
| 
 1 
2 
3 
4 
5 
 | 
 function getSearch(searchTerm,handler){ 
  var params = {q:searchTerm}; 
  requestObject = $.ajax({dataType: TEXT, url: SEARCH_URI, data: params, success: handler}); 
  return false; 
} 
 | 
  Первым шагом является создание массива, в котором поисковый термин передается как значение параметра с именем q .  Затем, используя функцию JQuery ajax() , мы вызываем API поиска в Twitter.  SEARCH_URI является константой, определенной как: 
| 
 1 
 | 
 SEARCH_URI=’http://search.twitter.com/search.json’ 
 | 
  Например, если параметр searchTerm имеет значение fortlauderdale , тогда запрос get, соответствующий приведенному выше вызову ajax() становится: 
| 
 1 
 | 
 http://search.twitter.com/search.json?q=fortlauderdale 
 | 
  Функция возвращается после выполнения вызова ajax() .  Результаты вызова ajax() , который по своей природе является асинхронным, будут обрабатываться функцией-обработчиком, передаваемой как значение handler параметра. 
  Функция populateTweetItems() 
  populateTweetItems() отвечает за анализ XML, отправленного API Twitter в ответ на запрос user_timeline , извлечение содержимого сообщения из ответа и, наконец, создание таблицы HTML для отображения этого содержимого.  Текст XML является входным параметром функции. 
  Ниже приведен пример текста XML, отправляемого API Twitter в ответ на запрос user_timeline , где мы показываем только контент, относящийся к нашему приложению: 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
 | 
 <?xml version=»1.0″ encoding=»UTF-8″?> 
<statuses type=»array»> 
  <status> 
    <created_at>Sat Oct 08 18:44:37 +0000 2011</created_at> 
    … 
    <text>Check out a photo gallery of South Floridians braving the storm Saturday: http://t.co/a5rEUND5</text> 
    … 
  </status> 
  <status> 
    <created_at>Sat Oct 08 12:30:29 +0000 2011</created_at> 
    … 
    <text>Wind, rain could pose threats Saturday in South Florida: http://t.co/YMt8AQyW</text> 
    … 
  </status> 
  … 
</statuses> 
 | 
  Приведенный выше XML-код является ответом на http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=SunSentinel где SunSentinel — псевдоним южнофлоридской газеты Sun Sentinel.  Как и многие другие медиа-организации, Sun Sentinel часто публикует последние новости в Twitter.  С каждым новостным сообщением предоставляется URL-ссылка с дополнительной информацией о новостях на их веб-сайте. 
Константы, используемые в функции, приведены ниже:
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
 | 
 var EMPTY = »; 
var STATUS = ‘status’; 
var WHEN = ‘created_at’; 
var SPACE = ‘ ‘; 
var TEXT = ‘text’; 
var HTML_FRG7 = ‘<tr><td>’; 
var HTML_FRG8 = ‘<hr></hr></td></tr>’; 
var EM1 = ‘<em>’; 
var EM2 = ‘</em> ‘; 
var MAX_TWEETS = 11; 
var TABLE_OPEN = ‘<table STYLE=»border-spacing: 10pt 0pt»>’; 
var TABLE_CLOSE = ‘</table>’; 
 | 
  Полный листинг кода для populateTweetItems() приведен ниже. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
 | 
 function populateTweetItems(xml){ 
  var tmpTxt = EMPTY; 
  var indx = 0; 
  $(xml).find(STATUS).each(function(){ 
    var when = $(this).find(WHEN).first().text().split(SPACE,4).join(SPACE); 
    var txt = $(this).find(TEXT).text(); 
    tmpTxt = tmpTxt + HTML_FRG7 + EM1 + when + EM2 + addHref(txt) + HTML_FRG8; 
    if(++indx >= MAX_TWEETS){ 
      return false; 
    } 
  }); 
    resultsVar.html(TABLE_OPEN + tmpTxt + TABLE_CLOSE); 
  showResults(); 
} 
 | 
  Функция tmpTxt populateTweetItems() начинается с определения двух переменных, tmpTxt и indx .  Синтаксический анализ XML-текста выполняется с помощью API jQuery.  Фрагмент кода $(xml).find(STATUS).each() извлекает каждый экземпляр элемента <status> из XML.  Внутренняя функция передается в функцию each() для дальнейшей обработки элемента <status> . 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
 | 
   … 
  $(xml).find(STATUS).each(function(){ 
    var when = $(this).find(WHEN).first().text().split(SPACE,4).join(SPACE); 
    var txt = $(this).find(TEXT).text(); 
    tmpTxt = tmpTxt + HTML_FRG7 + EM1 + when + EM2 + addHref(txt) + HTML_FRG8; 
    if(++indx >= MAX_TWEETS){ 
      return false; 
    } 
  }); 
  … 
} 
 | 
  Выражение $(this).find(WHEN).first().text().split(SPACE,4).join(SPACE) извлекает элемент <created_at> из <status> , анализирует первые четыре токена, а затем устанавливает переменную named в строку, состоящую из этих токенов.  Формат <created_at> выглядит следующим образом: 
- Первый токен: день недели (например, суббота)
 - Второй токен: месяц года (например, октябрь)
 - Третий токен: день месяца (например, 08)
 - Четвертый токен: HH24: MM: SS (например, 18:44:37, время в 24-часовом формате)
 - Пятый токен: местное дифференциальное время от GMT (например, +0000)
 - Шестое: год (например, 2011)
 
  Например, если значение <created_at> равно Sat Oct 08 18:44:37 +0000 2011 , то значение переменной становится Sat Oct 08 18:44:37 .  Для простоты мы игнорируем год и разницу с часовым поясом GMT в этой серии уроков. 
  Выражение $(this).find(TEXT).text() извлекает значение элемента <text> .  Это текстовое содержание статуса (твит).  Переменная с именем txt установлена в значение элемента <text> .  Затем мы строим строку таблицы HTML, используя переменные when и txt .  addHref() функция addHref() обрабатывает переданный ей текст и помещает любой URL, начинающийся с http:// внутри тега <a> .  В качестве примера рассмотрим следующий фрагмент: 
| 
 1 
2 
3 
 | 
 <created_at>Sat Oct 08 18:44:37 +0000 2011</created_at> 
  … 
<text>Check out a photo gallery of South Floridians braving the storm Saturday: http://t.co/a5rEUND5</text> 
 | 
Выражение ниже:
| 
 1 
 | 
 HTML_FRG7 + EM1 + when + EM2 + addHref(txt) + HTML_FRG8; 
 | 
будет выглядеть так:
| 
 1 
2 
3 
 | 
 <tr><td><em>Sat Oct 08 18:44:37</em> 
  Check out a photo gallery of South Floridians braving the storm Saturday: 
  <a href=’http://t.co/a5rEUND5′>http://t.co/a5rEUND5</a><hr></hr></td></tr> 
 | 
Выше разбито на несколько строк для удобства чтения, оригинальное выражение представляет собой одну строку.
  Затем он добавляется к текущему значению tmpTxt . 
  Выражение ниже ограничивает обработку элементов <status> (твитов) значением константы MAX_TWEETS , которое определяется как 11. 
| 
 1 
2 
3 
 | 
 if(++indx >= MAX_TWEETS){ 
  return false; 
} 
 | 
  Последние 2 строки populateTweetItems() выглядят следующим образом: 
| 
 1 
2 
3 
 | 
 … 
resultsVar.html(TABLE_OPEN + tmpTxt + TABLE_CLOSE); 
showResults(); 
 | 
  Для устройств с узким экраном resultsVar — это переменная, указывающая на элемент <div> с id='contentResults' .  Для широкоэкранных устройств resultsVar — это переменная, указывающая на элемент <div> с id='resultsCell' .  Мы определяем таблицу и устанавливаем ранее построенные строки в качестве ее содержимого.  Затем мы resultsVar таблицу в элемент <div> ссылается resultsVar .  Наконец, мы вызываем showResults() для отображения страницы результатов (для широкоэкранных устройств showResults() будет работать). 
  Функция populateSearchItems() 
  Функция populateSearchItems() очень похожа на функцию populateTweetItems() .  Он анализирует форматированный текст JSON, отправленный API-интерфейсом Twitter в ответ на запрос search , извлекает из него содержимое сообщения и, наконец, создает таблицу HTML для отображения этого содержимого.  Структура текста JSON представлена в следующем формате, в котором мы рассматриваем только элементы, относящиеся к данному приложению. 
| 
 1 
2 
3 
4 
5 
 | 
 {… 
  «results»:[{«created_at»:»…»,…,»text»:»…»}, 
             {«created_at»:»…»,…,»text»:»…»},…] 
  … 
} 
 | 
  Массив результатов состоит из результатов поиска.  Каждая запись массива начинается с элемента с именем created_at , значением которого является отметка даты / времени.  Пример таков: 
| 
 1 
 | 
 «created_at»:»Sun, 09 Oct 2011 20:06:49 +0000″ 
 | 
Текстовый элемент в каждой записи массива результатов содержит текстовое сообщение (твит), которое связано с поисковым термином. Обратите внимание, что поисковый термин может быть частью значения текстового элемента или какого-либо другого элемента в массиве результатов. Пример текстового элемента, который возвращается в ответ на поисковый запрос
| 
 1 
 | 
 fortlauderdale 
 | 
дается ниже:
| 
 1 
 | 
 «text»:»Turtle-friendly lighting at McSorleys (video) http://t.co/GqrLOlGn #Irish #Beach #Pub #FortLauderdale» 
 | 
Ниже приведен список констант, используемых функцией:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
 var EMPTY = »; 
var SPACE = ‘ ‘; 
var HTML_FRG7 = ‘<tr><td>’; 
var HTML_FRG8 = ‘<hr></hr></td></tr>’; 
var EM1 = ‘<em>’; 
var EM2 = ‘</em> ‘; 
var MAX_TWEETS = 11; 
var TABLE_OPEN = ‘<table STYLE=»border-spacing: 10pt 0pt»>’; 
var TABLE_CLOSE = ‘</table>’; 
 | 
Полный список функций приведен ниже:
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
 | 
 function populateSearchItems(jsonText){ 
  var tmpTxt = EMPTY; 
  var indx = 0; 
  var result = $.parseJSON(jsonText); 
  if(result != null){ 
    var resultsArr = result.results; 
    if(resultsArr != null){ 
      for(var i = 0; i < resultsArr.length; i++){ 
        var txt = resultsArr[i].text; 
        var whenArr = (resultsArr[i].created_at).split(SPACE,5); 
        var when = whenArr[0] + SPACE + whenArr[1] + SPACE + whenArr[2] + SPACE + whenArr[4]; 
        tmpTxt = tmpTxt + HTML_FRG7 + EM1 + when + EM2 + addHref(txt) + HTML_FRG8; 
        if(++indx >= MAX_TWEETS){ 
          break; 
        } 
      } 
    } 
    resultsVar.html(TABLE_OPEN + tmpTxt + TABLE_CLOSE); 
    showResults(); 
  } 
  return false; 
} 
 | 
  Функция начинается с объявления локальных переменных tmpTxt и indx .  Затем мы используем parseJSON() функции jQuery parseJSON() передавая форматированный текст JSON в качестве аргумента.  На обработанный JavaScript-объект ссылаются через переменную с именем result .  Если result не нуль, он должен содержать массив с именем results .  Переменная с именем resultsArr содержит ссылку на этот массив.  Если массив не равен NULL, мы выполняем его итерацию и извлекаем из него элементы text и created_at , как показано ниже: 
| 
 1 
2 
3 
4 
5 
6 
 | 
 … 
if(resultsArr != null){ 
  for(var i = 0; i < resultsArr.length; i++){ 
    var txt = resultsArr[i].text; 
    var whenArr = (resultsArr[i].created_at).split(SPACE,5); 
    … 
 | 
  Элемент created_at состоит из 6 токенов (см. Пример выше): 
- Первый токен: день недели, за которым следует запятая, например, Sun,
 - Второй токен: день месяца, например, 09
 - Третий токен: месяц года, например октябрь
 - Четвертый знак: год, например, 2011
 - Пятый токен: ЧЧ24: ММ: СС, например, 20:06:49, время в 24-часовом формате.
 - Шестой токен: местный дифференциал часов от GMT
 
  Поскольку нас интересуют первые пять токенов, мы используем функцию JavaScript split() чтобы извлечь их и поместить в массив с именем whenArr . 
Код продолжается следующим образом:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
 … 
    var when = whenArr[0] + SPACE + whenArr[1] + SPACE + whenArr[2] + SPACE + whenArr[4]; 
    tmpTxt = tmpTxt + HTML_FRG7 + EM1 + when + EM2 + addHref(txt) + HTML_FRG8; 
    if(++indx >= MAX_TWEETS){ 
      break; 
    } 
  } 
} 
… 
 | 
  Выше мы создаем текстовую переменную с именем, которая состоит из первого, второго, третьего и пятого токенов, разделенных пробелом (например, Sun, 09 октября 20:06:49).  Затем мы создаем строку в формате HTML и добавляем ее в переменную tmpTxt .  Для каждой записи в массиве результатов строка в формате HTML представляет собой строку таблицы, состоящую из переменных when и txt , где любой URL-адрес внутри переменной txt окружен тегом <a> .  Это тот же метод, который мы использовали в populateTweetItems() выше.  Например: 
| 
 1 
2 
 | 
 «created_at»:»Sun, 09 Oct 2011 20:06:49 +0000″ 
«text»:»Turtle-friendly lighting at McSorleys (video) http://t.co/GqrLOlGn #Irish #Beach #Pub #FortLauderdale» 
 | 
Это даст:
| 
 1 
2 
3 
 | 
 <tr><td><em>Sun, 09 Oct 20:06:49</em> Turtle-friendly lighting at McSorleys (video) 
  <a href=»http://t.co/GqrLOlGn»>http://t.co/GqrLOlGn</a> 
  #Irish #Beach #Pub #FortLauderdale<hr></hr></td></tr> 
 | 
Наконец, мы устанавливаем ограничение на количество записей
| 
 1 
 | 
 results 
 | 
  массив обработан.  Где, максимум, MAX_TWEETS записи разрешены. 
  Результирующая строка в формате HTML, представленная переменной tmpTxt , состоит из уникальной строки таблицы для каждого результата поиска.  Последние несколько строк листинга кода выглядят следующим образом.  Здесь мы помещаем эти строки <table> тег <table> .  Это устанавливается как содержимое элемента <div> ссылается resultsVar .  Наконец, мы вызываем showResults() для отображения страницы результатов (для широкоэкранных устройств вызов функции showResults() будет иметь никакого эффекта). 
| 
 1 
2 
3 
4 
5 
6 
 | 
     … 
    resultsVar.html(TABLE_OPEN + tmpTxt + TABLE_CLOSE); 
    showResults(); 
  } 
  return false; 
} 
 | 
Обработчики событий
В этом разделе мы рассмотрим функции, которые обрабатывают пользовательские события.
  Функция buttonAddUserClicked() 
  Функция buttonAddUserClicked() является обработчиком событий, когда пользователь нажимает кнопку, чтобы добавить отображаемое имя. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
 | 
 var EMPTY = »; 
var UL = ‘ul’; 
var REFRESH = ‘refresh’; 
… 
function buttonAddUserClicked(){ 
  var tmpInput = $.trim(txtInputVar.val()); 
  if(tmpInput.length < 1){ 
    return false; 
  } 
  addInput(txtInputVar.val(),false); 
  txtInputVar.val(EMPTY); 
  $(UL).listview(REFRESH); 
  storeCurrentInput(); 
} 
 | 
  Глобальная переменная txtInputVar указывает на текстовое поле id='txtInput' (устройство с узким экраном) или id='txtInputWide' (устройство с широким экраном).  Значение txtInputVar обрезается, и, если оно отличается от пустой строки, оно передается в addInput для добавления в представление списка имен экранов и условий поиска.  Вторым параметром для addInput является логическое значение false указывающее, что это псевдоним, а не поисковый термин.  Затем текстовое поле, на которое ссылается txtInputVar , очищается, представление списка поисковых терминов и отображаемых имен обновляется с помощью просмотра listview('refresh') jQuery Mobile listview('refresh') и storeCurrentInput() функция storeCurrentInput() для сохранения записей представления списка в локальная база данных. 
  Функция buttonAddSearchClicked() 
  Функция buttonAddSearchClicked() аналогична buttonAddUserClicked() .  Это обработчик событий, когда пользователь нажимает на кнопку для поискового запроса.  Список кодов приведен ниже. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
 | 
 var EMPTY = »; 
var UL = ‘ul’; 
var REFRESH = ‘refresh’; 
… 
function buttonAddSearchClicked(){ 
  var tmpInput = $.trim(txtInputVar.val()); 
  if(tmpInput.length < 1){ 
    return false; 
  } 
  addInput(txtInputVar.val(),true); 
  txtInputVar.val(EMPTY); 
  $(UL).listview(REFRESH); 
  storeCurrentInput(); 
} 
 | 
  Глобальная переменная txtInputVar указывает на текстовое поле id='txtInput' (устройство с узким экраном) или id='txtInputWide' (устройство с широким экраном).  Значение txtInputVar обрезается, и, если оно отличается от пустой строки, оно передается в addInput для добавления в представление списка имен экранов и условий поиска.  Вторым параметром addInput является логическое значение true указывающее, что это поисковый термин.  Затем текстовое поле, на которое ссылается txtInputVar , очищается, представление списка имен экранов и поисковых терминов обновляется с помощью просмотра listview('refresh') функции jQuery Mobile listview('refresh') и storeCurrentInput() функция storeCurrentInput() для сохранения записей представления списка в локальная база данных. 
Встроенные обработчики событий
В этом разделе мы рассмотрим различные обработчики событий, которые определены встроенными.
  Глобальная переменная buttonHdrShowInputsVar представляет кнопку «Назад» в заголовке страницы «Результаты».  При нажатии этой кнопки вызывается функция showInputs() для отображения страницы Inputs. 
| 
 1 
2 
3 
4 
 | 
 buttonHdrShowInputsVar.click(function() { 
  showInputs(); 
  return false; 
}); 
 | 
  Аналогично, глобальная переменная buttonFtrShowInputsVar представляет кнопку «Назад» в нижнем колонтитуле страницы «Результаты».  При нажатии этой кнопки вызывается функция showInputs() для отображения страницы Inputs. 
| 
 1 
2 
3 
4 
 | 
 buttonFtrShowInputsVar.click(function() { 
  showInputs(); 
  return false; 
}); 
 | 
  Глобальная переменная buttonProgShowInputsVar представляет кнопку возврата на странице хода выполнения.  Из обзора функций getSearch() и getTweets() для глобальной переменной requestObject задан объект jQuery XMLHttpRequest возвращаемый вызовами ajax() API Twitter.  При нажатии на эту кнопку функция jQuery abort() вызывается для объекта XMLHttpRequest для завершения вызова ajax() .  Затем откроется страница Inputs. 
| 
 1 
2 
3 
4 
5 
6 
7 
 | 
 buttonProgShowInputsVar.click(function() { 
  try{ 
    requestObject.abort(); 
  }catch(err){} 
  showInputs(); 
  return false; 
  }); 
 | 
  Глобальная переменная buttonAddUserVar представляет кнопку с buttonAddUserVar «Add Screen Name» на странице «Входы».  При нажатии этой кнопки вызывается функция buttonAddUserClicked() . 
| 
 1 
2 
3 
4 
 | 
 buttonAddUserVar.click(function() { 
  buttonAddUserClicked(); 
  return false; 
}); 
 | 
  Глобальная переменная buttonAddSearchVar представляет кнопку с меткой «Добавить buttonAddSearchVar поиска» на странице «Входы».  При нажатии этой кнопки вызывается функция buttonAddSearchClicked() . 
| 
 1 
2 
3 
4 
 | 
 buttonAddSearchVar.click(function() { 
  buttonAddSearchClicked(); 
  return false; 
}); 
 | 
  Глобальная переменная buttonAddUserWideVar представляет кнопку с меткой «Добавить отображаемое имя» на странице широкого содержимого.  При нажатии этой кнопки вызывается функция buttonAddUserClicked() . 
| 
 1 
2 
3 
4 
 | 
 buttonAddUserWideVar.click(function() { 
  buttonAddUserClicked(); 
  return false; 
}); 
 | 
  Глобальная переменная buttonAddSearchWideVar представляет кнопку с меткой «Добавить buttonAddSearchWideVar поиска» на странице широкого содержимого.  При нажатии этой кнопки вызывается функция buttonAddSearchClicked() . 
| 
 1 
2 
3 
4 
 | 
 buttonAddSearchWideVar.click(function() { 
  buttonAddSearchClicked(); 
  return false; 
}); 
 | 
Функции отображения страницы
В этом разделе мы рассмотрим функции, которые управляют скрытием / отображением страниц. Эти функции являются ключевыми для управления потоком экрана.
  Функция hideInputs() 
  Функция hideInputs скрывает заголовки, содержимое и нижний колонтитул страницы Inputs.  Обратите внимание, что hdrInputsVar , contentInputsVar и ftrInputsVar являются константами, указывающими на элементы <div> для разделов заголовка, содержимого и нижнего колонтитула страницы Inputs соответственно. 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
 var hdrInputsVar = $(‘#hdrInputs’); 
var contentInputsVar = $(‘#contentInputs’); 
var ftrInputsVar = $(‘#ftrInputs’); 
… 
function hideInputs(){ 
  hdrInputsVar.hide(); 
  contentInputsVar.hide(); 
  ftrInputsVar.hide(); 
} 
 | 
  Функция hideResults() 
  Эта функция скрывает заголовки, содержимое и нижний колонтитул страницы результатов.  Обратите внимание, что hdrResultsVar , contentResultsVar и ftrResultsVar являются константами, указывающими на элементы <div> для разделов заголовка, содержимого и нижнего колонтитула страницы результатов, соответственно. 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
 var hdrResultsVar = $(‘#hdrResults’); 
var contentResultsVar = $(‘#contentResults’); 
var ftrResultsVar = $(‘#ftrResults’); 
… 
function hideResults(){ 
  hdrResultsVar.hide(); 
  contentResultsVar.hide(); 
  ftrResultsVar.hide(); 
} 
 | 
  Функция hideProgress() 
  Эта функция скрывает разделы верхнего и нижнего колонтитула страницы Progress.  Обратите внимание, что hdrProgressVar , contentProgressVar и ftrProgressVar являются константами, указывающими на элементы <div> для разделов заголовка, содержимого и нижнего колонтитула страницы Progress, соответственно. 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
 var hdrProgressVar = $(‘#hdrProgress’); 
var contentProgressVar = $(‘#contentProgress’); 
var ftrProgressVar = $(‘#ftrProgress’); 
… 
function hideProgress(){ 
  hdrProgressVar.hide(); 
  contentProgressVar.hide(); 
  ftrProgressVar.hide(); 
} 
 | 
  Функция showInputs() 
  Эта функция показывает разделы верхнего и нижнего колонтитула страницы Inputs и скрывает страницы Progress, Results и Wide.  Обратите внимание, что hdrInputsVar , contentInputsVar и ftrInputsVar являются константами, указывающими на элементы <div> для разделов заголовка, содержимого и нижнего колонтитула страницы Inputs соответственно (см. Обзор hideInputs () выше). 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
 | 
 function showInputs(){ 
  hdrInputsVar.show(); 
  contentInputsVar.show(); 
  ftrInputsVar.show(); 
  hideProgress(); 
  hideResults(); 
  hideWide(); 
} 
 | 
  Функция showResults() 
  Для устройств с узким экраном функция showResults() показывает заголовки, разделы содержимого и showResults() колонтитула страницы результатов и скрывает страницы Progress, Inputs и Wide.  Обратите внимание, что hdrResultsVar , contentResultsVar и ftrResultsVar являются константами, указывающими на элементы <div> для разделов заголовка, содержимого и нижнего колонтитула страницы результатов, соответственно (см. Обзор hideResults() выше).  Для широкоэкранных устройств showResults() предоставляет никаких функций. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
 | 
 function showResults(){ 
  if(isWide){ 
    }else{ 
    hdrResultsVar.show(); 
    contentResultsVar.show(); 
    ftrResultsVar.show(); 
    hideProgress(); 
    hideInputs(); 
    hideWide(); 
  } 
} 
 | 
  Функция showProgress() 
  Для устройств с узким экраном функция showProgress() отображает разделы верхнего и нижнего колонтитула страницы Progress и скрывает страницы Inputs, Results и Wide.  Обратите внимание, что hdrProgressVar , contentProgressVar и ftrProgressVar являются константами, указывающими на элементы <div> для разделов заголовка, содержимого и нижнего колонтитула страницы Progress, соответственно (см. Обзор hideProgress() выше). 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
 | 
 function showProgress(){ 
  if(isWide){ 
    resultsVar.html(TMP_INNER_HTML); 
  } 
  else{ 
    hdrProgressVar.show(); 
    contentProgressVar.show(); 
    ftrProgressVar.show(); 
    hideInputs(); 
    hideResults(); 
    hideWide(); 
  } 
} 
 | 
  Для широкоэкранных устройств resultsVar указывает на <div> с id='resultsCell' , представляющим таблицу результатов.  Для широкоэкранных устройств эта функция устанавливает HTML-содержимое resultsVar в константу TMP_INNER_HTML , которая определяется следующим образом. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
 | 
 <div align=»CENTER»> 
  <a href=»javascript:try{requestObject.abort();resultsVar.html(EMPTY);}catch(err){};return false;» 
    data-inline=»true» data-role=»button» data-theme=»b» 
    class=»ui-btn ui-btn-inline ui-btn-corner-all ui-shadow ui-btn-up-b»> 
      <span class=»ui-btn-inner ui-btn-corner-all»> 
        <span class=»ui-btn-text»>Cancel 
  </a> 
</div> 
<div align=»CENTER»> 
  <img src=»css-js/images/wait.gif»/> 
</div> 
 | 
  Атрибуты data-inline , data-role и data-theme и значения различных атрибутов класса являются конструкциями jQuery Mobile. 
  Тег <a> имеет определение кнопки jQuery Mobile с меткой «Отмена».  Из обзора функций getSearch() и getTweets() напомним, что для глобальной переменной requestObject задан объект jQuery XMLHttpRequest возвращаемый из вызовов ajax в API Twitter.  При нажатии этой кнопки с помощью встроенного определения функции JavaScript функция jQuery abort() вызывается для объекта XMLHttpRequest для завершения вызова ajax() .  В дополнение к тегу <a> с кнопкой «Отмена», определенное выше содержимое HTML также содержит изображение вращающегося колеса wait.gif . 
  Функция hideWide() 
  Эта функция скрывает верхний, нижний и нижний колонтитулы страницы Wide.  Обратите внимание, что hdrWideVar , contentWideVar и ftrWideVar — это константы, указывающие на элементы <div> для hdrWideVar contentWideVar и ftrWideVar hdrWideVar , contentWideVar и ftrWideVar колонтитула на странице Wide, соответственно. 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
 var hdrWideVar = $(‘#hdrWide’); 
var contentWideVar = $(‘#contentWide’); 
var ftrWideVar = $(‘#ftrWide’); 
… 
function hideWide(){ 
  hdrWideVar.hide(); 
  contentWideVar.hide(); 
  ftrWideVar.hide(); 
} 
 | 
  Функция showWide() 
  Эта функция показывает разделы верхнего и нижнего колонтитула страницы Wide и скрывает страницы Progress, Inputs и Results.  Обратите внимание, что hdrWideVar , contentWideVar и ftrWideVar — это константы, указывающие на элементы <div> для hdrWideVar contentWideVar и ftrWideVar hdrWideVar , contentWideVar и ftrWideVar колонтитула на странице Wide, соответственно. 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
 | 
 function showWide(){ 
  hdrWideVar.show(); 
  contentWideVar.show(); 
  ftrWideVar.show(); 
  hideProgress(); 
  hideInputs(); 
  hideResults(); 
} 
 | 
Заключительные замечания
В части III мы продолжили проверку «Основных функций бизнес-логики», начиная с того места, на котором остановились в части II, и завершили анализ кода приложения Tweets, изучив «Обработчики событий» и «Функции отображения страницы».
В заключительной части этой серии, части IV, я начну с раздела «Файлы в архиве загрузок», где мы опишем содержимое архивного файла, сопровождающего эту статью. В разделе «Темы, специфичные для среды», мы объясним, как импортировать приложение в Eclipse для платформы Android и Xcode для платформы iOS. В этом разделе мы также предоставим снимки экрана приложения на телефоне Android, iPod touch и iPad 2. Наконец, мы дадим заключительные замечания и последние мысли для этого проекта.