Библиотека jQuery и Мобильный Фреймворк jQuery Mobile

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

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

ЧТО ТАКОЕ JAVASCRIPT?

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

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

ЧТО ТАКОЕ JQUERY?

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

МИНИМАЛЬНЫЙ НАБОР ЗНАНИЙ JAVASCRIPT ДЛЯ ИСПОЛЬЗОВАНИЯ JQUERY

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

Таким  образом, следует определить список основных знаний JavaScript или, так сказать, «заложить фундамент» для эффективного использования библиотеки jQuery:

  • Типы данных
  • Переменные: объявление, применение, видимость
  • Операции. Работа с числами и строками. Сокращение операций
  • Массивы. Получение и запись данных
  • События. Объекты события
  • Условия
  • Циклы
  • Функции
  • Объекты

JQUERY: БАЗОВЫЕ ФУНКЦИИ И ОСНОВНЫЕ ЗАДАЧИ, КОТОРЫЕ ВЫПОЛНЯЕТ БИБЛИОТЕКА

В jQuery существует много полезных функций для работы с DOM, обработчиками событий, формами, эффектами на странице и другое. Однако есть функции, с которыми следует ознакомиться до начала использования jQuery:

  • Взаимодействие с каждым элементом по отдельности: функция each()
  • События. Обработка событий: функция on()
  • Анимации и эффекты: функция animate()

Далее детально рассмотрим каждую из приведенных функций.

each()


В jQuery есть много преимуществ и одно из них — это «автоматическое зацикливание». Этим jQuery освобождает нас от состалвения циклов для прохода через определенный набор элементов. Например :

$(‘img’).fadeOut(); — в этом случае функция одновременно сработает для всех изображений на странице, тем самым, сделав их полностью прозрачными (CSS =  opacity: 0). Часто бывает, что при выборе определенного набора элементов, нужно выполнить не одно, а несколько действий. Для этого существует функция each().

Эта функция производит обход (перебор в цикле) всех элементов набора jQuery и вызывает функцию обратного вызова для каждого из них. Возвращает объект. Каждый раз, когда выполняется указанная функция (а выполняется она один раз для каждого совпавшего элемента), ключевое слово ‘this’ указывает на конкретный элемент DOM.

callback( [index, Element] ) – функция, вызываемая для каждого элемента в наборе jQuery. С каждой итерацией в качестве первого параметра index ей передается индекс текущего элемента (начиная с 0) как индекс текущего цикла. Во втором аргументе Element передается ссылка на сам DOM элемент. Контекст $(this) вызова функции каждый раз ссылается на текущий элемент, задействованный в данной итерации (Element == this). Цикл можно остановить в любой момент, вернув из функции обратного вызова return false.

Пример:

li
li class="stop"
li

Выводить в цикле содержимое пунктов списка до тех пор, пока не попадется «li» с классом «stop».

$('li').each(function(i,elem) {

if ($(this).hasClass(«stop»)) { // в данном случае $(this) обращается к «li» в текущей итерации

alert(«Остановлено на » + i + «-м пункте списка.»);

return false;

} else {

alert(i + ‘: ‘ + $(elem).text());

}
});

Более детально: http://api.jquery.com/each/

on() — «в прошлом bind(), live(), delegate()»


В jQuery есть набор обработчиков событий, которые фиксируют поведение посетителя на странице. С помощью этих обработчиков можно выполнять те или иные действия с выбранным элементом:

  • click(); — клик мышкой
  • dblclick(); — двойной клик мышкой
  • hover(); — наведение курсора на элемент. Работает как 2 в 1: mouseenter(); и mouseleave();
  • scroll(); — срабатывает, когда идет горизонтальная или вертикальная прокрутка окна браузера
  • toggle(); — вызывается при клике на элемент
  • load(); — срабатывает, когда все потомки родителя полностью загружены в документе

Полный список по ссылке: http://api.jquery.com/category/events/

С помощью функции on() jQuery позволяет нам более гибко обрабатывать события, чем вышеприведенные обработчики.  Рассмотрим структуру функции (ее аргументы):

$('selector').on('click', selector, myData, functionName)

  • первый аргумент: событие
  • второй (опционально).
  • третий: данные, которые можно передать в функцию. Это может быть Object Literal или переменная с Object Literal
  • четвертый аргумент: имя функции или анонимная функция

