11.11.2008

Книги по JavaScript

За последние пару лет появилось много хороших книг по яваскрипту, что не может не радовать. Еще совсем недавно можно было посоветовать только «наименее плохую» книгу (Флэнагана). Сегодня же я могу порекомендовать вам три отличные книги.

John Resig
Pro JavaScript Techniques
Книга недавно вышла на русском языке

Джон Ресиг (JavaScript-евангелист в Mozilla Corporation и автор библиотеки jQuery) в своей книге рассказывает об объектно-ориентированном JavaScript, написании кода для повторного использования, тестировании и отладке, DOM, Events, Ajax.

К сожалению, в книге невероятно много опечаток, в том числе в примерах кода, что особенно неприятно. Также не понравилось, что иногда вместо подробного объяснения какой-либо темы, Ресиг приводит ссылки на статьи в интернете (на того же Крокфорда) где эта тема раскрыта. Я люблю уютно устроиться долгим зимним вечером в обнимку с книгой, и хочу чтобы книга была самодостаточна, чтобы не нужно было ползти за ноутбуком.

Оценка: 4

Не смотря на эти недостатки, я собираюсь заказать следующую книгу Ресига — Secrets of the JavaScript Ninja, выход которой запланирован на конец 2008 года. Оглавление выглядит впечатляюще и многообещающе.

Douglas Crockford
JavaScript: The Good Parts

Дуглас Крокфорд (главный по JavaScript в Yahoo!) хорошо известен как один из самых крутых специалистов по JavaScript. Дуглас — автор формата обмена данными JSON и сервиса по проверке корректности кода JSLint. Надо сказать, что его мегамощные лекции и статьи меня реально торкнули, поэтому его книгу я ждал с особым нетерпением.

Книга невелика по объему (всего 145 страниц), но насыщена информацией. Крокфорд пишет просто и понятно, без многословных и замысловатых выражений. Я не всегда стопроцентно с ним согласен, тем не менее, его аргументы весьма разумны, а его мнение стоит того, чтобы к нему прислушаться.

Что мне особенно понравилось в книге Крокфорда (а также в JSLint) — это внимание к стилю написания кода, как сделать код максимально ясным, кратким, однозначным, как уменьшить шанс возникновения ошибок.

Оценка: 5, must read

Ross Harmes, Dustin Diaz
Pro JavaScript Design Patterns

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

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

Оценка: 5+, must read

01.11.2008

Типовой лейаут страницы

Особенности:

  • Standards mode
  • Минимальная и максимальная ширина
  • При растяжении больше максимальной ширины макет центрируется
  • Футер всегда прибит к низу страницы

Тестовая страница

Простой пример использования

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <title>Sample layout</title>
        <link rel="stylesheet" type="text/css" href="main.css"/>
        <!--[if lte IE 6]><link rel="stylesheet" type="text/css" href="main-ie6.css"/><![endif]-->
    </head>
    <body>
        <div id="outer">
            <div id="header">header</div>
            <div id="content">content</div>
        </div>
        <div id="footer">footer</div>
    </body>
</html>

main.css

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
}

body {
    color: #000;
    background-color: #fff;
    font-family: Arial, sans-serif;
    font-size: 0.8em;
    line-height: 1.4;
    text-align: center;
}

#outer {
    min-height: 100%;
}

#outer,
#footer {
    min-width: 700px;
    max-width: 1400px;
    margin: auto; /* center it */
    text-align: left;
}

#header {
    background-color: #66cc66;
}

#content {
    padding-bottom: 3.2em;
}

#footer {
    height: 2.6em;
    margin-top: -2.6em;
    background-color: #ff8080;
}

main-ie6.css

#outer {
    height: 100%;
}

#outer,
#footer {
    width: expression(document.documentElement.clientWidth < 700 ? '700px' : document.documentElement.clientWidth < 1400 ? '100%' : '1400px');
}

19.10.2008

Новый iepngfix.htc

