Заметки с тегом «ui»

Подключение Яндекс.Карт после загрузки страницы

В API Яндекс.Карт есть метод ready , который выполняет указанную функцию после полной загрузки всех требуемых модулей. Однако он стабильно работает только когда карты подключаются на страницу в теге head или по крайней мере до события DOMContentLoaded. Если карту попытаться загрузить гораздо позже, то метод может и не выполниться (обсуждение этого дефекта в клубе и ещё другое обсуждение этого же вопроса). Гарантировано получить уведомление о готовности API для работы можно другим способом.

У загрузчика карт есть недокументированный параметр onload, в котором можно указать имя функции. Эта функция как раз будет вызвана, когда будут загружены все требуемые модули карты.


function loadYandexMaps(callback) {
    var callbackName = "_myapp_map_init",
        loaderUrl = "http://api-maps.yandex.ru/2.0/?" +
            "load=package.standard&" +
            "lang=ru-RU&" +
            "onload=" + encodeURIComponent(callbackName); 
    if (!window['ymaps']) {
        window[callbackName] = function () {
            callback();
            window[callbackName] = null;
        };
        yepnope.injectJs(loaderUrl);
    } else {
        callback();
    }
}

Загрузчик карт добавляется на страницу с помощью yepnope.js только тогда, когда он реально потребуется на странице.

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

Комментарии к заметке: 1

Подсветка области клика на iOS

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

Цвет этой подсветки задается с помощью CSS свойства -webkit-tap-highlight-color.

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

Предположим, что нас интересует только клик по элементу с классом item__add.


$(".list").on("click", ".item__add", function () { … });

Но подсветка будет активироваться у элемента с классом list , так как именно на него повешен обработчик события. Исправим это CSS свойством в селекторе .list.


.list {
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
Комментарии к заметке: 3

Нелинейная шкала слайдера

Когда слайдере нужно использовать для ввода несоизмеримых по величине данных (например, от 1 тысячи до 10 миллионов рублей), то разумнее использовать какую-то нелинейную шкалу. В частности, для ввода сумм подходящей шкалой будет логарифмическая (по основанию 10).

Для сравнения приведу два слайдера с линейной и нелинейной шкалой.

Нелинейная система координат

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


function fromSlider(value) {
    return Math.round(Math.pow(10, value));
}

function toSlider(value) {
    return Math.log(value) / Math.log(10);
}

Теперь там где нужно установить значение в слайдер используем toSlider, а там где получаем значение из слайдера — fromSlider.


$(".logarithmic__slider").slider({
    min: toSlider(1000),
    max: toSlider(10000000),
    step: 0.01,
    value: toSlider(initialValue),
    slide: function (e, ui) {
        $(".logarithmic__value").html(fromSlider(ui.value));
    }
});

Округление и форматирование

Чтобы данные выглядели презентабельно их хорошо бы ещё округлить и отформатировать.


function round(n, threshold) {
    var digits, out;

    n = n.toFixed(0);
    digits = n.length;
    out = n.substr(0, Math.min(digits, threshold));

    if (digits > threshold) {
        out = out + "000000000000".substr(0, digits - threshold);
    }

    return parseInt(out);
}

Функция оставляет только указанное количество значимых разрядов в числе. Остальные будут обнулены.


function splitGroups(n, delim) {
    var digits;

    delim = delim || '<span class="tsp"> </span>';

    n = n.toFixed(0);
    digits = n.length > 3 ? n.length % 3 : 0;

    return (digits ? n.substr(0, digits) + delim : '') +
        n.substr(digits).replace(/(\d{3})(?=\d)/g, "$1" + delim);
}

А эта функция разделяет группы разрядов числа. В качестве разделителя по умолчанию я использую пробел половинной ширины.


.tsp {
    font-size: 50%;
    line-height: 1;
}

Или можно указать требуемый разделитель вторым параметром функции.

Комментарии к заметке: 1

Навигация по ссылкам в списках

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

Список авторов статей в блоге

Каждый элемент в списке содержит имя, фотографию и краткую биографию автора. Имя и фотография обрамлены ссылками на архив статей этого автора.


<ul class="authors">
  <li class="author">
    <div class="author-userpic">
      <a class="author-archive-link" title="Vicki Moyes" href="/author/vicki/">
        <img class="author-pic photo" alt="Vicki Moyes" src="/img/users/vicki-moyes.jpg">
      </a>
    </div>
    <p class="author-title">
      <a href="/author/vicki/" class="author-title-archive-link">Vicki Moyes</a>
    </p>
    <p class="author-bio">Director of Moyes Gliders.
      Organizer of annual Forbes competition.</p>
  </li>
</ul>

Используем tabindex=-1

Элементы, обрамленные ссылками

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

Проектируя интерфейс, первостепенно внимание уделяется пользователям, работающим с мышью или touch-интерфейсом. Кому-то из них привычнее и удобнее кликать по картинкам, а кто-то кликает только по явно обозначенным ссылкам. Поэтому удалить ссылку, обрамляющую фотографию, нельзя. Но зато можно сделать так, чтобы она не участвовала в последовательности переключения фокуса с клавиатуры. Для этого добавим ей атрибут tabindex="-1".

Переходы только по именам авторов

Такой нехитрый прием позволяет значительно улучшить впечатления пользователя от интерфейса и сделать его поведение более предсказуемым.

Одна ссылка

В этом примере два находящиеся рядом объекта (фотография и имя автора) должны вести на одну и ту же страницу. Технически их можно обернуть одной ссылкой. В HTML5 внутри строчного элемента a могут находиться как строчные, так и блочные элементы.


<a href="page.html">
    <div><img src="img1.jpg" alt="Page image"></div>
    <p>Page title</p>
</a>

Фрагмент кода валиден на 100%, только если используется в HTML5 документе.

Комментарии к заметке: 4

Порядок элементов виджета Sortable

У виджета jQuery Sortable помимо метода serialize есть еще другой метод, который можно использовать для сохранения порядка сортировки элементов, — toArray. Его отличие заключается в том, что он возвращает массив id элементов, а не просто строку.


<ul id="search-engines">
  <li id="item-1">Яндекс</li>
  <li id="item-3">Bing </li>
  <li id="item-2">Google</li>
</ul>

Получаем массив

var engines = $("#search-engines").sortable("toArray");

В результате в переменной engines будет массив ["item-1", "item-3", "item-2"].

toArray будет полезен, скорее всего, в ситуациях, когда требуется пост-обработка данных (например, фильтрация или переименование ключей) перед сохранением.

Комментарии к заметке: 2