18 Сценарии (скрипты)

Содержание

  1. Введение
  2. Дизайн документов для пользовательских агентов (ПА), поддерживающих скрипты (сценарии)
  3. Дизайн документов для ПА, не поддерживающих скрипты

 

18.1  Введение

Скрипт, выполняемый на стороне клиента (клиентский), это программа, которая может быть загружена вместе с документом HTML ил встроена прямо в него. Программа выполняется на клиентской машине при загрузке документа или в другое время, когда, например, если активируется гиперссылка. Поддержка скриптов языком HTML не зависит от языка скриптов.

Скрипты, таким образом, позволяют авторам расширить возможности документов HTML, как активные, так и интерактивные. Например:

Есть два вида скриптов, которые могут быть включены в документ HTML:

Примечание. Эта спецификация содержит более детальную информацию о сценариях в разделе о макросах сценариев.


18.2
Дизайн документов для ПА, поддерживающих скрипты

В следующем разделе обсуждаются вопросы, касающиеся ПА, поддерживающих скрипты.

18.2.1  Элемент SCRIPT

<!ELEMENT SCRIPT - - %Script;          -- операторы скрипта -->
<!ATTLIST SCRIPT
  charset     %Charset;      #ПРЕДПОЛАГАЕТСЯ  -- набор символов связанного ресурса --
  type        %ContentType;  #НЕОБХОДИМ -- тип содержимого языка скрипта --
  src         %URI;          #ПРЕДПОЛАГАЕТСЯ  -- URI внешнего скрипта --
  defer       (defer)        #ПРЕДПОЛАГАЕТСЯ  -- ПА могут отложить исполнение скрипта --
  >

Начальный тег: необходим, Конечный тег: необходим

Определения атрибутов

src = uri [CT]
Определяет местонахождение внешнего скрипта.
type = content-type [CI]
Определяет язык скрипта содержимого элемента и переопределяет язык по умолчанию. Язык сценария определяется как тип содержимого (напр., "text/javascript"). Авторы обязаны указать значение этого атрибута. Для этого атрибута нет значения по умолчанию.
language = cdata [CI]
Не рекомендуется. Определяет язык скрипта содержимого элемента. Его значением является идентификатор языка, но поскольку эти идентификаторы не стандартизованы, этот атрибут применять не рекомендуется, в отличие от атрибута type.
defer [CI]
Если установлен, этот булев атрибут подсказывает ПА, что скрипт не запущен для генерации какого-либо содержимого документа (напр., "document.write" в javascript), и, таким образом, ПА может продолжить разбор и вывод документа.

Атрибут, определённый в другом месте

Элемент SCRIPT помещает скрипт в документ. Этот элемент может появляться любое число раз в HEAD и BODY документа HTML.

Скрипт может быть определён внутри элемента SCRIPT или во внешнем файле. Если атрибут src не установлен, ПА должен интерпретировать содержимое элемента как скрипт. Если src имеет значение URI, ПА должен игнорировать содержимое элемента и затребовать скрипт по URI.
Обратите внимание, что атрибут charset относится к кодировке символов скрипта, обозначенного атрибутом src; он не касается содержимого элемента SCRIPT.

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

Синтаксис данных скрипта зависит от языка скриптов.

18.2.2  Установка языка скриптов

Поскольку HTML не соотносится с определённым языком сценариев, авторы документа должны однозначно указать ПА язык каждого скрипта. Это можно сделать, объявив значение по умолчанию или локально.

Язык сценариев по умолчанию

Авторы должны определить язык скриптов по умолчанию для всех скриптов в документе, включив следующее META объявление в HEAD:

<META http-equiv="Content-Script-Type" content="type">

где "type"  - это content type/тип содержимого, называющий язык скриптов. Примеры - "text/tcl", "text/javascript", "text/vbscript".

В отсутствие META объявления, значение по умолчанию может быть установлено заголовком "Content-Script-Type" HTTP:

    Content-Script-Type: type

где "type" это опять же content type/тип содержимого, называющий язык скриптов.

