Html script class include

Инклюд в яваскрипте 19 марта 2007

Современный крупный сайт невозможно представить без яваскрипта, и чем ближе разработчик желает приблизить свое приложение к тому, что называется вебом 2.0, тем больше становится доля яваскрипта в общем объеме программного кода.

Большое число скриптов труднее структурировать, а элемент каждой страницы превращается в нечто подобное:

Но это полбеды. Ведь файл Page/Index.js зависит от Company.js, а тот в свою очередь от Widget/Person.js и Widget/Address.js. А те от Widget/Date.js и Box.js и т. д.

Причем загружать их нужно именно в указанной последовательности. А если страниц много? А если, например, хочется разделить какой-нибудь из виджетов на два файла? Или добавить пару новых классов? Или объединить несколько скриптов в один большой файл для ускорения загрузки?

Ведь все зависимости удобно было бы хранить непосредственно в js-файлах.

Почти в любом «взрослом» языке для этого существует конструкция include. В яваскрипте ее нет, но при должном желании ее удается сымитировать. Представьте, как удобно было бы написать в начале Company.js что-нибудь вроде:

js.include('als.Template'); js.include('als.utils.Text'); js.include('als.widget.Box'); js.include('domain.ClientsInfo.Widget.Properties'); js.include('domain.ClientsInfo.widget.Address'); js.include('domain.ClientsInfo.widget.Person'); .

Что же мешает так сделать? Или веб 2.0 способен лишь на раскрашивание кнопок?

Решение

Какие препятствия поджидают нас? Во-первых, инклюд должен полностью отрабатывать до начала выполнения кода. Во-вторых, не исключены зависимости нескольких файлов от одного модуля и загружать его дважды совсем не хочется. В-третьих, требуется какой-нибудь механизм загрузки файлов с сервера. Для начала препятствий хватит.

На дворе 2007 год, и подавляющее большинство браузеров поддерживают XHTTPRequest — именно им и следует воспользоваться. Этот объект работает в двух режимах: асинхронном (когда указывается функция обратного вызова) и синхронном (запрос происходит непосредственно во время вызова xhttp.open() ). Нам нужен второй: при этом код загрузится прямо на месте js.include . А дальше достаточно выполнить eval(xhttp.responseText) :

01 
02
03
04
05
06
07
08
09
10
11
12
13
14
//js.js js = <>; js.loadedModules = <>; ┘ js.include = function(path) < if(js.loadedModules[path]) return; var transport = js.getXHTTPTransport(); transport.open('GET', js.rootUrl + path.replace(/\./g, '/') + '.js', false); transport.send(null); var code = transport.responseText; eval(code); >

Вот и все. Теперь перед загрузкой скриптов достаточно подключить js.js и инклюд работает.

Модули

Полезно вынести в отдельную команду объявление загруженного модуля. Например, в начале каждого файла писать js.module(«js.Event») , а саму функцию сделать так:

Читайте также:  Create pdf from javascript

Теперь инклюд будет знать о том, что скрипт с данным адресом уже загружен, даже если js-файл подключен с помощью тега .

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

js.module("domain.Class1"); domain.Class1 = function() js.module("domain.Class2"); js.include("domain.Class1"); domain.Class2 = function() domain.Class2.prototype = new domain.Class1();

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

Неймспейсы

Раз уж мы раскладываем файлы по папкам вроде domain/ClientsInfo/Widget/Person.js, логично было бы в файле Person.js иметь описание класса domain.ClientsInfo.Widget.Person. Но если попытаться создать класс domain.ClientsInfo.Widget.Person при несуществующем domain.ClientsInfo.Widget, интерпретатор яваскрипта выдаст ошибку. Между тем, проверять в начале каждого файла, что существует объект domain.ClientsInfo.Widget, а вместе с ним и domain.ClientsInfo, и просто domain, будет утомительно и громоздко.

Объявление неймспейса имен удобно вынести в функцию объявления модуля. Например, так:

01 
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23

js.evalProperty = function(object, name, value) < if(object) < if(!object[name]) object[name] = value || true; return object[name]; >return null; > js.evalPath = function(path, context, value) < context = context || window; var pos = path.indexOf('.'); if(pos == -1) < return js.evalProperty(context, path, value); >else < var name = path.substring(0, pos); var path = path.substring(pos + 1); var obj = js.evalProperty(context, name, value); return js.evalPath(path, obj, value); >> js.module = function(path)

Загруженный код выполняется с помощью функции eval(). Это означает, что в «Мозилле» отладить его не удастся. Visual Studio более покладиста, но не балует подсветкой синтаксиса. Проблема решается подключением отлаживаемых скриптов тегом .

Источник

HTML-импорт — include для веба: часть 1

Перевод статьи «HTML Imports #include for the web», Eric Bidelman.

От переводчика

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

Читайте также:  Gridsearchcv python что это

Для чего нужен HTML-импорт?

Начало работы

