Глава 3.13. Дополнительные возможности JScriptВ этой главе приведены описания нестандартных возможностей языка Microsoft JScript, реализованных в обозревателе Internet Explorer, а именно:
Мы не приводим описания объекта VBArray, используемого для доступа к массивам Visual Basic, т. к. наш справочник не содержит раздела, посвященного языку VBScript. 3.13.1. Управляющие элементы ActiveX3.13.1.1. Общее описаниеОсновные дополнения к языку JavaScript, сделанные корпорацией Microsoft, связаны с использованием управляющих элементов ActiveX. Эти элементы представляют собой динамические библиотеки, созданные в соответствии со стандартом COM. COM (Component Object Model) это стандарт создания программных компонентов, рассмотрение которого выходит за рамки нашего справочника. Для наших целей вполне достаточно воспринимать элементы ActiveX как черный ящик, выполняющий определенные действия по запросу вызвавшей его программы. Появление элементов ActiveX было порождено стремлением Microsoft создать технологию, которая могла бы успешно конкурировать с подключаемыми модулями обозревателей Netscape. Следует признать, что задача была решена исключительно удачно, т. к. в результате появился стандарт разработки платформо-зависимых программных компонентов, реализующих платформо-независимые протоколы и архитектуры. Все элементы ActiveX при установке в системе Windows регистрируются в ее регистре. При этом в качестве уникального ключа используется GUID данного элемента, т. е. его уникальный 64-разрядный шестнадцатеричный номер. Для доступа к элементу ActiveX по его GUID в HTML-документе используется элемент OBJECT, например: <OBJECT style="left: 0px; top: 0px" classid="clsid:8E27C92B-1264-101C-8A2F-040224009C02"> <PARAM NAME="_Version" VALUE="524288"> <PARAM NAME="_ExtentX" VALUE="7620"> <PARAM NAME="_ExtentY" VALUE="5080"> <PARAM NAME="_StockProps" VALUE="1"> <PARAM NAME="BackColor" VALUE="-2147483633"> <PARAM NAME="Year" VALUE="2000"> <PARAM NAME="Month" VALUE="10"> <PARAM NAME="Day" VALUE="22"> <PARAM NAME="DayLength" VALUE="1"> <PARAM NAME="MonthLength" VALUE="2"> <PARAM NAME="DayFontColor" VALUE="0"> <PARAM NAME="FirstDay" VALUE="2"> <PARAM NAME="GridCellEffect" VALUE="1"> <PARAM NAME="GridFontColor" VALUE="10485760"> <PARAM NAME="GridLinesColor" VALUE="-2147483632"> <PARAM NAME="ShowDateSelectors" VALUE="-1"> <PARAM NAME="ShowDays" VALUE="-1"> <PARAM NAME="ShowHorizontalGrid" VALUE="-1"> <PARAM NAME="ShowTitle" VALUE="-1"> <PARAM NAME="ShowVerticalGrid" VALUE="-1"> <PARAM NAME="TitleFontColor" VALUE="10485760"> <PARAM NAME="ValueIsNull" VALUE="0"> </OBJECT> Этот фрагмент HTML-документа содержит управляющий элемент ActiveX "Календарь" и будет отображаться обозревателем примерно так: Исполняющая система JScript дает нам более гибкие возможности запуска элементов ActiveX, которые описаны ниже. 3.13.1.2. Объект ActiveXObjectОбъект ActiveXObject используется для запуска объектов ActiveX. Он создается конструктором new ActiveXObject("сервер.класс" [,"адрес"?]) Здесь сервер имя COM-сервера, класс имя класса создаваемого объекта, адрес необязательное имя сетевого сервера, на котором должен быть создан заданный объект (может быть доменным именем или IP-адресом). Создание объекта на удаленном сервере действующими версиями JScirpt пока не поддерживается, т. е. аргумент адрес при вызове данного конструктора игнорируется. После создания объекта ActiveX (т. е. после запуска соответствующей программы) мы можем обращаться к его методам и свойствам, используя стандартный синтаксис языка JavaScript. Встроенных свойств и методов этот объект не имеет. Пример: если на компьютере-клиенте установлен Microsoft Word 7.0, то следующий сценарий его запустит, откроет документ Mydoc.doc, сохранит этот документ в текстовом формате и завершит работу MS Word. var word = new ActiveXObject("Word.Application"); // запускает MS Word word.Documents.Open("Mydoc.doc"); // открывает документ word.ActiveDocument.SaveAs("Mydoc.txt", 4); // 4 = текстовый формат DOS word.Quit(); // завершает работу MS Word Примечания.
Примеры использования элементов ActiveX см. в WDH+: TreeView на Веб-странице. 3.13.1.3. Функция GetObjectФункция GetObject возвращает ссылку на COM-объект, содержащийся в заданном файле. Она имеет вид GetObject(["имя_файла"][,"сервер.класс"?]) Здесь имя_файла спецификация файла, сервер имя COM-сервера, класс имя класса объектов. Если имя_файла опущено, то задание второго аргумента обязательно, в противном случае оно может быть опущено. При вызове этой функции запускается приложение, ассоциированное с заданной спецификацией файла (перечень таких ассоциаций хранится в системном регистре Windows). Если имя_файла это пустая строка "", то создается новый экземпляр объекта заданного типа. Если имя_файла опущено, то возвращается ссылка на объект данного типа, который активен в данный момент. Если такого объекта нет, то генерируется ошибка. Некоторые приложения позволяют нам активировать часть файла. Для этого следует добавить восклицательный знак (!) к имени файла и после него задать строку, указывающую на ту часть файла, которую мы хотим активировать. О том, как задавать эту строку, см. документацию к программе, с помощью которой создан данный файл. Так, например, программа автоматизации проектирования может хранить в файле чертежей несколько слоев. Для активации второго слоя в файле чертежа с именем MyCad.cad мы можем использовать строку var layerObj = GetObject("MyCad.cad!Layer2"); Если мы не укажем класс объекта, то приложение, активирующее данный файл, определяется из системного регистра. Однако, некоторые файлы могут поддерживать несколько типов объектов. В этом случае следует явно указывать второй аргумент данной функции, например: var myObj = GetObject("SAMPLE.DRW", "FIGMENT.DRAWING"); В этом примере FIGMENT имя программы, а DRAWING один из классов объектов, которые она поддерживает. После активации объекта мы можем обращаться к его методам и свойствам, используя стандартный синтаксис языка JavaScript. Встроенных свойств и методов этот объект не имеет. Функцией GetObject следует пользоваться в тех случаях, когда приложение, создающее экземпляры объектов данного класса, уже активно или когда мы хотим не только запустить приложение, но и загрузить в него файл, содержащий нужный нам объект. В остальных случаях используйте объект ActiveXObject. Если объект зарегистрирован как существующий в единственном экземпляре (например Word.Basic в Microsoft Word 7.0), то GetObject всегда возвращает ссылку на этот единственный экземпляр объекта, будучи вызвана с пустой строкой в качестве имени файла, и генерирует ошибку, если имя_файла опущено. Примечание. Приведенное описание функции GetObject и примеры ее использования позаимствованы из документации Microsoft. Дело в том, что автор не смог найти ни одного разумного применения этой функции в клиентской среде. Более того, по сообщению разработчиков, в обозревателях Interent Explorer ее применение запрещено "в целях безопасности" (см. Q239470 ). 3.13.2. Коллекции: объект EnumeratorОбъект Enumerator используется для просмотра элементов коллекций. Коллекции это списки объектов, реализованные в исполняющей системе JScript, но непосредственно не доступные пользователю. В частности, мы не можем добраться до их элементов ни с помощью индексов, ни с помощью оператора for in. Вместо этого мы должны создать для коллекции объект Enumerator, а затем последовательно перемещать его указатель от текущего элемента коллекции к следующему. Объект создается конструктором new Enumerator(коллекция) где коллекция любой объект, являющийся коллекцией. При создании объекта его указатель устанавливается на первый элемент коллекции. Следующий сценарий позаимствован из документации к JScript и демонстрирует использование данного объекта: function showDrives() { var fso = new ActiveXObject("Scripting.FileSystemObject"); var e = new Enumerator(fso.Drives); var s = ""; var name; for (e.moveFirst(); !e.atEnd(); e.moveNext()) { // просмотр всех дисков компьютера var x = e.item(); if (x.DriveType == 3) // сетевой диск? name = x.ShareName; else if (x.IsReady) name = x.VolumeName; else name = "[Диск не готов]"; s += x.DriveLetter + ": " + name + "<br>"; } return(s); } document.write(showDrives()); Объект Enumerator не имеет свойств; его методы описаны ниже.
Метод atEndСинтаксис: объект.atEnd() Результат: логическое значение Метод atEnd возвращает true, если текущий элемент коллекции является последним в ней, и false в противном случае. См. приведенный выше пример. Метод itemСинтаксис: объект.item() Результат: объект Метод item возвращает текущий элемент коллекции. Если коллекция пуста или текущий элемент не определен, то возвращается значение undefined. См. приведенный выше пример. Метод moveFirstСинтаксис: объект.moveFirst() Метод moveFirst перемещает указатель на первый элемент коллекции. См. приведенный выше пример. Метод moveNextСинтаксис: объект.moveNext() Метод moveNext перемещает указатель на следующий элемент коллекции. См. приведенный выше пример. 3.13.3. Информация о исполняющей системеОписанные ниже функции возвращают различную информацию о исполняющей системе сценариев. Их применение можно проиллюстрировать следующим примером: function GetScriptEngineInfo() { var s = ""; s += ScriptEngine() + " "; s += ScriptEngineMajorVersion() + "."; s += ScriptEngineMinorVersion() + "."; s += ScriptEngineBuildVersion(); return s; } document.write(GetScriptEngineInfo()); В результате выполнения этого сценария на экран обозревателя будет выведен примерно такой текст: JScript 5.5.5207. 3.13.3.1. Функция ScriptEngineСинтаксис: ScriptEngine() Результат: строковое значение Функция ScriptEngine возвращает одну из следующих строк, указывающую на текущий сценарный язык:
3.13.3.2. Функция ScriptEngineBuildVersionСинтаксис: ScriptEngineBuildVersion() Результат: строковое значение Функция ScriptEngineBuildVersion возвращает строку, содержащую номер сборки (build version) исполняющей системы сценариев. 3.13.3.3. Функция ScriptEngineMajorVersionСинтаксис: ScriptEngineMajorVersion() Результат: строковое значение Функция ScriptEngineMajorVersion возвращает строку, содержащую номер версии исполняющей системы сценариев. 3.13.3.4. Функция ScriptEngineMinorVersionСинтаксис: ScriptEngineMinorVersion() Результат: строковое значение Функция ScriptEngineMinorVersion возвращает строку, содержащую номер подверсии исполняющей системы сценариев. 3.13.4. Условная компиляция3.13.4.1. Понятие условной компиляцииНачиная с Internet Explorer 4.0, язык JScript поддерживает условную компиляцию сценариев. Она была введена в JScript для того, чтобы одновременно обеспечить и использование новых возможностей языка, и совместимость со старыми версиями обозревателей. Типичными примерами использования условной компиляции являются добавление в сценарий отладочного кода и трассировка исполнения сценария. Условная компиляция включается директивой @cc_on или директивами @if или @set. Директивы условной компиляции всегда следует помещать внутрь комментариев с тем, чтобы обозреватели, которые не поддерживают условную компиляцию (например, Netscape Navigator), их игнорировали. Приведем пример: /*@cc_on @*/ /*@if (@_jscript_version >= 4) alert("JScript версии 4 или выше"); @else @*/ alert("Ваш JScript устарел."); /*@end @*/ В этом примере использованы комментарии специального вида, которые используются только после
директивы @cc_on. Обозреватели, которые не поддерживают условную компиляцию,
увидят здесь только строку 3.13.4.2. Переменные условной компиляцииВ директивах условной компиляции могут использоваться предопределенные переменные, перечисленные в приведенной ниже таблице. Если значение переменной отлично от true, то она не определена и ведет себя как NaN.
3.13.4.3. Директива @cc_onСинтаксис: @cc_on Директива @cc_on включает условную компиляцию. Пример ее использования приведен выше. Альтернативный способом включения условной компиляции является использование директив @if или @set, не заключенных в комментарий. 3.13.4.4. Директива @ifСинтаксис: @if (условие1) текст1 @elif (условие2) текст2 @else текст3 @end Аргументы: условие1, условие2 логические выражения текст1, текст2, текст3 любой текст JScript Директива @if выполняет заданный фрагмент кода в зависимости от значения выражения. Если условие1 истинно, то выполняется текст1. Если условие1 ложно, присутствует необязательная директива @elif и условие2 истинно, то выполняется текст2. В противном случае, если присутствует необязательная директива @else, то выполняется текст3; если ее нет, то управление передается следующему оператору. Данная директива может содержать несколько ветвей @elif, но все они должны предшествовать ветви @else. Пример ее использования: @if (@_win32) alert("Работаем в Windows NT/95/98") @else alert("Неизвестная операционная система!"); 3.13.4.5. Директива @setСинтаксис: @set @перем = значение Аргументы: перем переменная условной компиляции значение числовое или логическое выражение Директива @set создает переменные условной компиляции. Имена таких переменных имеют синтаксис переменных JavaScript, но должны начинаться с символа "@". Значение, которое присваивается переменной, может быть любым выражением JavaScript (возможно с использованием ранее определенных переменных условной компиляции), которое возвращает числовое или логическое значение. Примеры: @set @var1 = 1 @set @var2 = (@var1 + 1) * 10; @set @var3 = @_jscript_version Если переменная используется до ее определения, то она имеет значение NaN. Поскольку это единственное значение. которое не равно самому себе, то проверку определенности значения переменной следует делать так: @if (@myVar != @myVar) | ||||||||||||||||||||||||||||||||||||||