Заметки за август 2012 года

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

В 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

Особенности @param в JsDoc

В комментариях я использую разметку JsDoc. Есть утилиты, которые автоматически строят документацию, основываясь на этой разметке. Ещё она польза заключается в том, что статические анализаторы в IDE умею проверять использование прокомментированных функций.

С перечнем аннотаций, их параметрами и примерами использования можно ознакомиться, например, в документации к генератору jsdoc-toolkit.

Самой популярной, пожалуй, аннотацией является @param.

@param {paramType} paramName paramDescription
  • paramType — опциональный: ожидаемый тип параметра;
  • paramName — обязательный: название параметра;
  • paramDescription — опциональный: описание параметра.

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

/**
 * @param {Number|String} value
 */
function showValue(value) {
    alert(value);
}

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

var uidx = 1;
/**
 * Generate an id that is unique among the application
 * @param {String} [prefix] optional guid prefix
 */
function guid(prefix) {
    return (prefix || 'app') + '-' + uidx++;
}

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

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

Равномерное выравнивание блоков по ширине

Подсказали шикарную статью про «равномерное выравнивание блоков по ширине». Решение работает с произвольным количеством блоков различных габаритов даже в самых старых, но всё ещё популярных, браузерах.

За базу берётся обычный список, построенный на элементах ul и li. Всем элементам списка назначается display: inline-block, а сам список получает стиль text-align: justify. А дальше идут мелочи и тонкости, которые в итоге и заставляют все блоки равномерно разместиться в контейнере, даже если они сами имеют разную ширину.

Равномерное выравнивание блоков по ширине

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

Как git rebase помогает управлять коммитами

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

Но, нигде не упоминается об интерактивном режиме и его возможностях. В этом режиме можно переставлять коммиты местами, объединять и разделять их, менять комментарии у произвольного коммита. Всё это может понадобиться, если использовать подход «микрокоммитов».

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

Копирование файлов по SSH

Традиционным способом копирования файлов по SSH является команда scp.

scp *.js user@remote-host.com:~/folder/

Все файлы с расширением js из текущей папки будут скопированы на сервер remote-host.com в папку folder в домашней директории пользователя user.

Можно так же копировать папку вместе со всеми файлам и вложенными папками:

scp -r src user@remote-host.com:~/folder/

А теперь нетрадиционный способ:

tar -c src | ssh user@remote-host.com "cd ~/folder/ && tar -x"

Папка src архивируется утилитой tar. Затем этот архив передается на сервер по SSH, где выполняется команда cd с указанными параметрами и распаковывается полученный архив.

Пример чуть сложнее:

npm run build && \
DEPLOY_TARGET=$(date +%Y%m%d-%H%M%S) && \
tar -c build | \
ssh -t mista_k@slim.local \
  `cd /var/www && \
  mkdir -p $DEPLOY_TARGET && \
  tar -x -C $DEPLOY_TARGET --strip-components 1 -v && \
  ln -sfn $DEPLOY_TARGET build`
Комментарии к заметке: 4