В наборе стандартов Web Components есть стандарт HTML Imports, который позволяет подключение HTML-документов друг в друга. В подключаемых HTML-документах разрешается Javascript и CSS, словом, все что .html обычно содержит. Это замечательный инструмент для загрузки пакетов HTML/CSS/JS кода.

Основы

Указанный URL, это расположение импорта(import location). Чтобы использовать импорт с другого домена, его расположение должно позволять междоменное разделение ресурсов(CORS):

Примечание: браузеры игнорируют повторные запросы на один и тот же URL. Это значит, что из одного адреса будет выполнена только одна загрузка сколько бы ни было подключений на странице

Проверка на поддержку браузером
function supportsImports() < return 'import' in document.createElement('link'); >if (supportsImports()) < // Good to go! >else < // Use other libraries/require systems to load files. >

Браузерная поддержка пока на ранней стадии(прим. переводчика: оригинал статьи опубликован 11 ноября 2013, теперь, наверное, другая ситуация с поддержкой). Chrome 31 первый браузер поддерживающий HTML-импорт. Chrome 36 обновлен до последней спецификации этой фичи. Вы можете включить поддержку импорта, отметив флаг «Включить экспериментальные функции веб-платформы» по адресу

в Chrome Canary. Для других браузеров это пока не работает.

Примечание: Включение экспериментальных функций позволит использовать и другие полезные фичи веб-компонентов

Бандлинг ресурсов

HTML-импорт позволяет собирать пакеты HTML/CSS/JS кода, которые в свою очередь могут использовать другие пакеты. Этот простой, но мощный функционал, может пригодиться, если вы хотите импортированием одного ресурса предоставить другим программистам какую-то библиотеку или набор стилей. Также это полезно для поддержки модульности вашего приложения. Вы даже можете отдавать на импорт целые приложения. Только подумайте, чего можно добиться таким образом.

Вы сможете экспортировать целые пакеты веб содержимого всего одной линкой.

Bootstrap это хороший пример того, как мог бы пригодиться импорт компонентов. Бутстрап состоит из различных файлов (bootstrap.css, bootstrap.js и др.), использует JQuery (как импортируемый компонент), а в результате выдает инструменты для верстки. Разработчикам нравится возможность подключать те или иные модули, по мере необходимости. Но обычно мы идем простым путем, подключая все модули бутстрапа сразу.

Импорт был бы очень полезен при использовании таких пакетов, как Bootstrap. Вот как в будущем может выглядеть его подключение:

Нужно всего лишь добавить один линк импорта. Больше не нужно подключать кучу файлов, вместо этого весь Bootstrap завернут в файл bootstrap.html:

Читайте также:  Язык программирования php изучить
События load/error

Импорт всегда загружается сразу же, в порядке нахождения тега

 function handleLoad(e) < console.log('Loaded import: ' + e.target.href); >function handleError(e)

Примечание: обработчики событий загрузки/ошибки нужно объявлять перед импортом, так как браузер загружает импорт в тот момент, когда встречает тег импорта. Если на момент импорта нет обработчика загрузки, в консоли выведется ошибка undefined function.

Вы, также, можете динамически создавать импорт:

var link = document.createElement('link'); link.rel = 'import'; link.href = 'file.html' link.onload = function(e) ; link.onerror = function(e) ; document.head.appendChild(link); 

Использование содержимого импорта

Элемент импорта на странице не указывает браузеру, где размещать содержимое импорта. Он только говорит браузеру получить документ для его дальнейшего использования. Чтобы использовать содержимое импорта, нам нужно написать немного JS кода.

Вот он момент прозрения, импорт, это всего-лишь документ. На самом деле, содержимое импорта так и называется документ импорта(import document). А использовать результат импорта вы можете стандартными средствами DOM API!

link.import
var content = document.querySelector('link[rel="import"]').import; 
  • Браузер не поддерживает импорт.
  • У элемента нет атрибута rel=»import» .
    Объект не добавлен в DOM.
    Или был удален из DOM
    Ресурс не поддерживает CORS.

Полный пример

Допустим у нас есть страница warnings.html :

 
h3

Warning!

This page is under construction

Heads up!

This content may be out of date

Вы можете использовать только необходимую вам часть импортированной страницы:

  .   

Скрипты в импорте

Импорт работает не совсем, как часть документа, который его использует. Но вы, все же, можете работать с подключившей его страницей. Из импортированной страницы можно работать, как с внутренним DOM, так и с главным документом:

Пример — import.html добавляет один из своих стилей главному документу

   /* Примечание: Внутренние стили, по умолчанию применяются к импортирующему документу. Их не нужно явно добавлять в главную страницу. */ #somecontainer .  
document.currentScript.ownerDocument

мы получаем доступ к внутреннему элементу-корню импортированного документа и добавляем его кусок в главный документ (

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

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

  • Код импорта выполняется в контексте содержащего его документа. Из этого исходят две удобные вещи:
    • Функции объявленные в импорте содержатся в главном объекте window .
    • Вам не нужно делать действий вроде добавления в главный документ тегов

    Источник

Оцените статью