Пример:

Нам нужно, чтобы сообщение alert() отображало разный текст, в зависимости от нажатого элемента. Можно создать несколько переменных и положить в них различные Object Literal:

var linkVar = {message: 'Hello from a link!'};

var pVar = {message: ‘Hello from a paragraph’};

function showMessage(e) {

alert(e.data.message);

}

$('a').on('click',linkVar,showMessage); — По клику на ссылку, выведем сообщение переменной linkVar

$('p').on('click',pVar,showMessage);— По клику на параграф, выведем сообщение переменной pVar

Также, можно использовать несколько событий для вызова одной и той же функции:

$('a').on('click keypress hover',linkVar,showMessage);

Пример:

Каждое событие может вызывать различные функции:

$('selector').on({

‘click’: function() {

// Hello world #1

},

‘mouseover’: function() {

// Hello world #2

}

});

Делегирование событий

Второй аргумент функции on() может принимать второй селектор.

$('selector').on('click', selector, myData, functionName)

Без второго селектора событие применяется к первоначальному селектору.

$('ul').on('click', function(){

$(this).css(‘color’: ‘red’); // в данном случае селектор this ссылается на ul

});

Проблемой с таким обработчиком событий является  то, что он только работает с элементами, которые уже представлены в DOM. Те элементы, которые добавлены динамически в DOM, не будут реагировать на данный обработчик события.

Например, создадим список задач <ul> (аналог TODO). После загрузки страницы, в списке нет задач. Добавим одну задачу в теге <li>. Далее, мы хотим вычеркнуть <li> с помощью text-decoration: line-through. Если присвоить обработчик событий на li как click(), on()…., то не будет никакого эффекта.

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

Пример:

$('ul').on('click', 'li', function(){

$(this).css(‘text-decoration’: ‘line-through’);  // селектор this ссылается на li

});

В этом случае мы говорим обработчику событий слушать события не родителя ul, а его потомков li.

Более детально по ссылке: http://api.jquery.com/on/

animte()


В jQuery есть хороший набор базовых анимаций как: fadeIn(); hide(); slideDown() и другие. Однако, они не позволяют создавать гибкие анимационные эффекты для элементов HTML, тем самым,  в какой-то степени ограничивая разработчика.

Для создания различных анимаций используют функцию animate();. Можно выполнить анимацию практически для любого свойства css, которое принимает числовые значения типа px, %, em. Чтобы использовать эту функцию, нужно передать ей object literal со свойствами CSS.

{
left: '650px',

opacity: .5,

fontSize: ’24px’
}

Скобки для названий свойств необязательны, однако для числовых значений с px,em,% — это обязательно. Также в object literal нельзя записывать названия свойств с черточкой тире — font-size, так как в языке JavaScript этот символ является специальным оператор вычитания, а не просто черточка. Поэтому нужно записывать свойства таким образом: fontSize, borderLeftWidth и др.

Но, если необходимо записывать свойства как принято, то нужно ставить скобки ‘font-size’.

Функция animate(); принимает 3 аргумента:

  • Object literal
  • Скорость анимации
  • Тип анимации (swing: ‘по-умолчанию’; Опционально: Linear)

Примечательно, что любая анимация в jQuery может принимать последние два аргумента: slideUp(1000, ‘linear’); Кроме стандартных эффектов Swing и Linear, можно использовать множество других, если подключить библиотеку  jQuery UI.

Бывает так, что возникает потребность что-то сделать с объектом сразу после анимации. Например, после того как появилась фотография, описание к ней должно плавно появиться. В CSS3 это можно сделать с помощью задержек в анимации. В jQuery это делается с помощью специальной функции обратного вызова (callback function):

$('#photo').animate(
{
width: '200px',

height: ‘200px’,

opacity: 1
},

1000,

‘linear’,

function() {

$(‘caption’).fadeIn(1000);

}
);

Чтобы выполнить несколько анимацией, необходимо вложить в функцию обратного вызова еще одну callback function с анимацией.

