Pull to refresh

Пишем простое приложение на jQuery Mobile

Reading time 8 min
Views 59K
imageФреймворк jQuery Mobile вышел уже относительно давно, но только сейчас мне удалось им заняться. До этого имел дело с jQTouch и Sencha Touch. У каждого из них есть свои плюсы и минусы, но сегодня речь пойдет именно про разработку на jQuery Mobile. Для получения базового опыта я опишу создание простого приложения с несколькими страницами, интеграцией с твиттер и гуглокартами, ну и набором базовых элементов. Поехали!

Итак, сначала подключим фреймворк и стили.
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.css" />
<script src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.js"></script>

Теперь примемся за страницы. Тут стоить отметить схожесть jQuery Mobile и jQTouch — все приложение это одна html страницы, на которой отмеченные особым образом div`ы являются «страницами» приложения. Базовый вид такой «страницы приложения» имеет вид:
<div data-role="page"> 
	<div data-role="header">...</div> 
	<div data-role="content">...</div> 
	<div data-role="footer">...</div> 
</div> 

Параметр data-role задает роль div`а: страница, header, содержимое страницы или footer. Так же обязательно надо задавать параметр id для div data-role=«page», чтобы можно было навигироваться по приложения.

Сразу стоит упомянуть еще об одном параметре data-theme. Данный параметр применим ко всем элементам страницы и определяет, какой из доступных по умолчанию стилей использовать. Примеры доступных тем можно посмотреть вот тут.

Итак, на главной странице нашего приложения будет меню, элементы которого будут вести на страницы с примерами. Чтобы сделать меню нам понадобится список ul. Выглядеть это будет вот так:
<ul data-role="listview" data-inset="true" data-theme="a">
	<li><a href="#twitter_page">Twitter example</a></li>
	<li><a href="#map_page">Map example</a></li>
	<li><a href="#search">Search example</a></li>
	<li><a href="#about">About</a></li>
</ul> 

О параметрах тега ul:
  • data-role=«listview» — показывает что это список, к которому нужно применить стилизацию;
  • data-inset=«true» — отображение списка не на всю ширину экрана, если нет, то эквивалентно false;
  • data-theme=«a»- применение цветовой схемы а.

В jQuery Mobile можно найти массу типов списков: простые, с иконками, с изображениями и прочие и прочие. Примеры можно посмотреть вот тут.

А еще мне хочется, чтобы в тулбаре была кнопка с настройками. Сделать это очень просто:
<a href="#settings" data-icon="gear" class="ui-btn-right">Options</a>

Как видно, данная кнопка ведет на страницу с настройками, имеет иконку шестеренки (data-icon=«gear») и расположена в правой части тулбара(class=«ui-btn-right»). Во фреймворке уже есть набор предопределенных иконок, посмотреть их можно тут.

В конечном итоге главная страница будет выглядеть вот так:
<div data-role="page" id="main_page" data-theme="b">
	<div data-role="header" >
		<h1 id="twi_acc">Home page</h1>
		<a href="#settings" data-icon="gear" class="ui-btn-right">Options</a>
	</div>
	<div data-role="content" >	
		<ul data-role="listview" data-inset="true" data-theme="a">
			<li><a href="#twitter_page">Twitter example</a></li>
			<li><a href="#map_page">Map example</a></li>
			<li><a href="#search">Search example</a></li>
			<li><a href="#about">About</a></li>
		</ul>
	</div>
	<div data-role="footer">
	</div>
</div>	

Теперь перейдем к созданию остальных страниц. Займемся страницей настроек. На ней мы расположим некоторые из элементов формы, полный список которых можно посмотреть тут.

Руководство рекомендует группировать все элементы внутри определенного дива:
<div data-role="fieldcontain">					
</div>	

Последуем данной рекомендации.

Расположим на форме следующие элементы.
Поле ввода
<label for="name">My name:</label>
<input type="text" name="name" id="name" value=""  />

Большое текстовое поле
<label for="textarea">About myself:</label>
<textarea cols="40" rows="8" name="textarea" id="textarea"></textarea>

Слайдер, задав его максимально, минимальное и текущее значения
<label for="slider">Value this site:</label>
<input type="range" name="slider" id="slider" value="0" min="-50" max="50" />

Переключатель
<label for="slider2">Value this site:</label>
<select name="slider2" id="slider2" data-role="slider">
	<option value="off">Like</option>
	<option value="on">Dislike</option>
</select> 

И селектор
<select name="select-choice-1" id="select-choice-1">
	<option value="standard">Tired</option>
	<option value="standard">Happy</option>
	<option value="standard">Sick</option>
	<option value="standard">Sunny</option>
</select>

На этом со страницей настроек все. Кстати, если запустить имеющий код и перейти на только что созданную страницу, то можно увидеть, что автоматом была создана кнопка «Back». Мелочь, а приятно.

Теперь создадим еще простую страницу — страницу поиска. На ней у нас будут два главных элемента — поле ввода и список результатов.
<div data-role="content" >	
	<label for="search">Search</label>
	<input type="search" name="password" id="search" value="" />
	<ul data-role="listview" data-inset="true" id="searchresult">					
	</ul>