ПА должны определить язык скрипта по умолчанию в такой последовательности (приоритет от высшего к низшему):

  1. Если есть какое-либо объявление META, определяющее "Content-Script-Type", последний определяет в потоке символов язык скриптов по умолчанию.
  2. Иначе, если какой-либо заголовок HTTP определяет "Content-Script-Type", последний определяет в потоке символов язык скриптов по умолчанию.

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

Локальное объявление языка скриптов

Атрибут type должен быть определён для каждого элемента SCRIPT в документе. Значение атрибута type элемента SCRIPT переопределяет язык скриптов по умолчанию для данного элемента.

В это примере мы объявляем язык скриптов по умолчанию "text/tcl". Мы включаем один SCRIPT в "шапку", чей скрипт находится во внешнем файле и написан на языке "text/vbscript". Мы также включили SCRIPT в тело документа, который сам содержит собственный скрипт, написанный на "text/javascript".

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
     "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>A document with SCRIPT</TITLE>
<META http-equiv="Content-Script-Type" content="text/tcl">
<SCRIPT type="text/vbscript" src="http://someplace.com/progs/vbcalc">
</SCRIPT>
</HEAD>
<BODY>
<SCRIPT type="text/javascript">
...сценарий JavaScript...
</SCRIPT>
</BODY>
</HTML>

Ссылки на элементы HTML из скрипта

У каждого языка скриптов есть свой набор соглашений о том, как ссылаться на объекты HTML из скрипта. Эта спецификация не определяет стандартный механизм ссылки на объекты HTML.

В то же время, скрипты должны ссылаться на элемент в соответствии с его установленным именем. Машины скриптов должны соблюдать правило старшинства при идентификации элемента: атрибут name имеет преимущество перед атрибутом id, если оба установлены. Иначе тот или другой могут быть использованы.

18.2.3  Внутренние события