Наверняка многие из вас пользовались популярным скриптом iepngfix.htc, который исправляет полупрозрачные PNG в IE 6. Скрипт умеет фиксить как PNG-изображения <img>, так и PNG заданные бекграундом. Основным недостатком этого инструмента было отсутствие поддержки background-position и background-repeat — эти параметры игнорировались. К счастью, Angus Turnbull, автор iepngfix, недавно выпустил новую версию v2.0 Alpha 3, лишенную этого недостатка. В новой версии добавился еще один файл iepngfix_tilebg.js, в котором находится метод IEPNGFix.tileBG.

UPD. Коллега наткнулся на еще одну JS-библиотеку для исправления полупрозрачных PNG в IE 6 — DD_belatedPNG. Также есть поддержка background-position и background-repeat, но подход принципиально другой: вообще отказ от AlphaImageLoader и вместо этого использование VML.

12.10.2008

XSL: применение шаблона с «внутренним» условием

Часто бывает нужно применить шаблон для элемента только если этот элемент (или его содержимое) удовлетворяет некоторому условию. Простой пример: применить шаблон для элемента <Brands> если внутри есть хотя бы один элемент <Brand>. Рассмотрим несколько вариантов как можно сделать эту проверку.

Вариант 1

<xsl:template match="Something">
    <xsl:if test="Brands/Brand">
        <xsl:apply-templates select="Brands"/>
    </xsl:if>
</xsl:template>

<xsl:template match="Brands">
    <h2>Производители</h2>
    <ul>
        <xsl:apply-templates select="Brand"/>
    </ul>
</xsl:template>

Неудачное решение, поскольку, написав проверку в шаблоне для <Something>, мы поместили в этот шаблон знание об особенности трансформации <Brands>.

Вариант 2

<xsl:template match="Something">
    <xsl:apply-templates select="Brands[Brand]"/>
</xsl:template>

<xsl:template match="Brands">
    <h2>Производители</h2>
    <ul>
        <xsl:apply-templates select="Brand"/>
    </ul>
</xsl:template>

Немного компактнее, но проблема первого варианта осталась.

Вариант 3

<xsl:template match="Something">
    <xsl:apply-templates select="Brands"/>
</xsl:template>

<xsl:template match="Brands">
    <xsl:if test="Brand">
        <h2>Производители</h2>
        <ul>
            <xsl:apply-templates select="Brand"/>
        </ul>
    </xsl:if>
</xsl:template>

Гораздо лучше. Шаблон для <Something> просто вызывает шаблон для <Brands>, не заморачиваясь о внутреннем устройстве <Brands>. Шаблон для <Brands> сам разбирается как трансформировать <Brands>.

Вариант 4

<xsl:template match="Something">
    <xsl:apply-templates select="Brands"/>
</xsl:template>

<xsl:template match="Brands"/>
<xsl:template match="Brands[Brand]">
    <h2>Производители</h2>
    <ul>
        <xsl:apply-templates select="Brand"/>
    </ul>
</xsl:template>

Я предпочитаю этот вариант. Он также хорошо работает и в случае с несколькими условиями — вместо громоздкого <xsl:choose> мы получаем компактные шаблончики.

<xsl:template match="Brands"/>

<xsl:template match="Brands[Brand]">
    <h2>Производители</h2>
    <ul>
        <xsl:apply-templates select="Brand"/>
    </ul>
</xsl:template>

<xsl:template match="Brands[count(Brand) > 10]">
    <h2>Много производителей</h2>
    <!-- Выводим бренды в три колонки -->
</xsl:template>

24.09.2008

Ссылка цветом текста

Задача: сделать ссылки цветом текста. При этом в разных блоках на странице цвет текста может меняться.

Сначала я указал цвет ссылки отдельно для каждого блока.

body {color: black;}
a.glossary {color: black;}
#shurum, #shurum a.glossary {color: red;}
#burum, #burum a.glossary {color: green;}

