12. JavaScript и браузер

Браузер – крайне враждебная программная среда

Дуглас Крокфорд, «Язык программирования JavaScript» (видеолекция)

Следующая часть книги расскажет о веб-браузерах. Без них не было бы JavaScript. А если бы и был, никто бы не обратил на него внимания.

Технологии веба с самого начала были децентрализованными – не только технически, но и с точки зрения их эволюции. Различные разработчики браузеров добавляли новую функциональность «по случаю», непродуманно, и часто эта функциональность обретала поддержку в других браузерах и становилась стандартом.

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

Сети и интернет

Компьютерные сети появились в 1950-х. Если вы проложите кабель между двумя или несколькими компьютерами и разрешите им передавать данные, вы может делать много удивительных вещей. А если связь двух машин в одном здании позволяет делать много разного, то связь компьютеров по всей планете должна позволять ещё больше. Технология, позволяющая это сделать, была создана в 1980-х, и получившаяся сеть зовётся интернетом. И она оправдала ожидания.

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

Стиль общения по сети описывает сетевой протокол. Есть протоколы для отправки e-мейлов, для получения e-мейлов, для распространения файлов и даже для контроля над компьютерами, заражёнными вредоносным софтом.

К примеру, простой протокол чата может состоять из одного компьютера, отправляющего биты, представляющие текст «ЧАТ?» на другой, а второго отвечающего текстом «ОК!», для подтверждения того, что он понял протокол. Дальше они могут перейти к отправке друг другу текстов, чтения полученных текстов и вывода их на экран.

Большинство протоколов построено на основе других протоколов. Наш протокол чата из примера рассматривает сеть как потоковое устройство, в которое можно вводить биты и заказывать их приход на конкретный адрес в правильном порядке. А обеспечение этого процесса – само по себе является сложной задачей. Transmission Control Protocol (TCP) – протокол, решающий эту задачу. Все устройства, подключённые к интернету, говорят на нём, и большинство общения в интернете построено на его основе.

Соединение по TCP работает так: один компьютер ждёт, или «слушает», пока другие не начнут с ним говорить. Чтобы можно было слушать разные виды общения в одно и то же время, для каждого из них назначается номер (называемый портом). Большинство протоколов устанавливают порт, используемый по умолчанию. К примеру, если мы отправляем е-мейл по протоколу SMTP, компьютер, через который мы его шлём, должен слушать порт 25.

Тогда другой компьютер может установить соединение, связавшись с компьютером назначения по правильному порту. Если машина назначения доступна, и она слушает этот порт, соединение устанавливается. Слушающий компьютер зовётся сервером, а соединяющийся – клиентом.

Такое соединение работает как двусторонняя труба, по которой текут биты – обе машины могут помещать в неё данные. Когда биты переданы, другая машина может их прочесть. Это удобная модель. Можно сказать, что TCP обеспечивает абстракцию сети.

Веб

World Wide Web, всемирная паутина (это не то же самое, что весь интернет в целом) – набор протоколов и форматов, позволяющий нам посещать странички через браузер. Web (рус. «паутина») в названии обозначает, что страницы можно легко связать друг с другом, в результате чего образуется гигантская сеть-паутина, по которой движутся пользователи.

Чтобы добавить в Веб содержимое, вам нужно соединить машину с интернетом и заставить её слушать 80 порт, используя протокол передачи гипертекста, Hypertext Transfer Protocol (HTTP). Он позволяет другим компьютерам запрашивать документы по сети.

Каждый документ имеет имя в виде универсального локатора ресурсов, Universal Resource Locator (URL), который выглядит примерно так:

http://eloquentjavascript.net/12_browser.html

|   |           |        |

протокол   сервер        путь

