Внешние скрипты, порядок исполнения
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/script-async-defer.
Если JavaScript-кода много – его выносят в отдельный файл, который подключается в HTML:
Здесь /path/to/script.js – это абсолютный путь к файлу, содержащему скрипт (из корня сайта).
Браузер сам скачает скрипт и выполнит.
Можно указать и полный URL, например:
Вы также можете использовать путь относительно текущей страницы. Например, src=»https://learn.javascript.ru/lodash.js» обозначает файл из текущей директории.
Чтобы подключить несколько скриптов, используйте несколько тегов:
На заметку:
Как правило, в HTML пишут только самые простые скрипты, а сложные выносят в отдельный файл.
Браузер скачает его только первый раз и в дальнейшем, при правильной настройке сервера, будет брать из своего кеша.
Благодаря этому один и тот же большой скрипт, содержащий, к примеру, библиотеку функций, может использоваться на разных страницах без полной перезагрузки с сервера.
Если указан атрибут src , то содержимое тега игнорируется.
В одном теге SCRIPT нельзя одновременно подключить внешний скрипт и указать код.
Вот так не сработает:
Нужно выбрать: либо SCRIPT идёт с src , либо содержит код. Тег выше следует разбить на два: один – с src , другой – с кодом, вот так:
Асинхронные скрипты: defer/async
Браузер загружает и отображает HTML постепенно. Особенно это заметно при медленном интернет-соединении: браузер не ждёт, пока страница загрузится целиком, а показывает ту часть, которую успел загрузить.
Если браузер видит тег , то он по стандарту обязан сначала выполнить его, а потом показать оставшуюся часть страницы.
Например, в примере ниже – пока все кролики не будут посчитаны – нижний
не будет показан:
Начинаем считать:
Кролики посчитаны!
Такое поведение называют «синхронным». Как правило, оно вполне нормально, но есть важное следствие.
Если скрипт – внешний, то пока браузер не выполнит его, он не покажет часть страницы под ним.
То есть, в таком документе, пока не загрузится и не выполнится big.js , содержимое будет скрыто:
Этот текст не будет показан, пока браузер не выполнит big.js.
И здесь вопрос – действительно ли мы этого хотим? То есть, действительно ли оставшуюся часть страницы нельзя показывать до загрузки скрипта?
Есть ситуации, когда мы не только НЕ хотим такой задержки, но она даже опасна.
Например, если мы подключаем внешний скрипт, который показывает рекламу или вставляет счётчик посещений, а затем идёт наша страница. Конечно, неправильно, что пока счётчик или реклама не подгрузятся – оставшаяся часть страницы не показывается. Счётчик посещений не должен никак задерживать отображение страницы сайта. Реклама тоже не должна тормозить сайт и нарушать его функциональность.
А что, если сервер, с которого загружается внешний скрипт, перегружен? Посетитель в этом случае может ждать очень долго!
Вот пример, с подобным скриптом (стоит искусственная задержка загрузки):
Важная информация не покажется, пока не загрузится скрипт.
. Важная информация!
Можно поставить все подобные скрипты в конец страницы – это уменьшит проблему, но не избавит от неё полностью, если скриптов несколько. Допустим, в конце страницы 3 скрипта, и первый из них тормозит – получается, другие два его будут ждать – тоже нехорошо.
Кроме того, браузер дойдёт до скриптов, расположенных в конце страницы, они начнут грузиться только тогда, когда вся страница загрузится. А это не всегда правильно. Например, счётчик посещений наиболее точно сработает, если загрузить его пораньше.
Поэтому «расположить скрипты внизу» – не лучший выход.
Кардинально решить эту проблему помогут атрибуты async или defer :
Поддерживается всеми браузерами, кроме IE9-. Скрипт выполняется полностью асинхронно. То есть, при обнаружении браузер не останавливает обработку страницы, а спокойно работает дальше. Когда скрипт будет загружен – он выполнится.
Поддерживается всеми браузерами, включая самые старые IE. Скрипт также выполняется асинхронно, не заставляет ждать страницу, но есть два отличия от async .
Первое – браузер гарантирует, что относительный порядок скриптов с defer будет сохранён.
То есть, в таком коде (с async ) первым сработает тот скрипт, который раньше загрузится:
А в таком коде (с defer ) первым сработает всегда 1.js , а скрипт 2.js , даже если загрузился раньше, будет его ждать.
Поэтому атрибут defer используют в тех случаях, когда второй скрипт 2.js зависит от первого 1.js , к примеру – использует что-то, описанное первым скриптом.
Второе отличие – скрипт с defer сработает, когда весь HTML-документ будет обработан браузером.
Например, если документ достаточно большой…
Много много много букв
…То скрипт async.js выполнится, как только загрузится – возможно, до того, как весь документ готов. А defer.js подождёт готовности всего документа.
Это бывает удобно, когда мы в скрипте хотим работать с документом, и должны быть уверены, что он полностью получен.
async вместе с defer
При одновременном указании async и defer в современных браузерах будет использован только async , в IE9- – только defer (не понимает async ).
Атрибуты async/defer – только для внешних скриптов
Атрибуты async/defer работают только в том случае, если назначены на внешние скрипты, т.е. имеющие src .
При попытке назначить их на обычные скрипты , они будут проигнорированы.
Тот же пример с async :
Важная информация теперь не ждёт, пока загрузится скрипт.
. Важная информация!
При запуске вы увидите, что вся страница отобразилась тут же, а alert из внешнего скрипта появится позже, когда загрузится скрипт.
Эти атрибуты давно «в ходу»
Большинство современных систем рекламы и счётчиков знают про эти атрибуты и используют их.
Перед вставкой внешнего тега понимающий программист всегда проверит, есть ли у него подобный атрибут. Иначе медленный скрипт может задержать загрузку страницы.
Забегая вперёд
Для продвинутого читателя, который знает, что теги можно добавлять на страницу в любой момент при помощи самого javascript, заметим, что скрипты, добавленные таким образом, ведут себя так же, как async . То есть, выполняются как только загрузятся, без сохранения относительного порядка.
Если же нужно сохранить порядок выполнения, то есть добавить несколько скриптов, которые выполнятся строго один за другим, то используется свойство script.async = false .
Выглядит это примерно так:
function addScript(src) < var script = document.createElement('script'); script.src = src; script.async = false; // чтобы гарантировать порядок document.head.appendChild(script); >addScript('1.js'); // загружаться эти скрипты начнут сразу addScript('2.js'); // выполнятся, как только загрузятся addScript('3.js'); // но, гарантированно, в порядке 1 -> 2 -> 3
Более подробно работу со страницей мы разберём во второй части учебника.
Итого
- Скрипты вставляются на страницу как текст в теге , либо как внешний файл через
- Специальные атрибуты async и defer используются для того, чтобы пока грузится внешний скрипт – браузер показал остальную (следующую за ним) часть страницы. Без них этого не происходит.
- Разница между async и defer : атрибут defer сохраняет относительную последовательность скриптов, а async – нет. Кроме того, defer всегда ждёт, пока весь HTML-документ будет готов, а async – нет.
Очень важно не только читать учебник, но делать что-то самостоятельно.
Решите задачки, чтобы удостовериться, что вы всё правильно поняли.
Задачи
Какой скрипт выполнится первым?
важность: 4
В примере ниже подключены два скрипта small.js и big.js .
Если предположить, что small.js загружается гораздо быстрее, чем big.js – какой выполнится первым?
Как подключить Javascript файл к html документу?