</div>

Теперь обратимся к яваскрипту. Забиндим для поле ввода на событие keyup наполнение списка результатов.
$("#search").keyup(function(){
	var res = shuffle(monthes);
	var list='';
	$.each(res, function(index, value) {
		list+='<li role="option" tabindex="0" data-theme="a" class="ui-btn ui-li ui-btn-up-a"><div class="ui-btn-inner"><div class="ui-btn-text">'+value+'</div><span class="ui-icon ui-icon-arrow-r"></span></div></li>';
	});							
        $("#searchresult").html(list);	
});

Несколько слов о коде. В первой строке мы перемешиваем имеющийся массив. Функция shuffle ниже.
var shuffle = function(o){ //v1.0
	for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
		return o;
        };

Затем мы создаем сам список. Создавать приходится таким образом, потому что происходит динамическое добавление элементов списка и фреймворк уже не будет их обрабатывать, для навешивания нужных стилей и параметров. Но возможно есть способ и лучше.

Теперь создадим пару интересных страниц. Первая будет работать с твиттером по средством @Anywhere. Сначала подключим нужные библиотеки:
<script src="http://platform.twitter.com/anywhere.js?id=key_value&v=1" type="text/javascript"></script>

Для получения ключа нужно зарегистрироваться вот тут.
Затем создаем код нужной нам странички.
<div data-role="page" id="twitter_page" data-theme="b">
	<div data-role="header" >
		<h1>Simple twitter example</h1>
	</div>
	<div data-role="content" >	
		<div id="twi_list"></div>
	</div>
	<div data-role="footer">				
	</div>
</div>

А теперь самое главное — яваскрипт код, который будет выполняться, когда будет открываться нужная нам страница. Для отслеживания этого события существует специальный event — pageshow. Об остальных событиях читаем тут.
$('#twitter_page').live('pageshow',function(event, ui){					
	twttr.anywhere(function(T) {			
		T.User.find('andrebrov').timeline().first(20).each(function(status) {					
			$('div#twi_list').append('<p>' + status.user.name + ': ' + status.text + '</p>');
		});	
						
	});					
});

Подробности работы с @Anywhere можно прочитать по ссылке.
Открыв созданную нами страницу мы видим, что некоторое время она остается пустой — грузятся твиты. Чтобы дать пользователю понять, что в данных момент что-то происходит добавим спиннер. Тогда код будет выглядеть вот так:
$('#twitter_page').live('pageshow',function(event, ui){					
	twttr.anywhere(function(T) {			
		$.mobile.pageLoading();	
		var j=0;
		T.User.find('andrebrov').timeline().first(20).each(function(status) {					
			$('div#twi_list').append('<p>' + status.user.name + ': ' + status.text + '</p>');
			j++;
			if (j==1){
				$.mobile.pageLoading(true);
			}
		});							
	});					
});

Про спиннер и прочие утилиты читаем тут.

Теперь займемся страницей карты. Вначале опять же подключим нужные скрипты
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>

Затем создадим страницу
<div data-role="page" id="map_page" data-theme="b">
	<div data-role="header" >
		<h1>Map example</h1>
	</div>
	<div data-role="content" >	
		<div id="map_canvas"></div>
	</div>
	<div data-role="footer">						
	</div>
</div>

Элемент map_canvas и будет содержать карту. Зададим ему стиль
#map_canvas{
	width:100%;
	height: 100%; 	
	position:relative;
	top:0px;
}

И добавим javascript-код, который будет определять текущее местоположение, относительно него центрировать карту и добавлять в центр маркер. На этот маркер мы кроме прочего повесим событие на его нажатие.
$('#map_page').live('pageshow',function(event, ui){					
	navigator.geolocation.getCurrentPosition(function(location) {						
		var point = new google.maps.LatLng(location.coords.latitude, location.coords.longitude);
		var myOptions = {
			zoom: 13,
			center: point,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};
		var map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
		var marker = new google.maps.Marker({position: point,map: map});						
		google.maps.event.addListener(marker, 'click', function() {
			alert("Current coodinates are: latitude "+location.coords.latitude+", longitude "+location.coords.longitude);
		});
	});	
});

И, наконец, страница обо мне =) На ней интересными элементами будут элементы списка:
Разделитель с закруглениями
<li data-role="list-divider" role="heading" tabindex="0" class="ui-li ui-li-divider ui-bar-b ui-corner-top"></li>

Ссылка, открывающая почтовый клиент
<li><a href="mailto:mailme@gmail.com" class="ui-link-inherit">EMail me</a></li>

Ссылка, приводящая к набору номера
<li><a href="tel:+79000000000" class="ui-link-inherit">Call me</a></li>

О типах ссылок читаем здесь.

Итак, наше приложение готово!

Итоговый результат.
Исходники.
Документация

Приятной всем работы!
Tags:
Hubs:
+71
Comments 42
Comments Comments 42

Articles