Первая часть говорит нам, что URL использует протокол HTTP (в отличие от, скажем, зашифрованного HTTP, который записывается как https://). Затем идёт часть, определяющая, с какого сервера мы запрашиваем документ. Последняя – строка пути, определяющая конкретный документ или ресурс.

У каждой машины, присоединённой к интернету, есть свой адрес IP, который выглядит как 37.187.37.82. Его иногда можно использовать вместо имени сервера в URL. Но цифры сложнее запоминать и печатать, чем имена – поэтому обычно вы регистрируете доменное имя, которое указывает на конкретную машину (или набор машин). Я зарегистрировал eloquentjavascript.net, указывающий на IP-адрес машины, которую я контролирую, поэтому можно использовать этот адрес для предоставления веб-страниц.

Если вы введёте указанный URL в адресную строку браузера, он попробует запросить и показать документ, находящийся по этому URL. Во-первых, браузеру надо выяснить, куда ссылается домен eloquentjavascript.net. Затем, используя протокол HTTP, он соединяется с сервером по этому адресу, и спрашивает его ресурс по имени /12_browser.html

В главе 17 мы подробнее рассмотрим протокол HTTP.

HTML

HTML, или язык разметки гипертекста, Hypertext Markup Language – формат документа, использующийся для веб-страниц. HTML содержит текст и теги, придающие тексту структуру, описывающие такие вещи, как ссылки, параграфы и заголовки.

Простой HTML документ может выглядеть так:

 

  Моя домашняя страничка

 

 

  

Моя домашняя страничка

  

Привет, я Марейн и это моя домашняя страничка.

  

А ещё я книжку написал! Читайте её

   здесь.

 

Теги, окружённые угловыми скобками

<
и
>
, описывают информацию о структуре документа. Всё остальное – просто текст.

Документ начинается с

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

У HTML документов есть заголовок и тело. Заголовок содержит информацию о документе, а тело – сам документ. В нашем случае мы объявили, что название страницы будет «Моя домашняя страничка», затем описали документ, содержащий заголовок (

, то есть heading 1, заголовок 1. Есть ещё

, заголовки разных размеров) и два параграфа.

У тегов может быть несколько форм. Элемент вроде тела, параграфа и ссылки начинается открывающим тегом

и заканчивается закрывающим

. Некоторые открывающие теги, типа ссылки
, содержат дополнительную информацию в виде
имя=”значение”
. Она называется «атрибутами». В нашем случае адрес ссылки задан как
href="http://eloquentjavascript.net"
, где
href
означает «гипертекстовая ссылка», “hypertext reference”.

Некоторые теги ничего не окружают, и их не надо закрывать. Пример – тег картинки

Чтобы включать в текст документа угловые скобки, нужно пользоваться специальной записью, так как в HTML они имеют особое значение. Открывающая скобка (она же знак «меньше») записывается как

<
(«less than», «меньше, чем»), закрывающая —
>
(«greater that», «больше, чем»). В HTML амперсанд
&
, за которым идёт слово и точка с запятой, зовётся сущностью и заменяется символом, который кодируется этой последовательностью.

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

&
. В атрибуте, заключаемом в двойные кавычки, символ кавычек записывается как
"
.

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

Следующий документ будет обработан так же, как и предыдущий.


Моя домашняя страничка


Моя домашняя страничка

Привет, я Марейн и это моя домашняя страничка.

А ещё я книжку написал! Читайте её

here.

Отсутствуют теги

,
и
. Браузер знает, что
</code></pre> должен быть в <pre><code><head></code></pre>, а <pre><code><h1></code></pre> — в <pre><code><body></code></pre>. Кроме того, параграфы не закрыты, поскольку открытие нового параграфа или конец документа означают их принудительное закрытие. Также адрес не заключён в кавычки.</p>
    <p>В этой книге мы опустим теги <pre><code><html></code></pre>, <pre><code><head></code></pre> и <pre><code><body></code></pre> для краткости. Но я буду закрывать теги, и заключать атрибуты в кавычки.</p>
    <p>Также обычно я буду опускать <pre><code>doctype</code></pre>. Я не советую делать это вам – браузеры иногда могут творить странные вещи, когда вы их опускаете. Считайте, что они присутствуют в примерах по умолчанию.</p>
   </section>
   <section>
    <h3 id='214'>
     <span>HTML и JavaScript</span>
    </h2>
    <p>В контексте нашей книги самый главный тег HTML — <pre><code><script></code></pre>. Он позволяет включать в документ программу на JavaScript.</p>
    <p><pre><code><h1>Внимание, тест.</h3></code></pre></p>
    <p><pre><code><script>alert("Привет!");</script></code></pre></p>
    <p>Такой скрипт запустится сразу, как только браузер встретит тег <pre><code><script></code></pre> при разборе HTML. На странице появится диалог-предупреждение.</p>
    <p>Включать большие программы в HTML непрактично. У тега <pre><code><script></code></pre> есть атрибут <pre><code>src</code></pre>, чтобы запрашивать файл со скриптом (текст, содержащий программу на JavaScript) с адреса URL.</p>
    <p><pre><code><h1>Внимание, тест.</h3></code></pre></p>
    <p><pre><code><script src="code/hello.js"></script></code></pre></p>
    <p>В файле code/hello.js содержится та же простая программа <pre><code>alert('Привет!');</code></pre>. Когда страница ссылается на другой URL и включает его в себя, браузер подгружает этот файл и включает их в страницу.</p>
    <p>Тег <pre><code>script</code></pre> всегда надо закрывать при помощи <pre><code></script></code></pre>, даже если он не содержит кода и ссылается на файл скрипта. Если вы забудете это сделать, оставшаяся часть страницы будет обработана как скрипт.</p>
    <p>Некоторые атрибуты тоже могут содержать программу JavaScript. У тега (на странице он выглядит как кнопка) есть атрибут <pre><code>onClick</code></pre>, и его содержимое будет запущено, когда по кнопке щёлкнут мышкой.</p>
    <p><pre><code><button onclick="alert('Бабах!');">НЕ ЖМИ</button></code></pre></p>
    <p>Заметьте, что я использовал одинарные кавычки для строки в атрибуте <pre><code>onclick</code></pre>, поскольку двойные кавычки уже используются в самом атрибуте. Можно было бы использовать <pre><code>"</code></pre>, но это бы затруднило чтение.</p>
   </section>
   <section>
    <h3 id='215'>
     <span>Песочница</span>
    </h2>
    <p>Запуск скачанных из интернета программ небезопасен. Вы не знаете ничего о тех людях, которые делали посещаемые вами сайты, и они не всегда доброжелательны. Запуская программы злых людей, вы можете заразить компьютер вирусами, потерять свои данные или дать доступ к своим аккаунтам третьим лицам.</p>
    <p>Но привлекательность веба в том, что по нему можно сёрфить без обязательного доверия всем посещаемым страницам. Поэтому браузеры сильно ограничивают то, что может сделать программа JavaScript. Она не может открывать файлы на компьютере, или менять что-либо, не связанное со страницей, в которую она встроена.</p>
    <p>Изолированное таким образом окружение называется песочницей – в том смысле, что программа безобидно играется в песочнице. Представляйте, однако, эту песочницу как клетку из толстых стальных прутьев.</p>
    <p>Сложность в создании песочницы – позволять программам делать достаточно много, чтобы они были полезными, при этом ограничивая их от совершения опасных действий. Много из того, что делает пользователь, например общение с другими серверами или чтение содержимого буфера обмена, можно использовать для нарушения приватности.</p>
    <p>Время от времени кто-то придумывает способ обойти ограничения браузера и сделать что-то вредное, от утечки некоей приватной информации до полного контроля над компьютером, где запущен скрипт. Разработчики исправляют эту дырку в браузере, и снова всё хорошо – до появления следующей проблемы, которая, можно надеяться, будет опубликована, и не тайно использоваться правительством или мафией.</p>
   </section>
   <section>
    <h3 id='216'>
     <span>Совместимость и браузерные войны</span>
    </h2>
    <p>На ранних стадиях развития Веба браузер по имени Mosaic занимал большую часть рынка. Через несколько лет баланс сместился в сторону Netscape, который затем был сильно потеснён браузером Internet Explorer от Microsoft. В любой момент превосходства одного из браузеров его разработчики позволяли себе в одностороннем порядке изобретать новые свойства веба. Так как большинство людей использовали один и тот же браузер, сайты просто начинали использовать эти свойства, не обращая внимания на остальные браузеры.</p>
    <p>Это были тёмные века совместимости, которые иногда называли «войнами браузеров». Веб-разработчики сталкивались с двумя или тремя несовместимыми платформами. Кроме того, браузеры около 2003 года были полны ошибок, причём у каждого они были свои. Жизнь людей, создававших веб-страницы, была тяжёлой.</p>
    <p>Mozilla Firefox, некоммерческое ответвление Netscape, бросил вызов гегемонии Internet Explorer в конце 2000-х. Так как Microsoft особо не стремилась к конкуренции, Firefox отобрал солидную часть рынка. Примерно в это время Google представил свой браузер Chrome, а Apple – Safari. Это привело к появлению четырёх основных игроков вместо одного.</p>
    <p>У новых игроков были более серьёзные намерения по отношению к стандартам и больше инженерного опыта, что привело к лучшей совместимости и меньшему количеству багов. Microsoft, видя сжатие своей части рынка, приняла эти стандарты. Если вы начинаете изучать веб-разработку сегодня – вам повезло. Последние версии основных браузеров работают одинаково и в них мало ошибок.</p>
    <p>Нельзя сказать, что ситуация уже идеальная. Некоторые люди в вебе по причинам инерционности или корпоративных правил используют очень старые браузеры. Пока они не отомрут совсем, написание веб-страниц для них потребует мистических знаний об их недостатках и причудах. Эта книга не про причуды – она представляет современный, разумный стиль веб-программирования.</p>
   </section>
  </section>

                    <div id="movable" caramel-id="01j78m0r5kdexmgsre1fes30j9"></div>

                    <div class="pagination">
                        <!-- if($content->bookInfo->litres_url == "" -->
                        
                                                            <a href="https://fb2.top/vyrazitelynyy-javascript-461328/read/part-13"
                                   class="btn btn-outline-dark btn-block btn-lg mr-1">< Назад</a>
                            
                            <a href="#" class="btn btn-outline-dark btn-block btn-lg mx-1 mt-0" data-toggle="modal"
                               data-target="#modalContents"><i class="fas fa-list-ul"></i></a>

                                                            <a href="https://fb2.top/vyrazitelynyy-javascript-461328/read/part-15"
                                   class="btn btn-outline-dark btn-block btn-lg mt-0 ml-1">Далее ></a>
                                                        <!-- // if($content->bookInfo->litres_url == "" -->
                                            </div>

                </div>

                <div class="d-none d-lg-block col-lg-4 col-xl-4">

                    <div class="sidebar">
    <div class="sidebar-inner">
        <div class="sidebar-box tg mt-3 mt-lg-0 ">
            <div class="sidebar-content">
                <div class="sidebar-title"><img src="/img/tg_logo_32.png"> ТЕЛЕГРАМ</div>
                <p>Канал с обзорами, анонсами новинок и книжными подборками</p>
                <a class="tg-btn" rel="nofollow" target="_blank" href="https://t.me/duosoft_books"
                   onclick="ym(67247512,'reachGoal','5');"><img src="/img/vestnik.knig-32.jpg"> Книжный Вестник</a>

                <div class="grey-line mb-3"></div>
                <p>Бот для удобного поиска книг (если не нашлось на сайте)</p>
                <a class="tg-btn" rel="nofollow" target="_blank" href="https://t.me/fb2top_bot"
                   onclick="ym(67247512,'reachGoal','6');"><img src="/img/bot-32.jpg"> Поиск книг</a>

                <div class="grey-line mb-3"></div>
                <p>Свежие любовные романы в удобных форматах</p>
                <a class="tg-btn" rel="nofollow" target="_blank" href="https://t.me/newlovebooks"
                   onclick="ym(67247512,'reachGoal','7');"><img src="/img/newlovebooks-32.jpg"> Любовные романы</a>

                <div class="grey-line mb-3"></div>
                <p>О психологии, саморазвитии и личностном росте</p>
                <a class="tg-btn" rel="nofollow" target="_blank" href="https://t.me/hotpsychologybooks "
                   onclick="ym(67247512,'reachGoal','21');"><img src="/img/hotpsychologybooks-32.jpg"> Саморазвитие</a>

                <div class="grey-line mb-3"></div>
                <p>Детективы и триллеры, все новинки</p>
                <a class="tg-btn" rel="nofollow" target="_blank" href="https://t.me/hotdetectivebooks"
                   onclick="ym(67247512,'reachGoal','14');"><img src="/img/DETECTIVE-32.jpg"> Детективы</a>

                <div class="grey-line mb-3"></div>
                <p>Фантастика и фэнтези, все новинки </p>
                <a class="tg-btn" rel="nofollow" target="_blank" href="https://t.me/hotfictionbooks"
                   onclick="ym(67247512,'reachGoal','15');"><img src="/img/fantasy-32.jpg"> Фантастика</a>

                <div class="grey-line mb-3"></div>
                <p>Отборные классические книги </p>
                <a class="tg-btn" rel="nofollow" target="_blank" href="https://t.me/freeclassicbooks"
                   onclick="ym(67247512,'reachGoal','16');"><img src="/img/classicbooks-32.jpg"> Классика</a>


            </div>
        </div>
        
        
        
        
        
        
        
        <div class="sidebar-box vk mt-3">
            <div class="sidebar-content">
                <div class="sidebar-title"><img src="/img/vk.png"> ВКОНТАКТЕ</div>
                <p>Цитаты, афоризмы, стихи, книжные подборки, обсуждения и многое другое</p>
                <a class="vk-btn" rel="nofollow" target="_blank" href="https://vk.com/duosoft_books"
                   onclick="ym(67247512,'reachGoal','9');"><img src="/img/vestnik.knig-32.jpg"> Книжный Вестник</a>
            </div>
        </div>

        <div class="sidebar-box insta mt-3">
            <div class="sidebar-content">
                <div class="sidebar-title"> БИБЛИОТЕКИ</div>
                <p>Библиотека с любовными романами, которая наверняка придётся по вкусу женской части аудитории</p>
                <a class="insta-btn" target="_blank" href="https://ladylib.top"><img src="/img/newlovebooks-32.jpg">
                    Любовные романы</a>

                <div class="grey-line mb-3"></div>
                <p>Библиотека с фантастикой и фэнтези, а также смежных жанров</p>
                <a class="insta-btn" target="_blank" href="https://fictionbooks.top"><img src="/img/fantasy-32.jpg">
                    Фантастика</a>

                <div class="grey-line mb-3"></div>
                <p>Самые популярные книги в формате фб2</p>
                <a class="insta-btn" target="_blank" href="https://фб2.рф"><img src="/img/classicbooks-32.jpg"> Топ фб2
                    книги</a>
            </div>
        </div>

        
    </div>

</div>

                </div>
            </div>

        </div>


        <div class="modal fade" id="modalContents" tabindex="-1" aria-labelledby="modalContentsTitle"
             aria-hidden="true">
            <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
                <div class="modal-content">
                    <div class="modal-header">
                        <h3 class="modal-title p-0">Оглавление</h3>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">×</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <a rel='nofollow' href='/abuse?bookId=461328'><i class='fas fa-exclamation-circle'></i> Пожаловаться</a><ul class='pl-2'><li class='mg-0 mt-3 mb-3'><a href='https://fb2.top/vyrazitelynyy-javascript-461328'>К описанию</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-1#1'>Введение</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-2#2'>О программировании</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-2#3'>Почему язык имеет значение</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-2#4'>Что такое JavaScript?</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-2#5'>Код, и что с ним делать</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-3#6'>1.  Величины, типы и операторы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-3#7'>Величины</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-3#8'>Числа</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-3#9'>Арифметика</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-3#10'>Специальные числа</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-3#11'>Строки</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-3#12'>Унарные операторы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-3#13'>Булевские величины</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-3#14'>Сравнения</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-3#15'>Неопределённые значения</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-3#16'>Автоматическое преобразование типов</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-3#17'>Короткое вычисление логических операторов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-3#18'>Итог</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-4#19'>2.  Структура программ</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#20'>Выражения и инструкции</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#21'>Переменные</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-4#22'>Переменные как щупальца</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#23'>Ключевые и зарезервированные слова</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#24'>Окружение</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#25'>Функции</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-4#26'>Диалог alert</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#27'>Функция console.log</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#28'>Возвращаемые значения</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#29'>prompt  и confirm</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#30'>Управление порядком выполнения программы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#31'>Условное выполнение</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#32'>Циклы while и do</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#33'>Отступы в коде</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#34'>Циклы for</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#35'>Выход из цикла</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#36'>Короткое обновление переменных</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#37'>Работаем с переменными при помощи switch</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#38'>Регистр имён</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#39'>Комментарии</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#40'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-4#41'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-4#42'>Треугольник в цикле</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-4#43'>FizzBuzz</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-4#44'>Шахматная доска</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-5#45'>3.  Функции</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#46'>Определение функции</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#47'>Параметры и область видимости</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#48'>Вложенные области видимости</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#49'>Функции как значения</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#50'>Объявление функций</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#51'>Стек вызовов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#52'>Необязательные аргументы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#53'>Замыкания</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#54'>Рекурсия</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#55'>Выращиваем функции</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#56'>Функции и побочные эффекты</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#57'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-5#58'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-5#59'>Минимум</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-5#60'>Рекурсия</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-5#61'>Считаем бобы</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-6#62'>4.  Структуры данных: объекты и массивы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#63'>Белка-оборотень</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#64'>Наборы данных</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#65'>Свойства</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#66'>Методы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#67'>Объекты</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#68'>Изменчивость (Mutability)</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#69'>Журнал оборотня</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#70'>Вычисляем корреляцию</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#71'>Объекты как карты (map)</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#72'>Итоговый анализ</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#73'>Дальнейшая массивология</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#74'>Строки и их свойства</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#75'>Объект arguments</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#76'>Объект Math</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#77'>Объект global</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#78'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-6#79'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-6#80'>Сумма диапазона</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-6#81'>Обращаем вспять массив</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-6#82'>Список</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-6#83'>Глубокое сравнение</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-7#84'>5.  Функции высшего порядка</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#85'>Абстракции</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#86'>Абстрагируем обход массива</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#87'>Функции высшего порядка</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#88'>Передача аргументов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#89'>JSON</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#90'>Фильтруем массив</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#91'>Преобразования при помощи map</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#92'>Суммирование при помощи reduce</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#93'>Компонуемость</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#94'>Цена</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#95'>Пра-пра-пра-пра-пра-…</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#96'>Связывание</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#97'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-7#98'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-7#99'>Свёртка</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-7#100'>Разница в возрасте матерей и их детей</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-7#101'>Историческая ожидаемая продолжительность жизни</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-7#102'>Every  и some</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-8#103'>6.  Тайная жизнь объектов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#104'>История</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#105'>Методы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#106'>Прототипы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#107'>Конструкторы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#108'>Перегрузка унаследованных свойств</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#109'>Нежелательное взаимодействие прототипов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#110'>Объекты без прототипов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#111'>Полиморфизм</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#112'>Форматируем таблицу</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#113'>Геттеры и сеттеры</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#114'>Наследование</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#115'>Оператор instanceof</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#116'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-8#117'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-8#118'>Векторный тип</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-8#119'>Ещё одна ячейка</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-8#120'>Интерфейс к последовательностям</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-9#121'>7.  Проект: электронная жизнь</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#122'>Определение</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#123'>Изображаем пространство</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#124'>Программный интерфейс существ</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#125'>Мировой объект</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#126'>this  и его область видимости</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#127'>Оживляем мир</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#128'>Оно двигается</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#129'>Больше форм жизни</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#130'>Более жизненная ситуация</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#131'>Обработчики действий</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#132'>Населяем мир</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#133'>Вдохнём жизнь</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-9#134'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-9#135'>Искусственный идиот</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-9#136'>Хищники</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-10#137'>8.  Поиск и обработка ошибок</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-10#138'>Ошибки программистов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-10#139'>Строгий режим (strict mode)</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-10#140'>Тестирование</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-10#141'>Отладка (debugging)</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-10#142'>Распространение ошибок</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-10#143'>Исключения</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-10#144'>Подчищаем за исключениями</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-10#145'>Выборочный отлов исключений</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-10#146'>Утверждения (Assertions)</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-10#147'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-10#148'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-10#149'>Повтор</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-10#150'>Запертая коробка</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-11#151'>9.  Регулярные выражения</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#152'>Создаём регулярное выражение</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#153'>Проверяем на совпадения</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#154'>Ищем набор символов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#155'>Повторяем части шаблона</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#156'>Группировка подвыражений</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#157'>Совпадения и группы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#158'>Тип даты</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#159'>Границы слова и строки</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#160'>Шаблоны с выбором</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#161'>Механизм поиска</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#162'>Откаты</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#163'>Метод replace</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#164'>Жадность</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#165'>Динамическое создание объектов RegExp</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#166'>Метод search</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#167'>Свойство lastIndex</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#168'>Циклы по вхождениям</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#169'>Разбор INI файлы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#170'>Международные символы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#171'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-11#172'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-11#173'>Регулярный гольф</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-11#174'>Кавычки в тексте</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-11#175'>Снова числа</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-12#176'>10.  Модули</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-12#177'>Зачем нужны модули</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-12#178'>Пространство имён</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-12#179'>Повторное использование</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-12#180'>Устранение связей (Decoupling)</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-12#181'>Использование функций в качестве пространств имён</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-12#182'>Объекты в качестве интерфейсов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-12#183'>Отсоединяемся от глобальной области видимости</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-12#184'>Выполняем данные как код</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-12#185'>Require</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-12#186'>Медленная загрузка модулей</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-12#187'>Разработка интерфейса</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-12#188'>Предсказуемость</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-12#189'>Компонуемость</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-12#190'>Многослойные интерфейсы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-12#191'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-12#192'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-12#193'>Названия месяцев</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-12#194'>Вернёмся к электронной жизни</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-12#195'>Круговые зависимости</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-13#196'>11.  Проект: язык программирования</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-13#197'>Разбор (parsing)</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-13#198'>Структура синтаксического дерева</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-13#199'>Интерпретатор</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-13#200'>Специальные формы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-13#201'>Окружение</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-13#202'>Функции</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-13#203'>Компиляция</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-13#204'>Мошенничество</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-13#205'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-13#206'>Массивы</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-13#207'>Замыкания</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-13#208'>Комментарии</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-13#209'>Чиним область видимости</a></li><li class='actual mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-14#210'>12.  JavaScript и браузер</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-14#211'>Сети и интернет</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-14#212'>Веб</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-14#213'>HTML</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-14#214'>HTML  и JavaScript</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-14#215'>Песочница</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-14#216'>Совместимость и браузерные войны</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-15#217'>13.  Document Object Model</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#218'>Деревья</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#219'>Стандарт</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#220'>Обход дерева</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#221'>Поиск элементов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#222'>Меняем документ</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#223'>Создание узлов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#224'>Атрибуты</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#225'>Расположение элементов (layout)</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#226'>Стили</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#227'>Каскадные стили</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#228'>Селекторы запросов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#229'>Расположение и анимация</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-15#230'>Использование синуса и косинуса для вычисления координат</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#231'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-15#232'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-15#233'>Строим таблицу</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-15#234'>Элементы по имени тегов</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-15#235'>Шляпа кота</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-16#236'>14.  Обработка событий</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#237'>Обработчики событий</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#238'>События и узлы DOM</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#239'>Объекты событий</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#240'>Распространение (propagation)</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#241'>Действия по умолчанию</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#242'>События от кнопок клавиатуры</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#243'>Кнопки мыши</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#244'>Движение мыши</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#245'>События прокрутки</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#246'>События, связанные с фокусом</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#247'>Событие загрузки</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#248'>График выполнения скрипта</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#249'>Установка таймеров</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#250'>Устранение помех (debouncing)</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#251'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-16#252'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-16#253'>Цензура клавиатуры</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-16#254'>След мыши</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-16#255'>Закладки</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-17#256'>15.  Проект: игра-платформер</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#257'>Игра</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#258'>Технология</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#259'>Уровни</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#260'>Чтение уровня</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#261'>Действующие лица (актёры)</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#262'>Бремя инкапсуляции</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#263'>Рисование</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#264'>Движение и столкновение</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-17#265'>Поиск столкновений на решётке</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#266'>Актёры и действия</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#267'>Отслеживание клавиш</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#268'>Запуск игры</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-17#269'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-17#270'>Конец игры</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-17#271'>Пауза</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-18#272'>16.  Рисование на холсте</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#273'>SVG</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#274'>Элемент холста canvas</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#275'>Заливка и обводка</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#276'>Пути</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#277'>Кривые</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#278'>Рисуем круговую диаграмму</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#279'>Текст</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#280'>Изображения</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#281'>Преобразования</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#282'>Хранение и очистка преобразований</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#283'>Назад к игре</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-18#284'>Спрайты для нашей игры</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#285'>Выбор графического интерфейса</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#286'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-18#287'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-18#288'>Формы</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-18#289'>Круговая диаграмма</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-18#290'>Прыгающий мячик</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-18#291'>Предварительно рассчитанное отзеркаливание</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-19#292'>17.  HTTP</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#293'>Протокол</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#294'>Браузер и HTTP</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#295'>XMLHttpRequest</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#296'>Отправка запроса</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#297'>Асинхронные запросы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#298'>Получение данных XML</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#299'>Песочница для HTTP</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#300'>Абстрагируем запросы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#301'>Обещания</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#302'>Цените HTTP</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#303'>Безопасность и HTTPS</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#304'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-19#305'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-19#306'>Согласование содержания (content negotiation)</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-19#307'>Ожидание нескольких обещаний</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-20#308'>18.  Формы и поля форм</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-20#309'>Поля</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-20#310'>Фокус</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-20#311'>Отключённые поля</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-20#312'>Форма в целом</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-20#313'>Текстовые поля</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-20#314'>Галочки и радиокнопки</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-20#315'>Поля select</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-20#316'>Файловое поле</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-20#317'>Хранение данных на стороне клиента</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-20#318'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-20#319'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-20#320'>Верстак JavaScript</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-20#321'>Автодополнение</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-20#322'>Игра «Жизнь» Конвея</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-21#323'>19.  Проект: Paint</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-21#324'>Простая программа рисования</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-21#325'>Реализация</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-21#326'>Строим DOM</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-21#327'>Основание</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-21#328'>Выбор инструмента</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-21#329'>Цвет и размер кисти</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-21#330'>Сохранение</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-21#331'>Загрузка картинок</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-21#332'>Закругляемся</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-21#333'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-21#334'>Прямоугольники</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-21#335'>Выбор цвета</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-21#336'>Заливка</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-22#337'>20.  Node.js</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#338'>Вступление</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#339'>Асинхронность</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#340'>Команда node</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#341'>Модули</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#342'>Установка через NPM</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#343'>Модуль file system</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#344'>Модуль HTTP</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#345'>Потоки</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#346'>Простой файловый сервер</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#347'>Обработка ошибок</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#348'>Итог</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-22#349'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-22#350'>И снова согласование содержания</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-22#351'>Устранение утечек</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-22#352'>Создание директорий</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-22#353'>Общественное место в сети</a></li><li class=' mt-1 mg-1'><a href='/vyrazitelynyy-javascript-461328/read/part-23#354'>21.  Проект: веб-сайт по обмену опытом</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-23#355'>Встречи моноциклистов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-23#356'>Дизайн</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-23#357'>Длинные запросы</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-23#358'>Интерфейс HTTP</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-23#359'>Сервер</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#360'>Маршрутизация</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#361'>Выдача файлов</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#362'>Темы как ресурсы</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#363'>Поддержка длинных запросов</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-23#364'>Клиент</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#365'>HTML</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#366'>Запуск</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#367'>Показ тем</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#368'>Обновление сервера</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#369'>Обнаружение изменений</a></li><li class=' mt-1 mg-2'><a href='/vyrazitelynyy-javascript-461328/read/part-23#370'>Упражнения</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#371'>Сохранение состояния на диск</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#372'>Обнуление полей комментариев</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#373'>Улучшенные шаблоны</a></li><li class=' mt-1 mg-3'><a href='/vyrazitelynyy-javascript-461328/read/part-23#374'>А кто без скрипта?</a></li></ul>
                    </div>

                </div>
            </div>
        </div>

        <div class="modal fade" id="modalNote" tabindex="-1" role="dialog" aria-labelledby="modalNotesTitle"
             aria-hidden="true">
            <div class="modal-dialog modal-dialog-centered">
                <div class="modal-content">
                    <div class="modal-body">

                    </div>
                    <div class="modal-footer">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">закрыть</span>
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <div id="reader_nodes" class="d-none">

        </div>

        <div id="loader-fullscreen">
            <div class="d-flex justify-content-center align-items-center">
                <div class="spinner-border" role="status">
                    <span class="sr-only">Загрузка...</span>
                </div>
            </div>
        </div>

        <input name="bookId" type="hidden" value="461328">
        <input name="from_cache" type="hidden" value="0">

    </div>


    <footer id="footer">

        <div class="container menu-row">
            <div>
                <a id="btn-zoom-plus" class="pl-1" href="#"><i class="fas fa-search-plus"></i></a>
                <a id="btn-zoom-minus" class="pl-3" href="#"><i class="fas fa-search-minus"></i></a>
                <a id="btn-moon" class="pl-3" href="#"><i class="far fa-moon"></i></a>
                <a id="btn-sun" class="pl-3" href="#"><i class="fas fa-sun "></i></a>
            </div>
            <div>

            </div>
            <div>
                <a class="tg btn px-1 d-inline d-lg-none" rel="nofollow" target="_blank"
                   href="https://vk.com/duosoft_books"
                   onclick="ym(67247512,'reachGoal','9');"><img src="/img/vk.png" class="img-fluid"
                                                                alt="Наш паблик в ВК" title="Наш паблик в ВК"></a>
                
                
                <a class="tg btn px-1 d-inline" rel="nofollow" target="_blank" href="https://t.me/duosoft_books"
                   onclick="ym(67247512,'reachGoal','5');"><img src="/img/tg_logo_32.png" class="img-fluid"
                                                                alt="Наш Телеграм канал"
                                                                title="Наш телеграм канал"><span
                        class="d-none d-md-inline"> Наш канал</span></a>
            </div>
        </div>

    </footer>


<!-- Styles -->

<link rel="stylesheet preload" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
      as="style" type="text/css"/>

<!-- Scripts -->
<script src="/lib/jquery-3.6.0.min.js" defer></script>
<script src="/lib/bootstrap-4.6.0/js/bootstrap.min.js" defer></script>
<script src="/lib/lib.js?v=2" defer></script>
<script src="/js/model/settings.js" defer></script>
<script src="/js/reader.js?v=21" defer></script>

<!-- Yandex.Metrika counter -->
<script type="text/javascript">
    (function (m, e, t, r, i, k, a) {
        m[i] = m[i] || function () {
            (m[i].a = m[i].a || []).push(arguments)
        };
        m[i].l = 1 * new Date();
        k = e.createElement(t), a = e.getElementsByTagName(t)[0], k.async = 1, k.src = r, a.parentNode.insertBefore(k, a)
    })
    (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");

    ym(67247512, "init", {
        clickmap: true,
        trackLinks: true,
        accurateTrackBounce: true,
        webvisor: true
    });
</script>
<noscript>
    <div><img src="https://mc.yandex.ru/watch/67247512" style="position:absolute; left:-9999px;" alt=""/></div>
</noscript>
<!-- /Yandex.Metrika counter -->

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-177760544-1"></script>
<script>
    window.dataLayer = window.dataLayer || [];

    function gtag() {
        dataLayer.push(arguments);
    }

    gtag('js', new Date());

    gtag('config', 'UA-177760544-1');
</script>

<div class="modal fade" id="modalSocials" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
        <div class="modal-content">
            <div class="modal-header">
                <h3 class="modal-title p-0">Нравится библиотека?</h3>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">×</span>
                </button>
            </div>
            <div class="modal-body">
                <p style="text-align: center">Присоединяйтесь к нашим литературным
                    сообществам!</p>
                <a class="vk-btn" rel="nofollow" target="_blank" href="https://vk.com/duosoft_books"
                   onclick="ym(67247512,'reachGoal','17');"><img src="/img/vk.png"> ВКОНТАКТЕ</a>
                
                <a class="tg-btn" rel="nofollow" target="_blank" href="https://t.me/duosoft_books"
                   onclick="ym(67247512,'reachGoal','19');"><img src="/img/tg_logo_32.png"> В ТЕЛЕГРАМ</a>
            </div>

        </div>
    </div>
</div>

<!-- catfish -->
<div caramel-id="01j78m0r68mjptaxr5j6npb1m5"></div>
<div caramel-id="01j78m1gm3wka3wb2wf3vsgc1f"></div>

</body>

</html>