Заметки за 2013 год (страница 2)

Операции над коллекциями объектов Backbone.js

Для работы с коллекциями в Backbone.js импортируется 28 методов из библиотеки Underscore.js. Среди них, пожалуй, самыми востребованными являются .forEach(), .filter(), .reject(), .find(), .without().

Предположим, что нужно найти в коллекции элементы, соответствующие определённому условию и уничтожить их.


var boxes = new Boxes(); // коллекция объектов
// предположим, что она уже заполнена нужными данными
var boxesToDestroy = boxes.filter(function (box) {
  return box.isReadyToDestroy();
});
_.forEach(boxesToDestroy, function (box) {
  box.destroy();
});

Выглядит громоздко. Всё это по тому, что методы Underscore.js возвращают массив, а не новый экземпляр коллекции.

Благо в Underscore.js есть метод .chain(), который позволяет всё значительно упростить.


boxes.chain()
  .filter(function (box) { return box.isReadyToDestroy(); })
  .forEach(function (box) { box.destroy(); });

Этот код можно ещё упростить, воспользовавшись методом .invoke().


boxes.chain()
  .filter(function (box) { return box.isReadyToDestroy(); })
  .invoke("destroy");

Так можно стоить цепочки из любых операций над элементами коллекции. Если по завершению цепочки нужно будет сохранить результат выборки в переменную, то последним вызовем метод .value().

Оставте свой комментарий

Заголовок для поля ввода и его доступность

Подпись или заголовок для поля ввода размечается тегом <label>. Наличие связанного с ним элемента <input>, <textarea> или <select> не является обязательным условиям. Хотя, при отсутствии такого элемента, сам заголовок приобретает другой смысл и может быть размечен другим тегом.

<label> может быть как обёрткой для поля ввода, так и быть связанным с ним с помощью атрибутов. Вот несколько типовых вариантов разметки:

Вариант №1:

<label>
  Фамилия <input type="text" name="family-name">
</label>

Вариант №2:


<label for="family-name-field">Фамилия</label>
<input id="family-name-field" type="text" name="family-name">

Клик по надписи в обоих случаях приведёт к том, что связанное с этой надписью поле ввода получит фокус. В первом случае связь инпута и лейбла определяется явно (фокус получает первое дочернее поле ввода). Во втором случае связь осуществляется с помощью атрибута id у поля ввода и аналогично значения у атрибута for лейбла.

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

Подсказка в поле ввода

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


<input type="text" placeholder="Фамилия" name="family-name">

Но не стоит путать подсказку и подпись.

Доступность

Но совсем отказываться от <label> нельзя из-за того, что вспомогательные технологи не зачитывают подсказки. Тег нужно оставить в разметке, но скрыть его от пользователя.


<label for="family-name-field" class="hidden">Фамилия</label>
<input id="family-name-field" type="text"
    placeholder="Фамилия" name="family-name">

Скрыв подпись к полю ввода с помощью стиля display: none , мы не решили проблему с доступностью текста подписи. Вспомогательные технологии игнорируют элементы, к которым применён такой стиль.

Вернуть видимость текста можно опять же несколькими способами.

Способ №1


<label>
  <span class="hidden">Фамилия</span>
  <input type="text" placeholder="Фамилия" name="family-name">
</label>

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

Скринридеры понимает, что <label> видим для пользователя и зачитывает его содержимое, не обращая внимания на то, что оно оказывается скрытым.

Способ №2


<label id="family-name-label"
    for="family-name-field" class="hidden">Фамилия</label>
<input aria-labelledby="family-name-label"
    id="family-name-field" type="text"
    placeholder="Фамилия" name="family-name">

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

Как вариант, явно указать подпись можно с помощью атрибута aria-label.

Способ №3


<label for="family-name-field" class="visuallyhidden">Фамилия</label>
<input id="family-name-field" type="text"
    placeholder="Фамилия" name="family-name">

Класс visuallyhidden выключает элемент из потока и делает его размеры 1×1 пиксель. Формально подсказка остаётся видимой и зачитывается ридерами, но фактически её не видно на экране.

У всех способов есть свои плюсы и минусы:

  • первый вариант оказался в итоге самым компактным и универсальным, но появился дополнительный элемент в разметке;
  • второй вариант самый громоздкий (требуется слишком много атрибутов и два уникальных идентификатора), но в то же время и самый надёжный;
  • третий вариант выглядит хорошим компромиссом, если не позаботиться о том, чтобы id инпута не повторялся на странице.
Комментарии к заметке: 2

Истинные размеры изображения

Когда картинка появилась на странице, то к ней сразу же начинают применяться стили и узнать её истинные габариты через свойства width и height уже нельзя.

Во всех современных браузерах (включая IE9 и старше) есть свойства naturalWidth и naturalHeight , которые после полной загрузки картинки принимают значения ширины и высоты изображения, соответственно.

var img = document.getElementById("gallery-image"),
    width = img.naturalWidth,
    height = img.naturalHeight;

В IE8 и младше этих свойств нет. Получить не модифицированные размеры можно, если создать новый элемент с тем же самым значением атрибута src и уже у него прочитать свойства width и height.


function getDimensions(sourceImage) {
    var img = new Image();
    img.src = sourceImage.src;
    return {
        width: img.width,
        height: img.height
    };
}
Комментарии к заметке: 2

Ридер для документации популярных проектов и технологий

DevDocs представляет собой оболочку для просмотра документации популярных проектов: Angular.js, Backbone.js, Ember.js, jQuery, jQuery UI, jQuery Mobile, Lo-Dash, Underscore.js. Так же в проекте есть документация по самым базовым технологиям: HTML, CSS, JavaScript, HTTP, и проектами, созданных на их основе: Node.js, Less, Sass.

Ридер имеет удобный быстрый поиск по выбранным проектам и продуманную навигацию с клавиатуры.

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

Охота за последним видимым элементом

Последний элемент среди соседей можно выбрать селектором псевдо-класса :last-child.


.item { display: block; }
.item:last-child { font-weight: bold; }

Разметка:


<div>
  <div class="item item_rank_1">Object “A”</div>
  <div class="item item_rank_1">Object “B”</div>
  <div class="item item_rank_0">Object “C”</div>
</div>

Но, если с помощью медиа-запроса скрыть часть элементов списка, то получить последний видимый элемент уже так просто не выйдет.


@media (max-width: 600px) {
  .item_rank_0 { display: none; }
}

Казалось бы можно использовать селектор .item_rank_1:last-child , но это так не работает. Псевдо-класс :last-child позволяет найти только одного последнего ребёнка своего родителя.

Но мы уже живём в мире HTML5, где можно грабить корованы и придумывать свои собственные теги (оригинал ). По этому вместо того, чтобы отличаться классами, элементы будут отличаются названиями тегов.


<div>
  <item-rank-1 class="item">Object “A”</item-rank-1>
  <item-rank-1 class="item">Object “B”</item-rank-1>
  <item-rank-0 class="item">Object “C”</item-rank-0>
</div>

Да, так тоже можно, если очень хочется.

Теперь в медиа-запросе можно использовать селектор :last-of-type для того, чтобы получить последний элемент группы, которая не была скрыта.


@media (max-width: 600px) {
  item-rank-0.item { display: none; }
  item-rank-1:last-of-type { font-weight: bold; }
}

Таким способом можно создавать любые теги и они будут прекрасно поддаваться оформлению через CSS. Для IE < 9 нужно будет их предварительно создать с помощью JavaScript так как делаем это для новых HTML5 элементов.

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

Живой пример

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

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