Потом я подумал, что ведь цвет ссылки можно наследовать от блока.

body {color: black;}
a.glossary {color: inherit;}
#shurum {color: red;}
#burum {color: green;}

Радости моей не было предела, пока я не открыл страницу в IE. Фак! Оба осла (6 и 7) не поддержали мою гениальную задумку и ни хрена не пронаследовали цвет. Тогда я достал большую базуку и замочил IE вдребезги пополам написал маленький экспрешн.

a.glossary {color: expression(this.parentNode.currentStyle.color);}

Лучше, конечно, написать одноразовый экспрешн (не стал здесь так делать для наглядности).

15.09.2008

IE 6 занял место Netscape 4

Лет 6—7 назад все ненавидели Netscape 4. Чтобы добиться нормального отображения страницы в Netscape 4, верстали исключительно таблицами, делали распорки, а о семантической верстке не шло и речи. Как только его не обзывали — Нетшкаф, Нетглюк, Нафигатор. Но постепенно сайты отказывались от A-grade поддержки Netscape 4. Я помню этот радостный момент, когда Студия объявила о прекращении полноценной поддержки Netscape 4 — все технологи со слезами на глазах обнялись и поздравили друг друга.

Сейчас место «браузера-изгоя тормозящего развитие веба» занял IE 6. Хотя говорить о прекращении A-grade поддержки IE 6 еще рано (думаю, придется еще пару лет с шестым ослом помучиться), тенденция к этому уже наметилась — все чаще встречаются сайты где что-то отвалилось или разъехалось в IE 6.

Ссылка по теме: Graded Browser Support

01.09.2008

JavaScript: область видимости переменных

В JavaScript область видимости переменных не ограничивается блоком {}, а ограничивается только функцией. Например, переменные объявленные внутри for или if продолжают жить после того, как эти for и if отработали.

for (var i = 0; i < 10; i += 1) {
    var a = i * i;
    // do something
}
document.writeln(i);    // 10
document.writeln(a);    // 81

if (true) {
    var b = "test";
    // do something
}
document.writeln(b);    // test


Поэтому, лучше явно обозначить это в коде.

var i, a;
for (i = 0; i < 10; i += 1) {
    a = i * i;
    // do something
}

var b;
if (true) {
    b = "test";
    // do something
}


Во многих языках программирования рекомендуется объявлять переменные как можно ближе к месту первого использования. В JavaScript все используемые в функции локальные переменные лучше объявлять в самом начале функции.

var myFunction = function () {
    // Объявление всех локальных переменных, включая переменные циклов
    // Код функции
}

04.08.2008

Простое правило для маргинов

При задании отступов у блоков я придерживаюсь простого правила — задаю отступы справа и снизу.

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

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

Это правило позволяет уменьшить зависимость блоков от окружения, то есть повышает универсальность верстки.

02.08.2008

Элементы с id порождают глобальные переменные в JS

Для всех элементов с атрибутом id в джавасрипте создается глобальная переменная. Следующий пример во всех браузерах выдаст алерт с "DIV".

<html>
<head>
    <script>
        window.onload = function () {
            alert(myDiv.tagName);
        };
    </script>
</head>
<body>
    <div id="myDiv">test</div>
</body>
</html>

Это плохо, но в принципе не страшно, если вы:

  • Избегаете создавать свои глобальные переменные.
  • Не забываете объявлять свои переменные. Если вы забыли объявить переменную (var myVar), то джавасрипт считает, что это глобальная переменная (implied global variable).

04.07.2008

Названия картинок

Советую не использовать в названии обычных картинок слова banner, promo и ad. У многих пользователей стоят блокировщики рекламы (например Adblock), которые не показывают такие картинки. Кстати, веб-разработчику не помешает проверять свои сайты в браузере с установленным блокировщиком рекламы.

Названия баннеров, наоборот, нужно честно начинать со слова banner, чтобы их не видели те, кто не хочет их видеть.