$('#photo').animate(
{
width: '200px',

height: ‘200px’,

opacity: 1

},
1000,

‘linear’,

function() { // первая callback function

$(‘#caption’).fadeIn(1000,

function() { // вторая callback function

$(‘#photo, #caption’).fadeOut(1000);

} // конец  второй callback function

); // конец fadeIn

} // конец первой callback function

); // конец функции animate

Однако, нет необходимости использовать callback функцию, если нужно выполнить несколько анимаций для одного и того же элемента.

$('#photo').fadeIn(1000).delay(10000).fadeOut(1000);

В этом случае, jQuery ставит каждый эффект в «очередь» и они выполняются поочередно.

Также,  стоит учесть, что если пользователь нажмет несколько раз на элемент, для которого стоит определенная анимация, то эта анимация будет выполнена столько раз, сколько он на нее нажмет. Чтобы этого избежать, стоит использовать специальную функцию остановки анимации stop();

Более детально по ссылке: http://api.jquery.com/animate/

ОСНОВНЫЕ ЗАДАЧИ, КОТОРЫЕ ВЫПОЛНЯЕТ  jQUERY

Работа с классами элементов

  • addClass( className or Function );
  • hasClass( classname );
  • removeClass( className or Function );
  • toggleClass( className / className,state / state / Function, state );

Копирование

  • clone( withDataAndEvents, deepWithDataAndEvents );

Работа с DOM, обхват

  • unwrap();
  • wrap( wrappingElement or Function );
  • wrapAll( wrappingElement or Function );
  • wrapInner( wrappingElement or Function );

Работа с DOM, внутри

  • html( htmlString or Function);
  • text( text or Function );
  • append( elements or Function );
  • appendTo( elements or Function );
  • prepend( elements or Function );
  • prependTo( elements or Function );

Работа с DOM, снаружи

  • after( elements or Function );
  • before( elements or Function );
  • insertAfter();
  • insertBefore();

Работа с DOM, удаление

  • empty();
  • remove();
  • detach();
  • unwrap();

Работа с DOM, замена

  • replaceAll( target );
  • replaceWith( newContent or Function );
  • Работа с DOM, другое
  • attr();
  • prop();
  • css();

Определение размеров и позиции элемента

  • width()
  • height()
  • innerWidth() — включает padding, но не border
  • innerHeight()
  • outerWidth( true ) — включает padding, border и опционально margin
  • outerHeight( true )
  • offset() — определить позицию элемента по отношению к document
  • position() — определить позицию элемента по отношению к parent
  • scrollLeft() — определить горизонтальную позицию скроллбара или установить позицию
  • scrollTop() — определить вертикальную позицию скроллбара или установить позицию

БАЗОВАЯ РАБОТА JQUERY С ФОРМОЙ. ВАЛИДАЦИЯ ДАННЫХ

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

Выбор элементов формы

  • $(‘:input’)
  • $(‘:text’)
  • $(‘:password’)
  • $(‘:radio’)
  • $(‘:checkbox’)
  • $(‘:submit’)
  • $(‘:image’)
  • $(‘:reset’)
  • $(‘:button’)
  • $(‘:file’)
  • $(‘:hidden’)

Извлечение и запись данных в форму. Интернет-магазины часто требуют специального функционала для подсчета суммы выбранных товаров, включая налоги, стоимость доставки и др.  Для такого рода задач можно использовать jQuery.

val()


Извлечение и запись данных в форму

var fieldValue = $('#email').val(); — может извлекать и записывать значение поля input

Пример – извлечение, обработка и запись значения из поля input

var unitPrice = 9.95;

var amout = $(‘#quantity’).val(); // извлекаем значение

var total = amount * unitPrice;

total = total.toFixed(2); // округление максимум до 2ух нулей после запятой

$(‘#total’).val(total); // записываем новое значение

prop()


Определение состояния Radio или Checkbox. Эта функция определяет состояние только первого элемента в выбранном диапазоне. Возвращает Undefined,  если нет значения. Чтобы извлечь значение каждого элемента отдельно, необходимо использовать функцию each().

Пример:

if ($('#news')).prop('checked') {

// checked: true

} else {

// checked: false

}

События форм и функции

Можно легко запускать функции проверки данных в форме благодаря обработчикам событий:

  • submit() — срабатывает, когда нажимаем элемент type=»submit»
  • focus() — срабатывает, когда нажимаем или tab-ем на input
  • blur() — срабатывает, когда нажимаем или tab-ем вне input
  • click() — срабатывает, когда нажимаем на любой элемент формы
  • change() — срабатывает, когда меняется значение. Только для тегов <input>, <textarea>,  <select>

Самое простое, что можно сделать при проверке данных, так это проверить – не оставил ли пользователь поле пустым:

Пример:

$('form').submit(function(e){

if ($(‘#username’).val() == ») {

alert(‘Пожалуйста, введите имя’);

return false; — запрещаем отправку формы

e.preventDefault(); — можно и так запретить отправку формы

} // end if

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

Проверка данных (на стороне клиента)

Данные формы, как правило, проверяются с помощью JavaScript и могут быть следующего типа:

  1. — оставил ли пользователь обязательные поля пустыми?
  2. — ввел ли пользователь корректный адрес e-mail?
  3. — ввел ли пользователь корректную дату?
  4. — не заполнил ли пользователь числовое поле текстом?
  5. оставил ли пользователь обязательные поля пустыми?

if (x == null || x == '') {Hello}

  1. ввел ли пользователь корректный адрес e-mail?

Обычно проверяют с помощью регулярного выражения таким образом:

var x = "Hello World";

var y = new RegExp(«^[a-zA-Z0-9]+$»); // создаем переменную с регулярным выраже6нием

var check = x.test(y); // проверяем значение

function test(x, y){  // создаем функцию для проверки данных регулярным выражением

if (x.test(y)) {

// True

} else {

// False

}

}

function(x, y); // вызываем функцию

Список готовых решений по регулярным выражениям: http://habrahabr.ru/post/123845/

  1. ввел ли пользователь корректную дату?

Дата в формате DD/MM/YYYY:

Пример рег. выражениям: (0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d

  1. не заполнил ли пользователь числовое поле текстом?

if (isNaN()) {Hello}

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

JQUERY MOBILE

Что это:

UI Framework  работает на большинстве мобильных устройств, планшетах и десктопных компьютерах. Используется для разработки мобильных веб-приложений, мобильной версии сайта.

Почему стоит использовать:

  1. Кроссбраузерный и кроссплатформенный
  2. Большой набор различных событий, функций, виджетов: Swipe, Taphold и др.
  3. Можно легко допиливать «под себя»
  4. Использует технологию AJAX. Страницы загружаются быстрее, экран не блымает
  5. Готовый адаптивный набор различных UI инструментов.
  6. Доступны различные анимашки. Транзишены на переходы между страницами, всплывающие формочки и т.д.Также в наличии своя сетка, адаптивные таблицы.

Из чего состоит:

  1. Стили jQuery Mobile (можно скачивать как минифицированную, так и development версию)
  2. Стандартный фреймворк jQuery (Обязательно)
  3. Сам jQuery Mobile (на сайте можно использовать custom builder, и выбрать необходимые модули для конкретного проекта, потому что полная версия jquery mobile весит почти 200 кб)

Стоит заметить, что для jQuery Mobile нет исходных файлов LESS или SASS.

Как начать использовать

  1. Подключаем все необходимые файлы: jQuery, jQuery Mobile, jQuery Mobile CSS
  2. Любая страница при использовании jQuery Mobile должна иметь такую структуру:

<div data-role="page" id="page-home">

<!— Шапка страницы —>

<div data-role=»header»>

<h1>HEADER</h1>

</div>

<!— Основной контент —>

<div role=»main» class=»ui-content»>

<h1>Content</h1>

</div>

<!— подвал —>

<div data-role=»footer»>

<h1>2015 Reclamare &copy;</h1>

</div>

</div>

Существует несколько вариантов использованию jQuery Mobile, такие как:

  1. Первый вариант, когда помещаем все страницы на одном URL, а навигацию по страницам осуществляется как простой переход с одной ссылки на другую внутри одной страницы.

В этом случае документ будет иметь такой вид:

<!-- Страница №1: это Главная-->

<div data-role=»page» id=»page-home»>

<!— Шапка страницы —>

<div data-role=»header»>

<a href=»#page-news»>Сетка в jQuery Mobile</a>

<a href=»#page-contacts»>Search example</a>

</div>

<!— Основной контент —>

<div role=»main» class=»ui-content»>

<h1>Content</h1>

</div>

<!— подвал —>

<div data-role=»footer»>

<h1>2015 Reclamare &copy;</h1>

</div>

</div>

<!— Страница №2 —>

<div data-role=»page» id=»page-news»>

<!— Шапка страницы —>

<div data-role=»header»>

<h1>HEADER</h1>

</div>

<!— Основной контент —>

<div role=»main» class=»ui-content»>

<h1>Content</h1>

</div>

<!— подвал —>

<div data-role=»footer»>

<h1>2015 Reclamare &copy;</h1>

</div>

</div>

<!— Страница №3 —>

<div data-role=»page» id=»page-contacts»>

<!— Шапка страницы —>

<div data-role=»header»>

<h1>HEADER</h1>

</div>

<!— Основной контент —>

<div role=»main» class=»ui-content»>

<h1>Content</h1>

</div>

<!— подвал —>

<div data-role=»footer»>

<h1>2015 Reclamare &copy;</h1>

</div>

</div>

При таком варианте желательно мобильную версию сайта разрабатывать на поддомене типа m.website.com и осуществлять редирект пользователей на мобильном устройстве на мобильную версию сайта m.website.com.

Можно сделать двумя способами:

  1. JS

if (screen.width <= 800) {

window.location = «http://m.website.com»;

}

  1. .htaccess

RewriteEngine On

# Check for mime types commonly accepted by mobile devices

RewriteCond %{HTTP_ACCEPT} «text\/vnd\.wap\.wml|application\/vnd\.wap\.xhtml\+xml» [NC]

RewriteCond %{REQUEST_URI} ^/$

RewriteRule ^ http://m.website.com%{REQUEST_URI} [R,L]

— Минус такого метода заключаются в том, что одна страница может содержать большое количество данных и, тем самым, может замедляться загрузка.

  1. Второй вариант — это когда размещаем страницы на отдельных URL.

<a href="/page-news">Новости Mobile</a>

<a href=»/page-contacts»>Контакты </a>

В этом случае мы нивелируем отрицательную сторону предыдущего метода. Стоит напомнить, что jQuery Mobile использует технологию AJAX.  Тем самым, при переходе с одного URL на другой URL браузер заново не инициализирует запросы JavaScript и CSS.

— Минус этого метода заключается в том, что переход между страницами будет немного дольше чем, если бы все данные были на одной странице.

+ Для устранения этого минуса, можно использовать «предварительную загрузку» страниц data-prefetch=»true». Таким образом, браузер подгрузит страницу в DOM.

Как альтернативу можно использовать скрип:

$( ":mobile-pagecontainer" ).pagecontainer( "load", pageUrl, { showLoadMsg: false } );

+ Однако, если хранить слишком много страниц в DOM, это может сильно повлиять на работу мобильного браузера.

jQuery Mobile после посещения предварительно подгруженной старницы удаляет ее c расчетом на то, что браузер закеширует страницу.

Однако, если есть потребность, то можно запретить удалять «предварительно загруженную страницу» из DOM  data-dom-cache=»true» — который присваиваем контейнеру страницы.

Как альтернативу можно использовать скрип:

$.mobile.page.prototype.options.domCache = true; — все страницы остаются в DOM

pageContainerElement.page({ domCache: true }); — выбираем какую-то отдельную страницу

* В общем, вышеперечисленная структура не является обязательным условием для использования jQuery Mobile, если использовать второй вариант, где каждая страница идет как отдельный URL.

Если на странице нет блока, где указан data-role=»page», то jQuery автоматически использует весь документ.

Стоит учесть, что jQuery Mobile использует функцию wrapAll() для поиска (дата атрибутов, классов и тд…) и загружает каждый исходный скрип с помощью XMLHttpRequest запроса.

Если будут присутствовать скрипты в теле документа, то браузер будет загружать их дважды. Тем самым, рекомендуется использовать div с data-role=»page».

  1. Вариант:

Создание мобильной версии сайта с помощью Виджетов.

Документация jQuery Mobile — http://jquerymobile.com/