Примечание. Обращаем внимание авторов документов HTML, что изменения вскоре могут появиться в определении внутренних событий (напр., как скрипты ограничены событиями). Исследования в этой сфере проводятся членами W3C Document Object Model Working Group (см. W3C сайт http://www.w3.org/).

Определения атрибутов

onload = script [CT]
Событие onload возникает, когда ПА закончил загрузку окна или всех фрэймов FRAMESET. Этот атрибут может быть использован элементами BODY и FRAMESET.
onunload = script [CT]
Событие onunload возникает, когда ПА удаляет документ из окна или фрэйма. Этот атрибут может быть использован элементами BODY и FRAMESET.
onclick = script [CT]
Событие onclick возникает, когда указательное устройство "щёлкает" на элементе. Этот атрибут может быть использован с большинством элементов.
ondblclick = script [CT]
Событие ondblclick возникает, когда указательное устройство дважды "щёлкает" на элементе. Этот атрибут может быть использован с большинством элементов.
onmousedown = script [CT]
Событие onmousedown возникает, когда кнопка указательного устройства "нажала" на элемент. Этот атрибут может быть использован с большинством элементов.
onmouseup = script [CT]
Событие onmouseup возникает, когда кнопка указательного устройства отпущена над элементом. Этот атрибут может быть использован с большинством элементов.
onmouseover = script [CT]
Событие onmouseover возникает, когда указательное устройство проходит над элементом. Этот атрибут может быть использован с большинством элементов.
onmousemove = script [CT]
Событие onmousemove возникает, когда указательное устройство перемещается в тот момент, когда находится над элементом. Этот атрибут может быть использован с большинством элементов.
onmouseout = script [CT]
Событие onmouseout возникает, когда указательное устройство убирается с элемента. Этот атрибут может быть использован с большинством элементов.
onfocus = script [CT]
Событие onfocus возникает, когда элемент получает фокус от указательного устройства или при навигации табуляцией. Этот атрибут может использоваться в элементах: A, AREA, LABEL, INPUT, SELECT, TEXTAREA и BUTTON.
onblur = script [CT]
Событие onblur возникает, когда элемент теряет фокус от указательного устройства или при навигации табуляцией. Может использоваться с теми же элементами, что и onfocus.
onkeypress = script [CT]
Событие onkeypress возникает, когда клавиша нажата и отпущена над элементом. Этот атрибут может быть использован с большинством элементов.
onkeydown = script [CT]
Событие onkeydown event возникает, когда клавиша нажата над элементом. Этот атрибут может быть использован с большинством элементов.
onkeyup = script [CT]
Событие onkeyup возникает, когда клавиша отпущена над элементом. Этот атрибут может быть использован с большинством элементов.
onsubmit = script [CT]
onsubmit возникает при отправке формы. Применяется только к элементу FORM.
onreset = script [CT]
onreset возникает при "очистке" формы. Применяется только к элементу FORM.
onselect = script [CT]
onselect возникает, когда пользователь выделяет какой-либо текст в текстовом поле. Этот атрибут может использоваться в элементах INPUT и TEXTAREA.
onchange = script [CT]
onchange возникает, когда ЭУ теряет фокус ввода и его значение изменилось с момента получения фокуса. Применяется в элементах: INPUT, SELECT и TEXTAREA.

Можно ассоциировать действие с определённым количеством событий, возникающих при взаимодействии пользователя с ПА. Каждое из "внутренних событий", перечисленных выше, имеет значение - скрипт. Скрипт выполняется , как только возникает событие в данном элементе. Синтаксис данных скрипта зависит от языка скрипта.

ЭУ, такие как INPUT, SELECT, BUTTON, TEXTAREA и LABEL, все откликаются на определённые внутренние события. Если эти элементы находятся вне формы, они могут использоваться для расширения возможностей пользовательского интерфейса документа.

К примеру, авторы могут вставить в документ кнопку, которая не отправляет форму, а взаимодействует с сервером при активации.

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

Здесь заполнение поля userName является необходимым. Если пользователь переносит фокус с этого поля, событие onblur вызовет функцию JavaScript для того, чтобы удостовериться, что userName содержит приемлемое значение:

<INPUT NAME="userName" onblur="validUserName(this.value)">

Вот пример другого JavaScript:

<INPUT NAME="num"
    onchange="if (!checkNum(this.value, 1, 10)) 
        {this.focus();this.select();} else {thanks()}"
    VALUE="0">

Пример VBScript-обработчика события для текстового поля:

    <INPUT name="edit1" size="50">    
    <SCRIPT type="text/vbscript">
      Sub edit1_changed()
        If edit1.value = "abc" Then
          button1.enabled = True
        Else
          button1.enabled = False
        End If
      End Sub
    </SCRIPT>

Пример с использованием Tcl:

    <INPUT name="edit1" size="50">
    <SCRIPT type="text/tcl">
      proc edit1_changed {} {
        if {[edit value] == abc} {
          button1 enable 1
        } else {
          button1 enable 0
        }
      }
      edit1 onChange edit1_changed
    </SCRIPT>

Пример JavaScript для события, связанного со скриптом. Сначала - простой обработчик щелчка кнопки:

 
<BUTTON type="button" name="mybutton" value="10">
<SCRIPT type="text/javascript">
      function my_onclick() {
         . . .
      }
    document.form.mybutton.onclick = my_onclick
 </SCRIPT>
 </BUTTON>

Более интересный обработчик окна:

<SCRIPT type="text/javascript">
      function my_onload() {
         . . .
      }

      var win = window.open("some/other/URI")
      if (win) win.onload = my_onload
</SCRIPT>

В Tcl это выглядит похоже:

 <SCRIPT type="text/tcl">
     proc my_onload {} {
       . . .
     }
     set win [window open "some/other/URI"]
     if {$win != ""} {
         $win onload my_onload
     }
 </SCRIPT>

Учтите, что "document.write" или аналогичные операторы в обработчиках внутренних событий создают новый документ и записывают туда, а не модифицируют текущий документ.


18.2.4
Динамическое изменение документов

Скрипты, выполняемые при загрузке документа, могут использоваться для динамической модификации документа. Возможность сделать это зависит от самого языка скриптов (напр., оператор "document.write" в объектной модели HTML не поддерживается некоторыми производителями).

Динамическая модификация документа может быть смоделирована так:

  1. Все элементы SCRIPT выполняются в том порядке, как они загружаются.
  2. Все конструкции скриптов в данном элементе SCRIPT, генерирующем SGML CDATA, выполняются. Их комбинированный сгенерированный текст вставляется в документ вместо элемента SCRIPT.
  3. Сгенерированные CDATA выполняется заново.

Документы HTML должны соответствовать Определению Типа Данных (ОТД) HTML и до, и после обработки элемента SCRIPT.

Следующий пример иллюстрирует, как скрипты могут модифицировать документ динамически.
Скрипт:

 <TITLE>Test Document</TITLE>
 <SCRIPT type="text/javascript">
     document.write("<p><b>Hello World!<\/b>")
 </SCRIPT>

работает так же, как и :

 <TITLE>Test Document</TITLE>
 <P><B>Hello World!</B>


18.3
   Дизайн документов для ПА, не поддерживающих сценарии

В данном разделе рассматривается, как авторы могут создать документ, работающий с ПА, не поддерживающими скрипты.

18.3.1   Элемент NOSCRIPT

<!ELEMENT NOSCRIPT - - (%block;)+
  -- контейнер для альтернативного содержимого при отображении без использования скриптов -->
<!ATTLIST NOSCRIPT
  %attrs;                              -- %coreattrs, %i18n, %events --
  >

Начальный тег: необходим, Конечный тег: необходим

Элемент NOSCRIPT даёт авторам возможность предоставить альтернативное содержимое, если скрипт не выполняется. Содержимое элемента NOSCRIPT  должно отображаться ПА, "понимающим" скрипты, только в следующих случаях:

ПА, не поддерживающие скрипты на стороне клиента, обязаны выводить содержимое этого элемента.

В следующем примере ПА, исполняющий SCRIPT, будет включать некоторые динамически создаваемые данные в документ. Если ПА не поддерживает скрипты, пользователь сможет запросить данные по гиперссылке.

<SCRIPT type="text/tcl">
 ...некоторый скрипт Tcl для вставки данных...
</SCRIPT>
<NOSCRIPT>
 <P>Перейдите на <A href="http://someplace.com/data">data.</A>
</NOSCRIPT>

18.3.2  Скрытие данных скрипта от ПА

Есть вероятность того, что ПА, не распознающие элемент SCRIPT, будут рассматривать его содержимое как текст. Некоторые машины скриптов, в том числе для языков JavaScript, VBScript и Tcl, разрешают включение операторов скрипта в комментарий SGML. ПА, не распознающие элемент SCRIPT, будут тогда игнорировать комментарий, в то время как более совершенные машины скриптов "поймут", что скрипт внутри комментария должен выполняться.

Другим решением проблемы является сохранение скриптов во внешнем документе и ссылка на него с помощью атрибута src.

Комментирование скриптов в JavaScript
Машина JavaScript допускает "<!--" как начало элемента SCRIPT  и игнорирует оставшиеся символы до конца строки. JavaScript интерпретирует "//" как начало комментария до конца текущей строки. Это необходимо, чтобы спрятать "-->" от разборщика JavaScript.

<SCRIPT type="text/javascript">
<!--  прячет содержимое скрипта от старых браузеров
  function square(i) {
    document.write("Вызов передан функции", i "<BR>")
    return i * i
  }
  document.write("Функция возвратила ",square(5),".")
// конец скрытия содержимого от старых браузеров  -->
</SCRIPT>

Комментирование скриптов в VBScript
В VBScript одиночная кавычка указывает, что оставшаяся часть строки должна рассматриваться как комментарий. Таким образом, она может использоваться для скрытия "-->" от VBScript, например:

   <SCRIPT type="text/vbscript">
     <!--
       Sub foo()
        ...
       End Sub
     ' -->
    </SCRIPT>

Комментирование скриптов в TCL
В Tcl символ"#" обозначает комментарий до конца строки:

<SCRIPT type="text/tcl">
<!--  прячет содержимое скрипта от старых браузеров
  proc square {i} {
    document write "Вызов передан функции $i.<BR>"
    return [expr $i * $i]
  }
  document write "Функция вернула [square 5]."
# конец скрытия содержимого от старых браузеров  -->
</SCRIPT>

Примечание. Некоторые браузеры закрывают комментарий при обнаружении первого символа ">", поэтому, для того, чтобы спрятать скрипт от таких браузеров, Вы можете поменять местами операнды в операторах сравнения и смещения (напр., использовать "y < x" вместо "x > y") или использовать зависимые от языка скриптов escape-последовательности для ">".