Введение в jQuery

О HTML, CSS и JavaScript

Разбить на страницы
Показывать лекцию целиком

Начнём знакомство с jQuery с повторения (или изучения) основ правильного употребления связки HTML и CSS с небольшой примесью JavaScript.

Если не хотите упасть в грязь лицом перед коллегами — то не пропускайте данную главу "мимо ушей".

HTML — о нём стоит помнить две вещи – семантический и правильный.

Семантическая вёрстка

Семантическая вёрстка HTML документа подразумевает использование тегов по прямому назначению, т.е. если вам необходим заголовок – то вот тег <h1> и собратья, необходима табличное представление данных – используйте тег <table> и только его.

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

Забегая чуть-чуть вперёд, стоит упомянуть теги из спецификации HTML5:

<article>, <aside>, <header>, <footer>, <menu>, <section> и т.д. — используйте их, не бойтесь.

Не бояться — это правильно, но использовать тоже надо с умом, рекомендую ресурс http://htmlbook.ru/html5 — очень хорошо и подробно расписано о нововведениях спецификации HTML5.

И еще парочка интересных ресурсов в нагрузку:

  • http://htmlbook.ru/html5 — неплохо, и на русском
  • http://www.html5rocks.com/en/ — тут целое сообщество
  • Старайтесь избегать избыточных элементов на странице, большинство HTML страниц грешат лишними блочными элементами:

    <div id="header"> 
    <div id="logo">
    <h1><a href="/">Мой блог</a></h1> 
    </div>
    <div id="description">
    <h2>Тут я делюсь своими мыслями</h2> </div>
    </div>
    

    Данную конструкцию можно легко упростить, и при этом код станет более читаемым, изменения в CSS будут минимальными (или даже не потребуются):

    <header> 
    <h1>
    <a href="/">Мой блог</a>
    </h1>
    <h2>Тут я делюсь своими мыслями</h2> 
    </header>
    

    В английском языке есть термин "divits" – сим термином награждают HTML- разметку с чрезмерным использованием div’ов без потребности, я же обзываю такие творения "дивными". Обычно таким грешат новички, которые для применения стилей CSS оборачивают элементы в div’ы, что и приводит к их размножению без нужды.

    Ещё одним обязательным пунктом для создания "правильного" HTML является использование названий классов и идентификаторов, которые однозначно говорят нам о содержимом элемента, а не о каких либо нюансах оформления, приведу пример:

    Плохо
    red, green и т.д. в какой-то момент захотите перекрасить, и элемент с классом "red" будет синего цвета
    wide, small и т.д. сегодня широкий, а завтра?
    h90w490 наверное, это элемент с высотой 90px и шириной 490px, или я ошибаюсь?
    b_1, ax_9 эти название тоже ни о чем не говорят
    color1, color2 и т.д. иногда встречается для "скинованных" сайтов, но создают такие классы из лени
    element1...20 такое тоже встречается, и ничем хорошим не пахнет

    Ну и примеры правильного именования:

    Хорошо
    logo, content логотип, основной контент
    menu, submenu меню и подменю
    even, odd чётный и нечётный элементы списка
    paginator постраничная навигация
    copyright копирайт

    Есть ещё один момент – это форматирование HTML и CSS кода, я не буду заострять на нём внимание, но весь код в книге будет отформатирован отступами, и, возможно, это даст свои плоды в ваших творениях.

    Валидный HTML

    Зеленый маркер W3C validator'а – это правильно, и к этому надо стремится, так что не забывайте закрывать теги, да прописывать обязательные параметры, приведу пример HTML кода, в котором допущено 6 ошибок (согласно спецификации HTML5), найдите их:

    <h2>Lorem ipsum
    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc urna metus, ultricies eu, congue vel, laoreet id, justo. Aliquam fermentum adipiscing pede. Suspendisse dapibus ornare quam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. <p>
    <a href="/index.php?mod=defaultact=image"><img src="/img001.jpg"></a>
    

    CSS-правила и селекторы

    Теперь приступим к CSS, и начнём, пожалуй, с расшифровки аббревиатуры CSS это Cascading Style Sheets, дословно "каскадная таблица стилей", но:

    — Почему же она называется каскадной? — этот вопрос я часто задаю на собеседованиях претендентам. Ответом же будет аналогия, ибо она незыблема как перпендикулярная лягушка: представьте себе каскад водопада, вот вы стоите на одной из ступенек каскада с чернильницей в руках, и выливаете ее содержимое в воду — вся вода ниже по каскаду будет окрашиваться в цвет чернил. Применив эту аналогию на HTML — создавая правило для элемента, вы автоматически применяете его на все дочерние элементы (конечно, не все правила так работают, но о них позже) — это наследование стилей. Теперь, если таких умников с чернильницей больше чем один, и цвета разные, то в результате получим смешение цветов, но это в жизни, а в CSS работают правила приоритетов, если кратко:

  • самый низкий приоритет имеют стили браузера по умолчанию — в разных браузерах они могут отличаться, поэтому придумали CSS Reset (гуглится и юзается), и все будут на равных
  • чуть важнее — стили заданные пользователем в недрах настроек браузера, встречается редко
  • самые важные — стили автора странички, но и там всё идёт по порядку
  • самый низкий приоритет у тех, что лежат во внешнем подключённом файле
  • затем те, что встроили внутрь HTML с помощью тега <style>
  • потом те, что захардкодили плохие люди (не вы, вы так делать не будете) в атрибуте "style"
  • самый высокий приоритет у правил с меткой "!important"
  • при равенстве приоритетов, тапки у того, кто объявлен последним
  • Если голова ещё не бо-бо, то я также упомяну, что при расчёте, чьи же правила главней, ещё анализируется специфичность селекторов, и тут считается следующим образом:

    за каждый идентификатор получаем [1:0:0] (#id)

    за каждый класс, либо псевдо класс — [0:1:0] (.my :pseudo)

    за каждый тег — [0:0:1] (div a)

    При этом [1:0:0] > [0:x:y] > [0:0:x].

    Пример селекторов, выстроенных по приоритету (первые важнее):

    #my p#id — [2:0:1] 
    #my #id — [2:0:0] 
    #my p — [1:0:1] 
    #id — [1:0:0]
    .wrapper .content p — [0:2:1]
    .content div p — [0:1:2]
    .content p — [0:1:1] 
    p — [0:0:1]
    

    Пример HTML-кода:

    <!DOCTYPE html>
    <html dir="ltr" lang="en-US">
    <head>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Приоритет CSS селекторов</title>
        <link rel="profile" href="http://gmpg.org/xfn/11"/>
        <link rel="shortcut icon" href="http://anton.shevchuk.name/favicon.ico"/>
        <link rel="stylesheet" href="css/styles.css"/>
    	<script type="text/javascript" src="js/jquery.js"></script>
    	<script type="text/javascript" src="js/code.js"></script>
        <script>
            function appendStyle(rule) {
                $('head').append('<style>'+rule+'</style>');
            }
        </script>
    </head>
    <body>
    <div class="wrapper">
        <menu>
            <a href="css.float.html" title="go prev" class="button alignleft" rel="prev">← Prev </a>
            <a href="index.html" title="back to Index" class="button alignleft" rel="index">Index §</a>
            <a href="css.selectors.html" title="go next" class="button alignright" rel="next">Next →</a>
            <hr/>
    		<h3>Шпаргалка</h3>
    <pre><code><em>// weight</em>
    #id    = [1,0,0]
    .class = [0,1,0]
    tag    = [0,0,1]
    <em>// compare</em>
    [1,0,0] > [0,1,0] > [0,0,1]
    [1,0,0] > [0,100,100]
    [0,1,0] > [0,0,100]
    </code></pre>
            <hr/>
            <pre><code contenteditable="true">appendStyle(<span>'p { color:orange }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'.content p { color:green }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'article.content p { color:blue }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'.wrapper .content p { color:red }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'#id { color:darkblue }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'#my p { color:darkcyan }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'#my #id { color:darkgreen }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'#my p#id { color:black }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
        </menu>
        <header>
            <h1>Приоритет CSS селекторов</h1>
            <h2>Сохраните страницу и попробуйте изменить CSS стили</h2>
        </header>
        <article id="my" class="content">
            <h2>Article Title</h2>
            <p id="id">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus rutrum,
            lectus eu varius consectetur, libero velit hendrerit augue, ut posuere enim neque
            in libero. Donec eget sagittis nibh. Suspendisse sed tincidunt urna. Cras quis
            euismod neque. Maecenas auctor ultricies posuere. Pellentesque luctus pulvinar dui
            eget semper. Donec sodales odio eu sapien varius luctus. Donec dictum feugiat diam
            at malesuada. Sed nec massa in augue condimentum faucibus quis ut diam. Quisque
            nisl sem, semper nec vulputate vel, mattis sit amet justo. Aliquam purus felis,
            tempor at scelerisque quis, tincidunt in neque. Etiam ut risus diam. Pellentesque
            fermentum risus id elit feugiat cursus. Ut fringilla dictum diam, sed iaculis
            lorem pulvinar ut. Cras vel elit id velit commodo viverra sit amet vel orci.</p>
        </article>
        <footer>
            ©copyright 2014 Anton Shevchuk — <a href="http://anton.shevchuk.name/jquery-book/">jQuery Book</a>
        </footer>
        <script type="text/javascript">
            var _gaq = _gaq || [];
            _gaq.push(['_setAccount', 'UA-1669896-2']);
            _gaq.push(['_trackPageview']);
            (function() {
             var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
             ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
             var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
            })();
        </script>
    </div>
    </body>
    </html>
    <div class="wrapper">
    <div id="my" class="content"> 
    <p id="id">
    Lorem ipsum dolor sit amet, consectetuer...
    </p>
    </div>
    </div>
    

    При равенстве счета — последний главный.

    Говорят, что правило с 255 классами будет выше по приоритету, нежели правило с одним "id", но я надеюсь, такого кода в реальности не существует

    Вот такое краткое вступительное слово, но пора вернуться к jQuery. Так вот, работая с jQuery, вы должны "на отлично" читать правила CSS, а также уметь составлять CSS-селекторы для поиска необходимых элементов на странице. Но давайте обо всем по порядку, возьмём следующий простенький пример вполне семантического HTML:

    <!DOCTYPE html>
    <html dir="ltr" lang="en-US"> 
    <head>
    <meta charset="UTF-8"/> 
    <title>Page Title</title>
    <link rel="profile" href="http://gmpg.org/xfn/11"/> 
    <style type="text/css">
    body {
    font: 62.5%/1.6 Verdana, Tahoma, sans-serif; color: #333333;
    }
    h1, h2 {
    color: #ff6600;
    }
    header, main, footer { margin: 30px auto; width: 600px;
    }
    #content { padding: 8px;
    }
    .box {
    border:1px solid #ccc; border-radius:4px; box-shadow:0 0 2px #ccc;
    }
    </style>
    </head>
    <body>
    <header>
    <h1>Page Title</h1> 
    <p>Page Description</p>
    </header>
    <main id="content" class="wrapper box"> <article>
    <h2>Article Title</h2> <p>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc urna metus, ultricies eu, congue vel, laoreet...
    </p>
    </article>
    <article>
    <h2>Article Title</h2> <p>
    Morbi malesuada, ante at feugiat tincidunt, enim massa gravida metus, commodo lacinia massa diam vel eros...
    </p>
    </article>
    </main>
    <footer>©copyright 2014</footer> 
    </body>
    </html>
    

    Это пример простого и правильного HTML5 с небольшим добавлением CSS3. Давайте разберём селекторы в приведённом CSS-коде (я предумышленно не выносил CSS в отдельный файл, ибо так наглядней):

    body – данные правила будут применены к тегу <body> и всем его потомкам

    h1,h2 – мы выбираем теги <h1> и <h2>, и устанавливаем цвет шрифта #content – выбираем элемент с "id="content"" и применяем правила

    .box – выбираем элементы с "class="box""

    Теперь подробнее и с усложнёнными примерами:

    h1 ищем элементы по имени тега
    #container ищем элемент по идентификатору "id=container" (идентификатор уникален, значит, на странице он должен быть только один)
    div#container ищем <div> c идентификатором container, но предыдущий селектор работает быстрее, но этот важнее
    .news выбираем элементы по имени класса "class="news""
    div.news все элементы <div> c классом news (так работает быстрее в IE8, т.к. в нём не реализован метод "getElementsByClassName()")
    #wrap .post ищем все элементы с классом post внутри элемента с "id = wrap"
    .cls1.cls2 выбираем элементы с двумя классами "class="cls1 cls2""
    h1,h2,.posts перечисление селекторов, выберем всё перечисленное
    .post > h2 выбираем элементы <h2>, которые являются непосредственными потомками элемента с классом "post"
    a + span будут выбраны все элементы <span> следующие сразу за элементом <a>
    a[href^=http] будут выбраны все элементы <a> у которых атрибут "href" начинается с http(предположительно, все внешние ссылки)

    Это отнюдь не весь список, описание же всех CSS3 селекторов можно найти на соответствующей страничке W3C: http://www.w3.org/TR/css3-selectors/

    40% задач, которые вы будете решать с помощью jQuery, сводятся к поиску необходимого элемента на странице, так что знание CSS селекторов обязательно. Вот еще кусочек CSS для тренировки, напишите соответствующий ему HTML (это тоже вопрос с собеседования ;):

    #my p.announce, .tt.pm li li a:hover+span { color: #f00; }

    Пишите прям тут:

    CSS. Погружение

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

    О форматировании

    Нет, я не властен над собой, и таки приведу в качестве примера CSS форматирование, которое я использую:

    /*header*/ 
    header {
    margin-bottom: 16px; 
    font-weight: 400;
    }
    header h1 { 
    color: #999;
    }
    header p {
    font-size: 1.4em; 
    margin-top: 0;
    }
    /*/header*/
    

    Почему это хорошо:

  • такой CSS легко читается
  • есть идентификатор начала и конца блока (можно быстро найти необходимую часть даже в очень большом CSS файле используя поиск по метке "*header")
  • подобное форматирование явно указывает на вложенность элементов
  • и можно легко проследить наследование свойств
  • Я не настаиваю на своём варианте, но хотелось, чтобы вы приняли на вооружение один из многих стандартов форматирования, и всегда следовали ему.

    Именование классов и идентификаторов

    Я уже затрагивал эту тему, когда рассказывал о релевантности HTML, так вот – имена классов могут быть даже такими: "b-service-list__column b-service-list__column_right" и это будет круто, и "must be" – но лишь в рамках действительно больших проектов, и собственно чего я распинаюсь, дам ссылки – информации из них хватит еще на одну книгу ;):

  • Клуб "Блок, Элемент, Модификатор" [http://clubs.ya.ru/bem/]
  • "Что такое БЭМ" [http://bem.github.com/bem-method/pages/beginning/beginning.ru.html]
  • Обязательно изучите – полезно для расширения кругозора, и прокачки скилов

    О цветах

    В WEB используется цветовая модель RGB, следовательно, красный цвет можно записать не только как red, но и ещё несколькими способами:

    p { color: red }
    p { color: #ff0000 }
    p { color: #f00 } /* сокращенная запись, экономит 3 байта */
    p { color: rgb(255, 0, 0) }
    

    Теперь вы без запинки должны назвать цвета #f00, #0f0, #00f, а те, у кого по рисованию было "отлично", назовут и #ff0, #0ff и #f0f ;)

    С появлением CSS3, указывая цвет, мы также можем задать значение альфа-канала, т.е. прозрачность:

    p { color: rgba(255, 0, 0, 1) } /* обычный текст */
    p { color: rgba(255, 0, 0, 0.5) } /* полупрозрачный текст */
    

    Ещё одна примочка CSS3 – это возможность использования цветовой модели HSL (hue saturation lightness – тон, насыщенность и светлота) и HSLA (HSL + α-канал):

    p { color: hsl(  0,	100%,	50%) }	/* красный */
    p { color: hsl(120,	100%,	50%) }	/* зелёный */
    p { color: hsl(240,	100%,	50%) } /* синий */
    p { color: hsla( 0,	100%,	50%, 0.5) } /* полупрозрачный красный */
    

    Для перевода из HSL в RGB существует простой алгоритм, но пока не стоит им себя грузить

    Да кто этим HSL пользуется? Не морочьте себе голову.

    Для тех, кого вопрос со смешанием каналов RGB поставил в тупик, то вот вам наглядное руководство:

    Блочные и строчные элементы

    Опять я буду ссылаться на чей-то учебник – на этот раз от Ивана Сагалаева - http://softwaremaniacs.org/blog/category/primer/, и пусть вас не смущают даты написания статей – они повествуют об основах и актуальность они не потеряют ещё очень долго

    Возможно, вы ещё не знаете, но HTML теги делятся на блочные (block) и строчные (inline). Блочными элементами называют те, которые отображаются как прямоугольник, они занимают всю доступную ширину и их высота определяется содержимым. Блочные теги по умолчанию начинаются и заканчиваются новой строкой — это <div>, <h1> и собратья, <p> и другие.

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

    Одна из самых часто встречаемых ошибок, это оборачивание заголовка в ссылку: <a href="#"><h1>Название статьи</h1></a>, не допускайте подобные промахи

    Хотя если мы ориентируемся на HTML5 – то тег <a> теперь может быть блочным элементом, и приведённый пример будет валидным. Ага, вот такой я не последовательный.

    По теме:

  • "Inline Elements List and What’s New in HTML5" [http://www.tutorialchip.com/tutorials/inline-elements-list-whats-new-in-html5/]
  • "HTML5 Block Level Elements: Complete List" [http://www.tutorialchip.com/tutorials/html5-block-level-elements-complete-list/]
  • "Раскладка в CSS: поток" [http://softwaremaniacs.org/blog/2005/08/27/css-layout-flow/]
  • О размерах блочных элементов

    Ещё хотел отдельно остановиться на вычислении ширины и высоты блочных элементов, ведь тут есть один нюанс, по умолчанию, высота и ширина элементов считается без учёта толщины границ и внутренних отступов, т.е. как-то так:

    Эта блочная модель называется "content-box", и вот в CSS3 появилась возможность изменять блочную модель, указывая атрибут "box-sizing".

    Отлично, теперь мы можем выбирать между двумя значениями "content-box" и "border-box", первый я уже описал, а вот второй вычисляет высоту и ширину включая внутренние отступы и толщину границ:

    Такая блочная модель была свойственна IE6 в "quirks mode"

    Полезные статьи по теме:

  • "Блочные элементы" [http://htmlbook.ru/content/blochnye-elementy]
  • "Встроенные элементы" [http://htmlbook.ru/content/vstroennye-elementy]
  • Плавающие элементы

    Я бы хотел ещё рассказать о CSS свойстве "float", но боюсь, рассказ будет долгим и утомительным, но если кратко: если вы указываете элементу свойство "float", то:

  • наш элемент будет смещён по горизонтали, и "прилипнет" к указанному краю родительского элемента
  • если это был блочный элемент, то теперь он не будет занимать всю ширину родительского элемента, и освободит место
  • если следом идут блочные элементы, то они займут его место
  • если следом идут строчные элементы, то они будут обтекать наш элемент со свободной стороны
  • Это поведение "по умолчанию", как это выглядит в живую можно посмотреть на примере

    <!DOCTYPE html>
    <html dir="ltr" lang="en-US">
    <head>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Свойство float в CSS</title>
        <link rel="profile" href="http://gmpg.org/xfn/11"/>
        <link rel="shortcut icon" href="http://anton.shevchuk.name/favicon.ico"/>
        <link rel="stylesheet" href="css/styles.css"/>
        <script type="text/javascript" src="js/jquery.js"></script>
        <script type="text/javascript" src="js/code.js"></script>
        <style>
            article {
                border: #999 1px solid;
                margin: 0 4px 4px;
            }
            article h2 {
                border: #999 1px solid;
                background: #fff;
            }
            article div {
                background: #ccffcc;
                font-size: 16px;
                padding: 10px;
            }
            article p {
                background: #ccffcc;
            }
            article span {
                background: #ccffcc;
            }
        </style>
    </head>
    <body>
        <div id="content" class="wrapper box">
            <menu label="Try...">
                <a href="html.example.html" title="go prev" class="button alignleft" rel="prev">← Prev </a>
                <a href="index.html" title="back to Index" class="button alignleft" rel="index">Index §</a>
                <a href="css.priority.html" title="go next" class="button alignright" rel="next">Next →</a>
            </menu>
            <header>
                <h1>Пример работы свойства float</h1>
                <h2>Смотрим... →</h2>
            </header>
            <article>
                <h2 style="float:right;">Article Title</h2>
                <div style="height:100px;">
                    <div style="height:100px;"></div>
                </div>
            </article>
            <article>
                <h2 style="float:right;">Article Title</h2>
                <div style="height:100px;clear:both;">
                    <div style="height:100px;clear:both;"></div>
                </div>
            </article>
            <article>
                <h2 style="float:right">Article Title</h2>
                <p>Duis in vestibulum sem. Cras euismod tincidunt dui, et scelerisque tellus condimentum vel.
                Maecenas et urna sit amet risus fermentum rhoncus nec porttitor ligula. Maecenas sit amet
                turpis enim, ut iaculis est. Duis feugiat, lacus id placerat porttitor, lorem augue gravida
                nisi, eu porta eros risus et lectus. Maecenas vestibulum nunc vel ipsum tincidunt sit amet
                blandit sapien bibendum. Proin vel vulputate nisl. Duis tempor imperdiet placerat. Pellentesque
                faucibus consequat magna, et bibendum nisl egestas non. Pellentesque sit amet mattis augue.
                Aenean at diam tincidunt purus sollicitudin gravida non in nisi. Fusce bibendum, magna in
                adipiscing mattis, sem risus fringilla mi, nec gravida lectus lectus at nibh. Suspendisse 
                adipiscing elementum laoreet. Suspendisse sem erat, varius quis aliquet vitae, dapibus sed
                nibh. Nullam iaculis sem at mauris faucibus in vestibulum libero pretium. Aliquam eu turpis
                libero. Fusce et ultrices lectus.</p>
            </article>
            <article>
                <h2 style="float:right">Article Title</h2>
                <span>Duis in vestibulum sem. Cras euismod tincidunt dui, et scelerisque tellus condimentum vel.
                Maecenas et urna sit amet risus fermentum rhoncus nec porttitor ligula. Maecenas sit amet
                turpis enim, ut iaculis est. Duis feugiat, lacus id placerat porttitor, lorem augue gravida
                nisi, eu porta eros risus et lectus. Maecenas vestibulum nunc vel ipsum tincidunt sit amet
                blandit sapien bibendum. Proin vel vulputate nisl. Duis tempor imperdiet placerat. Pellentesque
                faucibus consequat magna, et bibendum nisl egestas non. Pellentesque sit amet mattis augue.
                Aenean at diam tincidunt purus sollicitudin gravida non in nisi. Fusce bibendum, magna in
                adipiscing mattis, sem risus fringilla mi, nec gravida lectus lectus at nibh. Suspendisse
                adipiscing elementum laoreet. Suspendisse sem erat, varius quis aliquet vitae, dapibus sed
                nibh. Nullam iaculis sem at mauris faucibus in vestibulum libero pretium. Aliquam eu turpis
                libero. Fusce et ultrices lectus.</span>
            </article>
            <footer>
                ©copyright 2014 Anton Shevchuk — <a href="http://anton.shevchuk.name/jquery-book/">jQuery Book</a>
            </footer>
            <script type="text/javascript">
                var _gaq = _gaq || [];
                _gaq.push(['_setAccount', 'UA-1669896-2']);
                _gaq.push(['_trackPageview']);
                (function() {
                 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
                 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
                 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
                })();
             </script>
    	</div>
    </body>
    </html>
    

    Тут главное надо понимать происходящее, и уметь управлять, если конечно вы хотите хоть чуть-чуть научиться верстать :)

    Жизненно необходимая информация для верстальщиков:

    "Раскладка в CSS: float" [http://softwaremaniacs.org/blog/2005/12/01/css-layout-float/]

    Позиционирование

    Дам лишь вводную по "position" – у него бывает лишь четыре значения:

  • static – положение дел "по умолчанию", блоки ложатся друг за другом, сверху вниз, по порядку, без отклонений
  • absolute – блок позиционируется согласно заданным координатам
  • fixed – похоже на "absolute", с той лишь разницей, что блок не будет скролиться
  • relative – такой блок можно сдвигать относительно места где он расположен, ну и все внутренние "абсолютные" блоки будут использовать данный элемент как точку отсчета при позиционировании по координатам
  • Для самостоятельного изучения:

    "Раскладка в CSS: позиционирование" [http://softwaremaniacs.org/blog/2005/08/03/css-layout-positioning/]

    Разделяй и властвуй

    Тут стоит запомнить несколько простых правил:

  • выносим JavaScript во внешние файлы
  • никогда не пишем inline обработчиков событий "onclick="some()""
  • выносим CSS из HTML во внешние файлы
  • никогда не пишем inline стилей "style="color:red""
  • и ещё разок для закрепления – не пишем inline!
  • Теперь приведу код, за который следует что-нибудь ломать (это пример плохого кода, уточняю для тех, кто не понимает намёков):

    <script>
    
    function doSomething(){ /* … */ }
    /* раздается хруст сломанных костей запястья, чтобы не печатал */
    </script>
    <style>
    p { line-height:20px; }
    /* крхххх… берцовая кость, и на работу уже не пойдет */
    </style>
    <div style="color:red;font-size:1.2em">
    <p onclick="doSomething();">Lorem ipsum dolor sit amet...</p>
    <!-- тыдыщь, головой об стол… насмерть. как жест милосердия -->
    </div>
    

    Неясно, почему же это плохо? Похоже, вам просто не приходилось менять дизайн для уже готового сайта :) Проясню суть проблемы: вам ставят задачу – "надо поменять цвет шрифта для всех страниц сайта", коих может быть три десятка. Это могут быть не только HTML-файлы, а страницы какого-то шаблонизатора, разбросанные по двум десяткам папок (и это еще не самый плохой вариант). И тут появляется он — красный абзац. Вероятность услышать "слова поддержки" в адрес автора сего кода будет стремиться к единице. Насчет inline-обработчиков событий ситуация похожа, вот представьте себе — пишите вы JavaScript код, всё отлично, всё получается, пока вы не пытаетесь кликнуть по красному абзацу, он оказывается вам не подвластен, и живёт своей собственной жизнью, игнорируя все ваши усилия. Вы смотрите код, и опять кто-то услышит эти слова...

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

    <div id="abzac">
    <p>Lorem ipsum dolor sit
    amet...</p> </div>
    

    Стили можно будет легко повесить на <div> с идентификатором, как собственно и обработчик событий для нашего параграфа.

    Абзац не параграф, но для красного словца, и лёгкости усвоения сгодится

    Немного о JavaScript

    В данный раздел я вынес ту информацию о JavaScript, которую необходимо знать, чтобы у вас не возникало "детских" проблем с использованием jQuery. Если у вас есть опыт работы с JavaScript — то листайте далее.

    Изучать хотите JavaScript и jQuery? Так силу познайте инструмента истинного:

  • Developer Tools для Chrome и Safari (и других webkit-based браузеров)
  • FireBug для FireFox
  • DragonFly для Opera
  • Developer Tools для IE8+
  • Список не полон, но console там есть, применять её надо уметь

    О форматировании

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

  • "JQuery Core Style Guidelines" [http://contribute.jquery.org/style-guide/js/]
  • "Google JavaScript Style Guide" [http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml]
  • Siemens "JavaScript Programming Guideline" [http://www.galasoft-lb.ch/myjavascript/Siemens_SBT_JavaScript_Coding_Guidelines.pdf]
  • "Как писать неподдерживаемый код?" – вредные советы от Ильи [http://learn.javascript.ru/write-unmain-code]
  • В довесок поделюсь небольшим советом: все переменные, содержащие объект jQuery, лучше всего именовать, начиная с символа "$". Поверьте, такая небольшая хитрость экономит много времени.

    И ещё – в конце каждой строки я ставлю точку с запятой, сам JavaScript этого не требует, но и лишним не будет.

    Основы JavaScript

    Переменные

    Первое с чем столкнёмся – это объявление переменных:

    var name = "Ivan"; 
    var age = 32;

    Всё просто, объявляем переменную, используя ключевое слово "var". Можно, конечно же, и без него, но делать я вам это настоятельно не рекомендую, т.к. могут возникнуть непредвиденные проблемы (о чём чуть позже расскажу).

    На имена переменных наложено два ограничение:

  • имя должно состоять только из букв, цифр, и символов "$" и "_"
  • первый символ не должен быть цифрой
  • И ещё, регистр букв имеет значение:

    var company = "Facebook";
    // совсем другая "компания" 
    var Company = "Google";
    

    Константы

    В JavaScript'е нет констант, но поскольку необходимость в них всё же есть, то появилась договорённость: переменные, набранные в верхнем регистре через подчёркивание, не изменять:

    var USER_STATUS_ACTIVE = 1; 
    var USER_STATUS_BANNED = 2;

    Константы необходимы, чтобы избежать появления "magic numbers", сравните следующий код "if(status==2)" – о чём тут речь мало кому будет понятно, а вот код "if(status==USER_STATUS_BANNED)" уже более информативный

    Типы данных

    В JavaScript не так уж и много типов данных:

  • number – целое или дробное число
    var answer = 42; 
    var pi = 3.1415;
    также существуют следующие специальные значения:
  • NaN (not-a-number) – результат числовой операции, которая завершилась ошибкой – запустите:
    Math.sqrt(-5);
    но учтите:
    (NaN == NaN) == false; 
    isNaN(NaN) == true;
  • Infinity – за гранью 1.7976931348623157E+10308 (т.е. больше)
  • -Infinity – за гранью -1.7976931348623157E+10308 (т.е. меньше)
  • string – строка, заключается в кавычки:
    var str = "Hello World!";
    в JavaScript нет разницы между двойными кавычками и одинарными (привет PHP)
  • boolean – булево значение, т.е. или "true" или "false"
    var result = true; 
  • object – это объекты, на них остановлюсь подробнее чуть позже…
  • null – специальное значение для определения "пустоты"
    var result = null;
  • undefined – ещё одно специальное значение "неопределенности", используется как значение неопределённой переменной, т.е. переменная объявлена и существует, но значение ей ещё не присвоено:
    // переменная есть, но нет значения var a;
    alert(a);  // undefined
    if (typeof a == "undefined") { alert("variable is undefined");
    }
    // или может совсем не быть переменной if (window["a"] == undefined) {
    alert("variable does not exist");
    }
    
  • Во втором примере нас может ожидать сюрприз, если кто определит переменную "undefined", как обойти такую "неприятность" я ещё расскажу

    Массивы

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

    var users = ["Ivan", "Petr", "Serg"]

    Нумерация массивов начинается с "0", так что для получения первого элемента вам потребуется следующий код:

    alert(users[0]);  // выведет Ivan

    Размер массива хранится в свойстве length:

    alert(users.length);  // выведет 3
    a[3] = "Danylo"; 
    alert(users.length); // выведет 4
    

    В действительности "length" возвращает индекс последнего элемента массива+1, так что не попадитесь:

    var a = []; 
    a[4] = 10;
    alert(a.length); // выведет 5;

    Для перебора массива лучше всего использовать цикл "for(;;)":

    for (var i = 0; i < users.length; i++) {
    alert(users[i]);  // последовательно выведет Ivan, Petr и Serg
    }
    

    Для работы с последними элементами массива следует использовать методы "push()" и "pop()":

    users.push("Sidorov"); // добавляем элемент в конец массива var 
    sidorov = users.pop(); // удаляем и возращаем последний элемент

    Для работы с первыми элементами массива следует использовать методы "unshift()" и "shift()":

    users.unshift("Sidorov"); // добавляем элемент в начало массива var 
    sidorov = users.shift(); // удаляем и возращаем первый элемент

    Последние два метода работают медленно, т.к. перестраивают весь массив

    Функции

    С функциями в JavaScript'е всё просто, вот вам элементарный пример:

    function hello() {
    alert("Hello world");
    }
    

    Просто, пока не заговорить об анонимных функциях…

    Анонимные функции

    В JavaScript можно создавать анонимную функцию (т.е. функцию без имени), для этого достаточно слегка изменить предыдущую конструкцию:

    function() {
    alert("Hello world");
    }
    

    Так как функция это вполне себе объект, то её можно присвоить переменной, и (или) передать в качестве параметра в другую функцию:

    var myAlert = function(name) 
    { alert("Hello " + name);
    }
    function helloMike(myFunc) { // тут функция передаётся как параметр myFunc("Mike");
    }
    helloMike(myAlert);
    

    Анонимную функцию можно создать и тут же вызвать с необходимыми параметрами:

    (function(name) { alert("Hello " + name);
    })("Mike");
    

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

    Объекты

    На объекты в JavaScript возложено две роли:

  • хранилище данных
  • функционал объекта
  • Первое предназначение можно описать следующим кодом:

    var user = {
    name: "Ivan", age: 32
    };
    alert(user.name); // Ivan
    alert(user.age); // 32
    

    Это фактически реализация key-value хранилища, или хэша, или ассоциативного массива, или …, ну вы поняли, названий много, но в JavaScript'е это объект, и запись выше – это JSON – JavaScript Object Notation (хоть и с небольшими оговорками).

    Для перебора такого хранилища можно использовать цикл "for(.. in ..)":

    for (var prop in user) {
    alert(prop + "=" + user[prop]); // выведет name=Ivan 
    								// затем age=32
    }
    

    С объектами, конструкторами и т.д. в JavaScript посложнее будет, хотя для понимания не так уж и много надо, запоминайте: любая функция вызванная с использованием ключевого слова "new" возвращает нам объект, а сама становится конструктором данного объекта:

    function
     User(name)
     { this.name 
     = name;
    this.status = USER_STATUS_ACTIVE;
    }
    var me = new User("Anton");
    

    Поведение функции "User()" при использовании "new" слегка изменится:

  • Данная конструкция создаст новый, пустой объект
  • Ключевое слово "this" получит ссылку на этот объект
  • Функция выполнится и возможно изменит объект через "this" (как в примере выше)
  • Функция вернёт "this" (по умолчанию)
  • Результатом выполнения кода будет следующий объект:

    me = { name: "Anton", status: 1 };

    Область видимости и чудо this

    Для тех, кто только начинает своё знакомство с JavaScript я расскажу следующие нюансы:

  • когда вы объявляете переменную или функцию, то она становится частью "window":
    var a = 1234; 
    alert(window["a"]); // => 
    1234 function myLog(message) {
    alert(message); // => 1234
    }
    window["myLog"](a);
    
  • когда искомая переменная не найдена в текущей области видимости, то её поиски будут продолжены в области видимости родительской функции:
    var a = 1234; (function(){
    var b = 4321; (function() {
    var c = 1111; alert((a+b)/c); // => 5
    })();
    })();
    
  • чудо-переменная "this" всегда указывает на текущий объект вызывающий функцию (поскольку по умолчанию все переменные и функции попадают в "window", то "this == window"):
    var a = 1234;
    function myLog() {
    alert(this); // => 
    window alert(this.a); // 
    => 1234
    }
    
  • контекст "this" можно изменить используя функции "bind()", "call()", и "apply()"
  • Всё что касается "window" относится лишь к браузерам, но поскольку книга о jQuery, то иное поведение я и не рассматриваю, но вот так прозрачно намекаю, что оно есть ;)

    Замыкания

    Изучив замыкания, можно понять много магии в JavaScript’e. Приведу пример кода с пояснениями:

    var a = 1234;
    var myFunc = function(){ var b = 4321;
    var c = 1111; return function() {
    return ((a+b)/c);
    };
    };
    var anotherFunc = myFunc(); // myFunc возвращает анонимную функцию 
    							// с "замкнутыми" значениями c и b
    alert(anotherFunc()); // => 5
    

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

    Рекомендуемые статьи по теме:

  • "Функции "изнутри", замыкания" [http://learn.javascript.ru/closures]
  • "Использование замыканий" [http://learn.javascript.ru/closures-usage]
  • "Closures: Front to Back" [http://net.tutsplus.com/tutorials/javascript-ajax/closures-front-to-back/]
  • Вводная по JavaScript затянулась, лучше почитайте: http://learn.javascript.ru/

    Страницы:

    Начнём знакомство с jQuery с повторения (или изучения) основ правильного употребления связки HTML и CSS с небольшой примесью JavaScript.

    Если не хотите упасть в грязь лицом перед коллегами — то не пропускайте данную главу "мимо ушей".

    HTML — о нём стоит помнить две вещи – семантический и правильный.

    Семантическая вёрстка

    Семантическая вёрстка HTML документа подразумевает использование тегов по прямому назначению, т.е. если вам необходим заголовок – то вот тег <h1> и собратья, необходима табличное представление данных – используйте тег <table> и только его.

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

    Забегая чуть-чуть вперёд, стоит упомянуть теги из спецификации HTML5:

    <article>, <aside>, <header>, <footer>, <menu>, <section> и т.д. — используйте их, не бойтесь.

    Не бояться — это правильно, но использовать тоже надо с умом, рекомендую ресурс http://htmlbook.ru/html5 — очень хорошо и подробно расписано о нововведениях спецификации HTML5.

    И еще парочка интересных ресурсов в нагрузку:

  • http://htmlbook.ru/html5 — неплохо, и на русском
  • http://www.html5rocks.com/en/ — тут целое сообщество
  • Старайтесь избегать избыточных элементов на странице, большинство HTML страниц грешат лишними блочными элементами:

    <div id="header"> 
    <div id="logo">
    <h1><a href="/">Мой блог</a></h1> 
    </div>
    <div id="description">
    <h2>Тут я делюсь своими мыслями</h2> </div>
    </div>
    

    Данную конструкцию можно легко упростить, и при этом код станет более читаемым, изменения в CSS будут минимальными (или даже не потребуются):

    <header> 
    <h1>
    <a href="/">Мой блог</a>
    </h1>
    <h2>Тут я делюсь своими мыслями</h2> 
    </header>
    

    В английском языке есть термин "divits" – сим термином награждают HTML- разметку с чрезмерным использованием div’ов без потребности, я же обзываю такие творения "дивными". Обычно таким грешат новички, которые для применения стилей CSS оборачивают элементы в div’ы, что и приводит к их размножению без нужды.

    Ещё одним обязательным пунктом для создания "правильного" HTML является использование названий классов и идентификаторов, которые однозначно говорят нам о содержимом элемента, а не о каких либо нюансах оформления, приведу пример:

    Плохо
    red, green и т.д. в какой-то момент захотите перекрасить, и элемент с классом "red" будет синего цвета
    wide, small и т.д. сегодня широкий, а завтра?
    h90w490 наверное, это элемент с высотой 90px и шириной 490px, или я ошибаюсь?
    b_1, ax_9 эти название тоже ни о чем не говорят
    color1, color2 и т.д. иногда встречается для "скинованных" сайтов, но создают такие классы из лени
    element1...20 такое тоже встречается, и ничем хорошим не пахнет

    Ну и примеры правильного именования:

    Хорошо
    logo, content логотип, основной контент
    menu, submenu меню и подменю
    even, odd чётный и нечётный элементы списка
    paginator постраничная навигация
    copyright копирайт

    Есть ещё один момент – это форматирование HTML и CSS кода, я не буду заострять на нём внимание, но весь код в книге будет отформатирован отступами, и, возможно, это даст свои плоды в ваших творениях.

    Валидный HTML

    Зеленый маркер W3C validator'а – это правильно, и к этому надо стремится, так что не забывайте закрывать теги, да прописывать обязательные параметры, приведу пример HTML кода, в котором допущено 6 ошибок (согласно спецификации HTML5), найдите их:

    <h2>Lorem ipsum
    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc urna metus, ultricies eu, congue vel, laoreet id, justo. Aliquam fermentum adipiscing pede. Suspendisse dapibus ornare quam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. <p>
    <a href="/index.php?mod=defaultact=image"><img src="/img001.jpg"></a>
    

    CSS-правила и селекторы

    Теперь приступим к CSS, и начнём, пожалуй, с расшифровки аббревиатуры CSS это Cascading Style Sheets, дословно "каскадная таблица стилей", но:

    — Почему же она называется каскадной? — этот вопрос я часто задаю на собеседованиях претендентам. Ответом же будет аналогия, ибо она незыблема как перпендикулярная лягушка: представьте себе каскад водопада, вот вы стоите на одной из ступенек каскада с чернильницей в руках, и выливаете ее содержимое в воду — вся вода ниже по каскаду будет окрашиваться в цвет чернил. Применив эту аналогию на HTML — создавая правило для элемента, вы автоматически применяете его на все дочерние элементы (конечно, не все правила так работают, но о них позже) — это наследование стилей. Теперь, если таких умников с чернильницей больше чем один, и цвета разные, то в результате получим смешение цветов, но это в жизни, а в CSS работают правила приоритетов, если кратко:

  • самый низкий приоритет имеют стили браузера по умолчанию — в разных браузерах они могут отличаться, поэтому придумали CSS Reset (гуглится и юзается), и все будут на равных
  • чуть важнее — стили заданные пользователем в недрах настроек браузера, встречается редко
  • самые важные — стили автора странички, но и там всё идёт по порядку
  • самый низкий приоритет у тех, что лежат во внешнем подключённом файле
  • затем те, что встроили внутрь HTML с помощью тега <style>
  • потом те, что захардкодили плохие люди (не вы, вы так делать не будете) в атрибуте "style"
  • самый высокий приоритет у правил с меткой "!important"
  • при равенстве приоритетов, тапки у того, кто объявлен последним
  • Если голова ещё не бо-бо, то я также упомяну, что при расчёте, чьи же правила главней, ещё анализируется специфичность селекторов, и тут считается следующим образом:

    за каждый идентификатор получаем [1:0:0] (#id)

    за каждый класс, либо псевдо класс — [0:1:0] (.my :pseudo)

    за каждый тег — [0:0:1] (div a)

    При этом [1:0:0] > [0:x:y] > [0:0:x].

    Пример селекторов, выстроенных по приоритету (первые важнее):

    #my p#id — [2:0:1] 
    #my #id — [2:0:0] 
    #my p — [1:0:1] 
    #id — [1:0:0]
    .wrapper .content p — [0:2:1]
    .content div p — [0:1:2]
    .content p — [0:1:1] 
    p — [0:0:1]
    

    Пример HTML-кода:

    <!DOCTYPE html>
    <html dir="ltr" lang="en-US">
    <head>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Приоритет CSS селекторов</title>
        <link rel="profile" href="http://gmpg.org/xfn/11"/>
        <link rel="shortcut icon" href="http://anton.shevchuk.name/favicon.ico"/>
        <link rel="stylesheet" href="css/styles.css"/>
    	<script type="text/javascript" src="js/jquery.js"></script>
    	<script type="text/javascript" src="js/code.js"></script>
        <script>
            function appendStyle(rule) {
                $('head').append('<style>'+rule+'</style>');
            }
        </script>
    </head>
    <body>
    <div class="wrapper">
        <menu>
            <a href="css.float.html" title="go prev" class="button alignleft" rel="prev">← Prev </a>
            <a href="index.html" title="back to Index" class="button alignleft" rel="index">Index §</a>
            <a href="css.selectors.html" title="go next" class="button alignright" rel="next">Next →</a>
            <hr/>
    		<h3>Шпаргалка</h3>
    <pre><code><em>// weight</em>
    #id    = [1,0,0]
    .class = [0,1,0]
    tag    = [0,0,1]
    <em>// compare</em>
    [1,0,0] > [0,1,0] > [0,0,1]
    [1,0,0] > [0,100,100]
    [0,1,0] > [0,0,100]
    </code></pre>
            <hr/>
            <pre><code contenteditable="true">appendStyle(<span>'p { color:orange }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'.content p { color:green }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'article.content p { color:blue }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'.wrapper .content p { color:red }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'#id { color:darkblue }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'#my p { color:darkcyan }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'#my #id { color:darkgreen }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>appendStyle(<span>'#my p#id { color:black }'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
        </menu>
        <header>
            <h1>Приоритет CSS селекторов</h1>
            <h2>Сохраните страницу и попробуйте изменить CSS стили</h2>
        </header>
        <article id="my" class="content">
            <h2>Article Title</h2>
            <p id="id">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus rutrum,
            lectus eu varius consectetur, libero velit hendrerit augue, ut posuere enim neque
            in libero. Donec eget sagittis nibh. Suspendisse sed tincidunt urna. Cras quis
            euismod neque. Maecenas auctor ultricies posuere. Pellentesque luctus pulvinar dui
            eget semper. Donec sodales odio eu sapien varius luctus. Donec dictum feugiat diam
            at malesuada. Sed nec massa in augue condimentum faucibus quis ut diam. Quisque
            nisl sem, semper nec vulputate vel, mattis sit amet justo. Aliquam purus felis,
            tempor at scelerisque quis, tincidunt in neque. Etiam ut risus diam. Pellentesque
            fermentum risus id elit feugiat cursus. Ut fringilla dictum diam, sed iaculis
            lorem pulvinar ut. Cras vel elit id velit commodo viverra sit amet vel orci.</p>
        </article>
        <footer>
            ©copyright 2014 Anton Shevchuk — <a href="http://anton.shevchuk.name/jquery-book/">jQuery Book</a>
        </footer>
        <script type="text/javascript">
            var _gaq = _gaq || [];
            _gaq.push(['_setAccount', 'UA-1669896-2']);
            _gaq.push(['_trackPageview']);
            (function() {
             var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
             ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
             var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
            })();
        </script>
    </div>
    </body>
    </html>
    <div class="wrapper">
    <div id="my" class="content"> 
    <p id="id">
    Lorem ipsum dolor sit amet, consectetuer...
    </p>
    </div>
    </div>
    

    При равенстве счета — последний главный.

    Говорят, что правило с 255 классами будет выше по приоритету, нежели правило с одним "id", но я надеюсь, такого кода в реальности не существует

    Вот такое краткое вступительное слово, но пора вернуться к jQuery. Так вот, работая с jQuery, вы должны "на отлично" читать правила CSS, а также уметь составлять CSS-селекторы для поиска необходимых элементов на странице. Но давайте обо всем по порядку, возьмём следующий простенький пример вполне семантического HTML:

    <!DOCTYPE html>
    <html dir="ltr" lang="en-US"> 
    <head>
    <meta charset="UTF-8"/> 
    <title>Page Title</title>
    <link rel="profile" href="http://gmpg.org/xfn/11"/> 
    <style type="text/css">
    body {
    font: 62.5%/1.6 Verdana, Tahoma, sans-serif; color: #333333;
    }
    h1, h2 {
    color: #ff6600;
    }
    header, main, footer { margin: 30px auto; width: 600px;
    }
    #content { padding: 8px;
    }
    .box {
    border:1px solid #ccc; border-radius:4px; box-shadow:0 0 2px #ccc;
    }
    </style>
    </head>
    <body>
    <header>
    <h1>Page Title</h1> 
    <p>Page Description</p>
    </header>
    <main id="content" class="wrapper box"> <article>
    <h2>Article Title</h2> <p>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc urna metus, ultricies eu, congue vel, laoreet...
    </p>
    </article>
    <article>
    <h2>Article Title</h2> <p>
    Morbi malesuada, ante at feugiat tincidunt, enim massa gravida metus, commodo lacinia massa diam vel eros...
    </p>
    </article>
    </main>
    <footer>©copyright 2014</footer> 
    </body>
    </html>
    

    Это пример простого и правильного HTML5 с небольшим добавлением CSS3. Давайте разберём селекторы в приведённом CSS-коде (я предумышленно не выносил CSS в отдельный файл, ибо так наглядней):

    body – данные правила будут применены к тегу <body> и всем его потомкам

    h1,h2 – мы выбираем теги <h1> и <h2>, и устанавливаем цвет шрифта #content – выбираем элемент с "id="content"" и применяем правила

    .box – выбираем элементы с "class="box""

    Теперь подробнее и с усложнёнными примерами:

    h1 ищем элементы по имени тега
    #container ищем элемент по идентификатору "id=container" (идентификатор уникален, значит, на странице он должен быть только один)
    div#container ищем <div> c идентификатором container, но предыдущий селектор работает быстрее, но этот важнее
    .news выбираем элементы по имени класса "class="news""
    div.news все элементы <div> c классом news (так работает быстрее в IE8, т.к. в нём не реализован метод "getElementsByClassName()")
    #wrap .post ищем все элементы с классом post внутри элемента с "id = wrap"
    .cls1.cls2 выбираем элементы с двумя классами "class="cls1 cls2""
    h1,h2,.posts перечисление селекторов, выберем всё перечисленное
    .post > h2 выбираем элементы <h2>, которые являются непосредственными потомками элемента с классом "post"
    a + span будут выбраны все элементы <span> следующие сразу за элементом <a>
    a[href^=http] будут выбраны все элементы <a> у которых атрибут "href" начинается с http(предположительно, все внешние ссылки)

    Это отнюдь не весь список, описание же всех CSS3 селекторов можно найти на соответствующей страничке W3C: http://www.w3.org/TR/css3-selectors/

    40% задач, которые вы будете решать с помощью jQuery, сводятся к поиску необходимого элемента на странице, так что знание CSS селекторов обязательно. Вот еще кусочек CSS для тренировки, напишите соответствующий ему HTML (это тоже вопрос с собеседования ;):

    #my p.announce, .tt.pm li li a:hover+span { color: #f00; }

    Пишите прям тут:

    CSS. Погружение

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

    О форматировании

    Нет, я не властен над собой, и таки приведу в качестве примера CSS форматирование, которое я использую:

    /*header*/ 
    header {
    margin-bottom: 16px; 
    font-weight: 400;
    }
    header h1 { 
    color: #999;
    }
    header p {
    font-size: 1.4em; 
    margin-top: 0;
    }
    /*/header*/
    

    Почему это хорошо:

  • такой CSS легко читается
  • есть идентификатор начала и конца блока (можно быстро найти необходимую часть даже в очень большом CSS файле используя поиск по метке "*header")
  • подобное форматирование явно указывает на вложенность элементов
  • и можно легко проследить наследование свойств
  • Я не настаиваю на своём варианте, но хотелось, чтобы вы приняли на вооружение один из многих стандартов форматирования, и всегда следовали ему.

    Именование классов и идентификаторов

    Я уже затрагивал эту тему, когда рассказывал о релевантности HTML, так вот – имена классов могут быть даже такими: "b-service-list__column b-service-list__column_right" и это будет круто, и "must be" – но лишь в рамках действительно больших проектов, и собственно чего я распинаюсь, дам ссылки – информации из них хватит еще на одну книгу ;):

  • Клуб "Блок, Элемент, Модификатор" [http://clubs.ya.ru/bem/]
  • "Что такое БЭМ" [http://bem.github.com/bem-method/pages/beginning/beginning.ru.html]
  • Обязательно изучите – полезно для расширения кругозора, и прокачки скилов

    О цветах

    В WEB используется цветовая модель RGB, следовательно, красный цвет можно записать не только как red, но и ещё несколькими способами:

    p { color: red }
    p { color: #ff0000 }
    p { color: #f00 } /* сокращенная запись, экономит 3 байта */
    p { color: rgb(255, 0, 0) }
    

    Теперь вы без запинки должны назвать цвета #f00, #0f0, #00f, а те, у кого по рисованию было "отлично", назовут и #ff0, #0ff и #f0f ;)

    С появлением CSS3, указывая цвет, мы также можем задать значение альфа-канала, т.е. прозрачность:

    p { color: rgba(255, 0, 0, 1) } /* обычный текст */
    p { color: rgba(255, 0, 0, 0.5) } /* полупрозрачный текст */
    

    Ещё одна примочка CSS3 – это возможность использования цветовой модели HSL (hue saturation lightness – тон, насыщенность и светлота) и HSLA (HSL + α-канал):

    p { color: hsl(  0,	100%,	50%) }	/* красный */
    p { color: hsl(120,	100%,	50%) }	/* зелёный */
    p { color: hsl(240,	100%,	50%) } /* синий */
    p { color: hsla( 0,	100%,	50%, 0.5) } /* полупрозрачный красный */
    

    Для перевода из HSL в RGB существует простой алгоритм, но пока не стоит им себя грузить

    Да кто этим HSL пользуется? Не морочьте себе голову.

    Для тех, кого вопрос со смешанием каналов RGB поставил в тупик, то вот вам наглядное руководство:

    Блочные и строчные элементы

    Опять я буду ссылаться на чей-то учебник – на этот раз от Ивана Сагалаева - http://softwaremaniacs.org/blog/category/primer/, и пусть вас не смущают даты написания статей – они повествуют об основах и актуальность они не потеряют ещё очень долго

    Возможно, вы ещё не знаете, но HTML теги делятся на блочные (block) и строчные (inline). Блочными элементами называют те, которые отображаются как прямоугольник, они занимают всю доступную ширину и их высота определяется содержимым. Блочные теги по умолчанию начинаются и заканчиваются новой строкой — это <div>, <h1> и собратья, <p> и другие.

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

    Одна из самых часто встречаемых ошибок, это оборачивание заголовка в ссылку: <a href="#"><h1>Название статьи</h1></a>, не допускайте подобные промахи

    Хотя если мы ориентируемся на HTML5 – то тег <a> теперь может быть блочным элементом, и приведённый пример будет валидным. Ага, вот такой я не последовательный.

    По теме:

  • "Inline Elements List and What’s New in HTML5" [http://www.tutorialchip.com/tutorials/inline-elements-list-whats-new-in-html5/]
  • "HTML5 Block Level Elements: Complete List" [http://www.tutorialchip.com/tutorials/html5-block-level-elements-complete-list/]
  • "Раскладка в CSS: поток" [http://softwaremaniacs.org/blog/2005/08/27/css-layout-flow/]
  • О размерах блочных элементов

    Ещё хотел отдельно остановиться на вычислении ширины и высоты блочных элементов, ведь тут есть один нюанс, по умолчанию, высота и ширина элементов считается без учёта толщины границ и внутренних отступов, т.е. как-то так:

    Эта блочная модель называется "content-box", и вот в CSS3 появилась возможность изменять блочную модель, указывая атрибут "box-sizing".

    Отлично, теперь мы можем выбирать между двумя значениями "content-box" и "border-box", первый я уже описал, а вот второй вычисляет высоту и ширину включая внутренние отступы и толщину границ:

    Такая блочная модель была свойственна IE6 в "quirks mode"

    Полезные статьи по теме:

  • "Блочные элементы" [http://htmlbook.ru/content/blochnye-elementy]
  • "Встроенные элементы" [http://htmlbook.ru/content/vstroennye-elementy]
  • Плавающие элементы

    Я бы хотел ещё рассказать о CSS свойстве "float", но боюсь, рассказ будет долгим и утомительным, но если кратко: если вы указываете элементу свойство "float", то:

  • наш элемент будет смещён по горизонтали, и "прилипнет" к указанному краю родительского элемента
  • если это был блочный элемент, то теперь он не будет занимать всю ширину родительского элемента, и освободит место
  • если следом идут блочные элементы, то они займут его место
  • если следом идут строчные элементы, то они будут обтекать наш элемент со свободной стороны
  • Это поведение "по умолчанию", как это выглядит в живую можно посмотреть на примере

    <!DOCTYPE html>
    <html dir="ltr" lang="en-US">
    <head>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Свойство float в CSS</title>
        <link rel="profile" href="http://gmpg.org/xfn/11"/>
        <link rel="shortcut icon" href="http://anton.shevchuk.name/favicon.ico"/>
        <link rel="stylesheet" href="css/styles.css"/>
        <script type="text/javascript" src="js/jquery.js"></script>
        <script type="text/javascript" src="js/code.js"></script>
        <style>
            article {
                border: #999 1px solid;
                margin: 0 4px 4px;
            }
            article h2 {
                border: #999 1px solid;
                background: #fff;
            }
            article div {
                background: #ccffcc;
                font-size: 16px;
                padding: 10px;
            }
            article p {
                background: #ccffcc;
            }
            article span {
                background: #ccffcc;
            }
        </style>
    </head>
    <body>
        <div id="content" class="wrapper box">
            <menu label="Try...">
                <a href="html.example.html" title="go prev" class="button alignleft" rel="prev">← Prev </a>
                <a href="index.html" title="back to Index" class="button alignleft" rel="index">Index §</a>
                <a href="css.priority.html" title="go next" class="button alignright" rel="next">Next →</a>
            </menu>
            <header>
                <h1>Пример работы свойства float</h1>
                <h2>Смотрим... →</h2>
            </header>
            <article>
                <h2 style="float:right;">Article Title</h2>
                <div style="height:100px;">
                    <div style="height:100px;"></div>
                </div>
            </article>
            <article>
                <h2 style="float:right;">Article Title</h2>
                <div style="height:100px;clear:both;">
                    <div style="height:100px;clear:both;"></div>
                </div>
            </article>
            <article>
                <h2 style="float:right">Article Title</h2>
                <p>Duis in vestibulum sem. Cras euismod tincidunt dui, et scelerisque tellus condimentum vel.
                Maecenas et urna sit amet risus fermentum rhoncus nec porttitor ligula. Maecenas sit amet
                turpis enim, ut iaculis est. Duis feugiat, lacus id placerat porttitor, lorem augue gravida
                nisi, eu porta eros risus et lectus. Maecenas vestibulum nunc vel ipsum tincidunt sit amet
                blandit sapien bibendum. Proin vel vulputate nisl. Duis tempor imperdiet placerat. Pellentesque
                faucibus consequat magna, et bibendum nisl egestas non. Pellentesque sit amet mattis augue.
                Aenean at diam tincidunt purus sollicitudin gravida non in nisi. Fusce bibendum, magna in
                adipiscing mattis, sem risus fringilla mi, nec gravida lectus lectus at nibh. Suspendisse 
                adipiscing elementum laoreet. Suspendisse sem erat, varius quis aliquet vitae, dapibus sed
                nibh. Nullam iaculis sem at mauris faucibus in vestibulum libero pretium. Aliquam eu turpis
                libero. Fusce et ultrices lectus.</p>
            </article>
            <article>
                <h2 style="float:right">Article Title</h2>
                <span>Duis in vestibulum sem. Cras euismod tincidunt dui, et scelerisque tellus condimentum vel.
                Maecenas et urna sit amet risus fermentum rhoncus nec porttitor ligula. Maecenas sit amet
                turpis enim, ut iaculis est. Duis feugiat, lacus id placerat porttitor, lorem augue gravida
                nisi, eu porta eros risus et lectus. Maecenas vestibulum nunc vel ipsum tincidunt sit amet
                blandit sapien bibendum. Proin vel vulputate nisl. Duis tempor imperdiet placerat. Pellentesque
                faucibus consequat magna, et bibendum nisl egestas non. Pellentesque sit amet mattis augue.
                Aenean at diam tincidunt purus sollicitudin gravida non in nisi. Fusce bibendum, magna in
                adipiscing mattis, sem risus fringilla mi, nec gravida lectus lectus at nibh. Suspendisse
                adipiscing elementum laoreet. Suspendisse sem erat, varius quis aliquet vitae, dapibus sed
                nibh. Nullam iaculis sem at mauris faucibus in vestibulum libero pretium. Aliquam eu turpis
                libero. Fusce et ultrices lectus.</span>
            </article>
            <footer>
                ©copyright 2014 Anton Shevchuk — <a href="http://anton.shevchuk.name/jquery-book/">jQuery Book</a>
            </footer>
            <script type="text/javascript">
                var _gaq = _gaq || [];
                _gaq.push(['_setAccount', 'UA-1669896-2']);
                _gaq.push(['_trackPageview']);
                (function() {
                 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
                 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
                 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
                })();
             </script>
    	</div>
    </body>
    </html>
    

    Тут главное надо понимать происходящее, и уметь управлять, если конечно вы хотите хоть чуть-чуть научиться верстать :)

    Жизненно необходимая информация для верстальщиков:

    "Раскладка в CSS: float" [http://softwaremaniacs.org/blog/2005/12/01/css-layout-float/]

    Позиционирование

    Дам лишь вводную по "position" – у него бывает лишь четыре значения:

  • static – положение дел "по умолчанию", блоки ложатся друг за другом, сверху вниз, по порядку, без отклонений
  • absolute – блок позиционируется согласно заданным координатам
  • fixed – похоже на "absolute", с той лишь разницей, что блок не будет скролиться
  • relative – такой блок можно сдвигать относительно места где он расположен, ну и все внутренние "абсолютные" блоки будут использовать данный элемент как точку отсчета при позиционировании по координатам
  • Для самостоятельного изучения:

    "Раскладка в CSS: позиционирование" [http://softwaremaniacs.org/blog/2005/08/03/css-layout-positioning/]

    Разделяй и властвуй

    Тут стоит запомнить несколько простых правил:

  • выносим JavaScript во внешние файлы
  • никогда не пишем inline обработчиков событий "onclick="some()""
  • выносим CSS из HTML во внешние файлы
  • никогда не пишем inline стилей "style="color:red""
  • и ещё разок для закрепления – не пишем inline!
  • Теперь приведу код, за который следует что-нибудь ломать (это пример плохого кода, уточняю для тех, кто не понимает намёков):

    <script>
    
    function doSomething(){ /* … */ }
    /* раздается хруст сломанных костей запястья, чтобы не печатал */
    </script>
    <style>
    p { line-height:20px; }
    /* крхххх… берцовая кость, и на работу уже не пойдет */
    </style>
    <div style="color:red;font-size:1.2em">
    <p onclick="doSomething();">Lorem ipsum dolor sit amet...</p>
    <!-- тыдыщь, головой об стол… насмерть. как жест милосердия -->
    </div>
    

    Неясно, почему же это плохо? Похоже, вам просто не приходилось менять дизайн для уже готового сайта :) Проясню суть проблемы: вам ставят задачу – "надо поменять цвет шрифта для всех страниц сайта", коих может быть три десятка. Это могут быть не только HTML-файлы, а страницы какого-то шаблонизатора, разбросанные по двум десяткам папок (и это еще не самый плохой вариант). И тут появляется он — красный абзац. Вероятность услышать "слова поддержки" в адрес автора сего кода будет стремиться к единице. Насчет inline-обработчиков событий ситуация похожа, вот представьте себе — пишите вы JavaScript код, всё отлично, всё получается, пока вы не пытаетесь кликнуть по красному абзацу, он оказывается вам не подвластен, и живёт своей собственной жизнью, игнорируя все ваши усилия. Вы смотрите код, и опять кто-то услышит эти слова...

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

    <div id="abzac">
    <p>Lorem ipsum dolor sit
    amet...</p> </div>
    

    Стили можно будет легко повесить на <div> с идентификатором, как собственно и обработчик событий для нашего параграфа.

    Абзац не параграф, но для красного словца, и лёгкости усвоения сгодится

    Немного о JavaScript

    В данный раздел я вынес ту информацию о JavaScript, которую необходимо знать, чтобы у вас не возникало "детских" проблем с использованием jQuery. Если у вас есть опыт работы с JavaScript — то листайте далее.

    Изучать хотите JavaScript и jQuery? Так силу познайте инструмента истинного:

  • Developer Tools для Chrome и Safari (и других webkit-based браузеров)
  • FireBug для FireFox
  • DragonFly для Opera
  • Developer Tools для IE8+
  • Список не полон, но console там есть, применять её надо уметь

    О форматировании

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

  • "JQuery Core Style Guidelines" [http://contribute.jquery.org/style-guide/js/]
  • "Google JavaScript Style Guide" [http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml]
  • Siemens "JavaScript Programming Guideline" [http://www.galasoft-lb.ch/myjavascript/Siemens_SBT_JavaScript_Coding_Guidelines.pdf]
  • "Как писать неподдерживаемый код?" – вредные советы от Ильи [http://learn.javascript.ru/write-unmain-code]
  • В довесок поделюсь небольшим советом: все переменные, содержащие объект jQuery, лучше всего именовать, начиная с символа "$". Поверьте, такая небольшая хитрость экономит много времени.

    И ещё – в конце каждой строки я ставлю точку с запятой, сам JavaScript этого не требует, но и лишним не будет.

    Основы JavaScript

    Переменные

    Первое с чем столкнёмся – это объявление переменных:

    var name = "Ivan"; 
    var age = 32;

    Всё просто, объявляем переменную, используя ключевое слово "var". Можно, конечно же, и без него, но делать я вам это настоятельно не рекомендую, т.к. могут возникнуть непредвиденные проблемы (о чём чуть позже расскажу).

    На имена переменных наложено два ограничение:

  • имя должно состоять только из букв, цифр, и символов "$" и "_"
  • первый символ не должен быть цифрой
  • И ещё, регистр букв имеет значение:

    var company = "Facebook";
    // совсем другая "компания" 
    var Company = "Google";
    

    Константы

    В JavaScript'е нет констант, но поскольку необходимость в них всё же есть, то появилась договорённость: переменные, набранные в верхнем регистре через подчёркивание, не изменять:

    var USER_STATUS_ACTIVE = 1; 
    var USER_STATUS_BANNED = 2;

    Константы необходимы, чтобы избежать появления "magic numbers", сравните следующий код "if(status==2)" – о чём тут речь мало кому будет понятно, а вот код "if(status==USER_STATUS_BANNED)" уже более информативный

    Типы данных

    В JavaScript не так уж и много типов данных:

  • number – целое или дробное число
    var answer = 42; 
    var pi = 3.1415;
    также существуют следующие специальные значения:
  • NaN (not-a-number) – результат числовой операции, которая завершилась ошибкой – запустите:
    Math.sqrt(-5);
    но учтите:
    (NaN == NaN) == false; 
    isNaN(NaN) == true;
  • Infinity – за гранью 1.7976931348623157E+10308 (т.е. больше)
  • -Infinity – за гранью -1.7976931348623157E+10308 (т.е. меньше)
  • string – строка, заключается в кавычки:
    var str = "Hello World!";
    в JavaScript нет разницы между двойными кавычками и одинарными (привет PHP)
  • boolean – булево значение, т.е. или "true" или "false"
    var result = true; 
  • object – это объекты, на них остановлюсь подробнее чуть позже…
  • null – специальное значение для определения "пустоты"
    var result = null;
  • undefined – ещё одно специальное значение "неопределенности", используется как значение неопределённой переменной, т.е. переменная объявлена и существует, но значение ей ещё не присвоено:
    // переменная есть, но нет значения var a;
    alert(a);  // undefined
    if (typeof a == "undefined") { alert("variable is undefined");
    }
    // или может совсем не быть переменной if (window["a"] == undefined) {
    alert("variable does not exist");
    }
    
  • Во втором примере нас может ожидать сюрприз, если кто определит переменную "undefined", как обойти такую "неприятность" я ещё расскажу

    Массивы

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

    var users = ["Ivan", "Petr", "Serg"]

    Нумерация массивов начинается с "0", так что для получения первого элемента вам потребуется следующий код:

    alert(users[0]);  // выведет Ivan

    Размер массива хранится в свойстве length:

    alert(users.length);  // выведет 3
    a[3] = "Danylo"; 
    alert(users.length); // выведет 4
    

    В действительности "length" возвращает индекс последнего элемента массива+1, так что не попадитесь:

    var a = []; 
    a[4] = 10;
    alert(a.length); // выведет 5;

    Для перебора массива лучше всего использовать цикл "for(;;)":

    for (var i = 0; i < users.length; i++) {
    alert(users[i]);  // последовательно выведет Ivan, Petr и Serg
    }
    

    Для работы с последними элементами массива следует использовать методы "push()" и "pop()":

    users.push("Sidorov"); // добавляем элемент в конец массива var 
    sidorov = users.pop(); // удаляем и возращаем последний элемент

    Для работы с первыми элементами массива следует использовать методы "unshift()" и "shift()":

    users.unshift("Sidorov"); // добавляем элемент в начало массива var 
    sidorov = users.shift(); // удаляем и возращаем первый элемент

    Последние два метода работают медленно, т.к. перестраивают весь массив

    Функции

    С функциями в JavaScript'е всё просто, вот вам элементарный пример:

    function hello() {
    alert("Hello world");
    }
    

    Просто, пока не заговорить об анонимных функциях…

    Анонимные функции

    В JavaScript можно создавать анонимную функцию (т.е. функцию без имени), для этого достаточно слегка изменить предыдущую конструкцию:

    function() {
    alert("Hello world");
    }
    

    Так как функция это вполне себе объект, то её можно присвоить переменной, и (или) передать в качестве параметра в другую функцию:

    var myAlert = function(name) 
    { alert("Hello " + name);
    }
    function helloMike(myFunc) { // тут функция передаётся как параметр myFunc("Mike");
    }
    helloMike(myAlert);
    

    Анонимную функцию можно создать и тут же вызвать с необходимыми параметрами:

    (function(name) { alert("Hello " + name);
    })("Mike");
    

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

    Объекты

    На объекты в JavaScript возложено две роли:

  • хранилище данных
  • функционал объекта
  • Первое предназначение можно описать следующим кодом:

    var user = {
    name: "Ivan", age: 32
    };
    alert(user.name); // Ivan
    alert(user.age); // 32
    

    Это фактически реализация key-value хранилища, или хэша, или ассоциативного массива, или …, ну вы поняли, названий много, но в JavaScript'е это объект, и запись выше – это JSON – JavaScript Object Notation (хоть и с небольшими оговорками).

    Для перебора такого хранилища можно использовать цикл "for(.. in ..)":

    for (var prop in user) {
    alert(prop + "=" + user[prop]); // выведет name=Ivan 
    								// затем age=32
    }
    

    С объектами, конструкторами и т.д. в JavaScript посложнее будет, хотя для понимания не так уж и много надо, запоминайте: любая функция вызванная с использованием ключевого слова "new" возвращает нам объект, а сама становится конструктором данного объекта:

    function
     User(name)
     { this.name 
     = name;
    this.status = USER_STATUS_ACTIVE;
    }
    var me = new User("Anton");
    

    Поведение функции "User()" при использовании "new" слегка изменится:

  • Данная конструкция создаст новый, пустой объект
  • Ключевое слово "this" получит ссылку на этот объект
  • Функция выполнится и возможно изменит объект через "this" (как в примере выше)
  • Функция вернёт "this" (по умолчанию)
  • Результатом выполнения кода будет следующий объект:

    me = { name: "Anton", status: 1 };

    Область видимости и чудо this

    Для тех, кто только начинает своё знакомство с JavaScript я расскажу следующие нюансы:

  • когда вы объявляете переменную или функцию, то она становится частью "window":
    var a = 1234; 
    alert(window["a"]); // => 
    1234 function myLog(message) {
    alert(message); // => 1234
    }
    window["myLog"](a);
    
  • когда искомая переменная не найдена в текущей области видимости, то её поиски будут продолжены в области видимости родительской функции:
    var a = 1234; (function(){
    var b = 4321; (function() {
    var c = 1111; alert((a+b)/c); // => 5
    })();
    })();
    
  • чудо-переменная "this" всегда указывает на текущий объект вызывающий функцию (поскольку по умолчанию все переменные и функции попадают в "window", то "this == window"):
    var a = 1234;
    function myLog() {
    alert(this); // => 
    window alert(this.a); // 
    => 1234
    }
    
  • контекст "this" можно изменить используя функции "bind()", "call()", и "apply()"
  • Всё что касается "window" относится лишь к браузерам, но поскольку книга о jQuery, то иное поведение я и не рассматриваю, но вот так прозрачно намекаю, что оно есть ;)

    Замыкания

    Изучив замыкания, можно понять много магии в JavaScript’e. Приведу пример кода с пояснениями:

    var a = 1234;
    var myFunc = function(){ var b = 4321;
    var c = 1111; return function() {
    return ((a+b)/c);
    };
    };
    var anotherFunc = myFunc(); // myFunc возвращает анонимную функцию 
    							// с "замкнутыми" значениями c и b
    alert(anotherFunc()); // => 5
    

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

    Рекомендуемые статьи по теме:

  • "Функции "изнутри", замыкания" [http://learn.javascript.ru/closures]
  • "Использование замыканий" [http://learn.javascript.ru/closures-usage]
  • "Closures: Front to Back" [http://net.tutsplus.com/tutorials/javascript-ajax/closures-front-to-back/]
  • Вводная по JavaScript затянулась, лучше почитайте: http://learn.javascript.ru/

    Вернуться к учебному плану