Предположим, что у вас есть html-документ и javascript код, который должен в нем выполняться. Код javacript может находиться как внутри html-документа, так и в отдельном файле формата *.js.
Проблема, которая очень часто появляется у начинающих пользователей: Как подключить javacript-код или файл к html документу?
В этой небольшой заметке мы рассмотрим, как это можно сделать.
Все мои уроки по Javascript здесь.
Пусть содержимое файла html будет следующее:
Документ без названия Содержимое html-файла
Ничего лишнего. Теперь код, который необходимо подключить:
alert("Javacript подключен");
Т.е. этот скрипт просто должен вывести всплывающее окно с сообщением, что «Javacript подключен» при открытии файла html-документа. Итак, рассматриваем два варианта подключения скрипта.
Вариант 1. Подключение внутри html-файла.
Делается это с помощью конструкции:
Вставим этот код можно внутри тэга , либо внутри тега . В итоге, содержимое html файла может буть следующим:
Документ без названия Содержимое html-файла
Проверяем, что все работает:
Отлично. Окно с сообщением появилось.
Вариант 2. Подключение внешнего файла скрипта с кодом.
Если javascript-код находится во внешнем файле, то способ его подключение будет несколько другим. Пусть такой файл называется script.js. О том, как создать javascript файл я писал здесь.
В итоге, имеем два файла index.html и script.js, которые находятся в одной папке.

Как теперь подключить скрипт к html файлу? В этом случае нужно воспользоваться тэгом
Об адресах и как их правильно выставлять информация здесь.
Так как файл скрипта script.js находится в той же папке, что и файл index.html, то html-код может быть следующим:
Документ без названия Содержимое html-файла
Как правило, скрипты подключаются в области документа. Если все сделано правильно, то вы точно также сможете увидеть всплывающее окно с надписью, что «javascript подключен». Это два основных способа, как вы можете подключить код javascript к html документу.
Пользуйтесь этим на практике.
Все мои уроки по Javascript здесь.
Bada Web-based приложение: Взаимодействия C++ и Javascript
Коротко о главном: как известно, из С++ кода достаточно вызвать метод EvaluateJavascriptN для передачи данных или вызова события. А вот из Яваскрипта вызвать С++ метод пока что не возможно. Для этого нам придется воспользоваться очень уж железным ломом. Но если вам удобнее разрабатывать приложение на html/css/Javascript, но при этом вам нужен доступ к нативному коду и локальным файлам, то вам определенно под кат. Там мы рассмотрим этот ломик подробнее и заготовим себе Project Template для быстрого старта.
Вначале попрошу извинения, за мои пробелы в знании русского языка, но я приложу максимум усилий, что бы текст был без ошибок.
Чуть-чуть лирики
- приложение с десяткой кнопок и проигрывание звуков
- приложение с некоторыми статьями для чтения
Начало пути
Засучив рукава быстренько скачал Bada SDK. И создавая новой проект меня заинтересовал template «Web-Based Application». В нем создался вэб контрол в который загружался локальный html файл, а поиск в интернете подсказал, что бада располагает -webkit движком и эти факты меня уж очень сильно обрадовали. Но радость моя была поспешной: аудио не проигрывается и получать котент локального файла через ajax нельзя в силу безопасности. Вот здесь то и пришло в голову, что надо как то связать Яваскрипт и С++, таким образом, в первом случае по нажатию кнопки мы пошлем в нативный код соответствующий путь к файлу и оттуда проиграем звук. Ну а во втором, мы пошлем снова же путь к файлу и получим его контент, аля XmlHttpRequest.
А вот и лом
Просмотрев поближе вэб контрол, оказывается, в распоряжении у нас только ILoadingListener. Мельком в коде упоминается более обнадеживающий IWebUiListener. Но у разработчиков пока не дошли руки его привести в исполнение, поэтому вернемся к ILoadingListener. К счастью, он работает так как надо, то-есть если добавим в body iframe или вызовем window.frames.myFrame.location.reload() мы получим в коде события о загрузке. Должен заметить, что атрибут src у iframe мы можем даже не указывать. Ну а теперь здесь все очень просто, меняем hash, делаем iframe reload и получаем в OnLoadingRequested url страницы и соответственно реагируем. Правда, увидев, что вэб контрол имеет метод GetTitle, я остановился на том, что меняю заголовок страницы и получаю его в OnLoadingStarted. Таким образом у нас нет проблем с урл кодировкой.
Украшаем ломик — получаем framework
Возникло желание создать готовую базу с которой можна начинать писать подобного рода приложения. Вот основные примеры/задачи кода::
JavaScript:
bada.sendData();
эта функция передаст в С++ «key=Value&secondKey=secondValue» и там это пропарсится в WebCppProxy::Data::StringDictionary.
Еще примеры не требующие объяснений:
bada.getFile( ‘/Res/help.html’ , function (responseText)< $( '#helpDialog' ).html(responseText)>);
bada.playAudio( ‘/Res/sound.mp3’ );
Для лучшего тестирования была создана консоль, которая будет доступна если прописать атрибут debug=’true’ в теге body
C++
Здесь вожатым выступает класс WebCppProxy::WebProxyForm — это тот же вэб контрол, но в котором осуществляется взаимосвязь с Яваскриптом. Вожатый получает из текущего приложения класс унаследованный от WebCppProxy::ICommandListener и в ходе выполнения вызывает определенные методы.
virtual void OnCommand(Osp::Base:: String command) = 0;
virtual void OnCommand(WebCppProxy::Data::StringDictionary* dictionary) = 0;
virtual void OnReady() = 0; // ondomready
Чтение файла и проигрывание mp3 происходит за кулисами. Имеются наброски кода для работы с базой данных, но после отсутствия audio я был приятно удивлен, что в Bada реализован localStorage.
Вот, собственно очень кратко описал цель и реализацию, а заготовленный проект можно скачать/посмотреть здесь: Assembla
Код предоставлен только для ознакомления, и не из-за копирайта, а из-за соображения безопасности/стабильности/продуктивности, ведь все еще очень сыро.
Надеюсь помог кому-то в написании приложений для Bada. Хотя используя html5/css/javascript можна их легко портировать под другие платформы и наоборот.
Добавляем поддержку скриптов JavaScript в C++
В данной заметке я опишу способ добавления поддержки JavaScript скриптов в приложение на C++ с помощью библиотеки Tiny-JS.

Tiny-JS представляет из себя библиотеку для встраивания в C++, обеспечивающая выполнение JavaScript кода, с поддержкой биндингов (возможность вызывать код C++ из скриптов)
Сначала я хотел использовать популярные библиотеки ChaiScript, Duktape или подключить Lua, но из-за зависимостей и возможных сложностей в портируемости на разные платформы, было принято решение найти простую, минимальную, но мощную MIT JS либу, этим критериям отвечает Tiny-JS. Единственный минус этой библиотеки в отсутствии поддержки/развития автором, однако ее код достаточно прост, что позволяет взять поддержку на себя, если это потребуется.
Далее добавьте в код который отвечает за скрипты хидеры Tiny-JS:
#include "tiny-js/TinyJS.h" #include "tiny-js/TinyJS_Functions.h"
На этап сборки добавьте .cpp файлы TinyJS, далее можно приступать к написанию загрузки и запуска скриптов.