Статьи

Создать индикатор выполнения с помощью Javascript

Индикатор выполнения — один из последних компонентов, добавленных в превосходную библиотеку виджетов пользовательского интерфейса и помощников по взаимодействию, построенных на основе jQuery. Он был представлен в последней версии библиотеки, которая на момент написания статьи была 1.7.




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

Нам понадобится копия текущей версии пользовательского интерфейса jQuery, которую можно получить у разработчика загрузок по адресу http://jqueryui.com/download. Как только мы загрузим его, нам нужно будет распаковать его, чтобы сохранить существующую структуру каталогов. Мы должны создать новый каталог на нашем компьютере с именем jQuery UI, а затем внутри него создать еще одну новую папку с именем jqueryui1.7. Затем архив должен быть распакован в папку jqueryui1.7.

Архив будет содержать все необходимое для начала работы; сжатые и несжатые версии всех файлов библиотеки, некоторые файлы тем (по умолчанию используется метка с плавным названием) и даже самая последняя версия базовой библиотеки jQuery.

Панель Progress полагается на ряд файлов, чтобы функционировать; они перечислены ниже в том порядке, в котором они должны быть добавлены на нашу страницу:

  • ui.core.css
  • ui.theme.css
  • ui.progressbar.css
  • JQuery [CurrentVersion] .js
  • ui.core.js
  • ui.progressbar.js

Первые три файла являются частью обширного CSS-фреймворка и используются, чтобы придать индикатору выполнения отчетливый вид. Нам не нужно придерживаться этой темы в реальной реализации; У нас есть много вариантов настройки, включая огромное количество предварительно настроенных тем, доступных непосредственно из Themeroller, настраиваемую тему, которую мы можем создать самостоятельно с помощью Themeroller, или даже настраиваемую тему, которую мы создаем вручную, переопределяя правила, определенные в таблицах стилей по умолчанию. Мы не будем делать ничего из этого в этом руководстве, но мы можем использовать некоторые классы, предоставляемые фреймворком.

Этот виджет требует очень мало базовой разметки; все, что нам нужно, в дополнение к перечисленным выше ресурсам библиотеки, это простой элемент контейнера. В текстовом редакторе создайте следующую оболочку страницы с необходимыми ресурсами и элементом контейнера:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE HTML PUBLIC «-//W3C//DTD HTML 4.01//EN» «http://www.w3.org/TR/html4/strict.dtd»>
<html>
  <head>
    <link rel=»stylesheet» type=»text/css» href=»jqueryui1.7/development-bundle/themes/smoothness/ui.core.css»>
    <link rel=»stylesheet» type=»text/css» href=»jqueryui1.7/development-bundle/themes/smoothness/ui.theme.css»>
    <link rel=»stylesheet» type=»text/css» href=»jqueryui1.7/development-bundle/themes/smoothness/ui.progressbar.css»>
    <meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″>
    <title>jQuery UI Progress Bar</title>
  </head>
  <body>
    <div id=»container»></div>
    <script type=»text/javascript» src=»jqueryui1.7/development-bundle/jquery-1.3.2.js»></script>
    <script type=»text/javascript» src=»jqueryui1.7/development-bundle/ui/ui.core.js»></script>
    <script type=»text/javascript» src=»jqueryui1.7/development-bundle/ui/ui.progressbar.js»></script>
    <script type=»text/javascript»>
     
    </script>
  </body>
</html>

Сохраните это как progressBar.html в корневом каталоге jQuery UI. Мы помещаем таблицы стилей прямо в начало файла, а сценарии — в конец; Это связано с производительностью, поскольку страницы загружают контент быстрее, когда они не пытаются загрузить JavaScript одновременно. Это хорошо документированная практика производительности, которой лучше всего придерживаться. Мы оставили пустой тег сценария внизу страницы; давайте добавим немного кода там дальше:

1
2
3
4
5
$(function() {
 
  //call progress bar constructor
  $(«#container»).progressbar();
});

Чтобы инициализировать индикатор выполнения по умолчанию, все, что мы делаем, — это вызываем его метод конструктора progressbar элемента контейнера, в который должен отображаться виджет. Когда вы запустите эту страницу в своем браузере, вы должны увидеть, что индикатор выполнения создан и автоматически заполняет ширину своего контейнера, который в данном случае является телом страницы:

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

1
2
//call progress bar constructor
$(«#container»).progressbar({ value: 50 });

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

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

01
02
03
04
05
06
07
08
09
10
11
12
$(«#container»).mouseover(function() {
                 
  //display the current value
  $(«<p>»).attr(«id», «percentage»).text($(«#container»).progressbar(«option», «value») + «% complete»).appendTo(«body»);
});
                 
//set mouseout for progress bar
$(«#container»).mouseout(function() {
                   
  //hide value
  $(«#percentage»).remove();
});

Мы добавили две простые анонимные функции, которые запускаются при событиях mouseover и mouseout, запускаемых индикатором выполнения (обратите внимание, что это стандартные события DOM, а не настраиваемые события индикатора выполнения). Все, что мы делаем в первой функции, это создаем новый абзац с текущим значением индикатора выполнения в качестве своего innerText и добавляем его на страницу.

Значение извлекается с использованием метода option. Аргумент, передаваемый методу, является именем свойства, которое мы хотели бы получить. Вторая функция просто удаляет сообщение снова. Сообщение показано на следующем снимке экрана:

Свойство value или опция в настоящее время является единственным настраиваемым свойством индикатора выполнения; в этом примере мы устанавливаем его, когда виджет инициализируется, передавая его как свойство объекта конфигурации. Чтобы установить это свойство после инициализации виджета, мы будем использовать метод option. Чтобы использовать этот метод в режиме установки, нам нужно передать второй параметр, указывающий новое значение, например:

1
progressbar(«option», «value», 75)

Вы можете удивиться, почему я сказал «второй параметр», когда в приведенной выше строке кода явно есть три аргумента. Хотя мы используем метод option, мы не вызываем его напрямую. Вместо этого мы снова вызываем метод конструктора, но говорим, что хотим вызвать метод option. Виджет будет вызывать метод внутренне, передавая два параметра («значение» и 75), которые мы передаем конструктору после имени метода.

Индикатор выполнения отображает одно событие — событие изменения, которое предоставляет нам механизм, чтобы мы могли реагировать на изменения его значения. Это пользовательское событие, поэтому мы можем обнаруживать и реагировать на него двумя различными способами. Мы можем определить анонимную функцию как значение свойства change в объекте конфигурации, как мы это сделали со свойством value, или мы можем использовать метод привязки jQuery, чтобы указать анонимную функцию для выполнения. Тонкое различие между ними заключается в том, что код, указанный с помощью метода bind, будет выполнен первым.
API индикатора выполнения предоставляет пять методов, которые перечислены ниже:

  • уничтожить
  • отключить
  • включить
  • вариант
  • значение

Все эти методы используются точно так же, как и метод option, который мы рассмотрели; вызвав метод конструктора, указав имя метода и любые параметры, которые мы хотели бы передать. Большинство из них должны быть довольно понятными.

Этот пример до сих пор был очень базовым для тех из вас, кто раньше вообще не использовал jQuery UI. Давайте сделаем шаг вперед и соберем что-то похожее на то, что мы хотели бы сделать в правильной реализации. Этот пример также будет базовым, но он должен дать гораздо лучшее представление о том, как можно заставить виджет работать на нас. Наша готовая страница будет выглядеть примерно так:

Начните со следующей базовой страницы в новом файле в вашем текстовом редакторе:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!DOCTYPE HTML PUBLIC «-//W3C//DTD HTML 4.01//EN» «http://www.w3.org/TR/html4/strict.dtd»>
<html>
  <head>
    <link rel=»stylesheet» type=»text/css» href=»jqueryui1.7/development-bundle/themes/smoothness/ui.core.css»>
    <link rel=»stylesheet» type=»text/css» href=»jqueryui1.7/development-bundle/themes/smoothness/ui.theme.css»>
    <link rel=»stylesheet» type=»text/css» href=»jqueryui1.7/development-bundle/themes/smoothness/ui.progressbar.css»>
    <link rel=»stylesheet» type=»text/css» href=»regForm.css»>
    <meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″>
    <title>jQuery UI Progress Bar</title>
  </head>
  <body>
    <div class=»form-container ui-helper-clearfix ui-corner-all»>
      <h1>Registration Form</h1>
      <p>Progress:</p>
      <div id=»progress»></div><label id=»amount»>0%</label>
        <form action=»serverScript.php»>
          <div id=»panel1″ class=»form-panel»>
            <h2>Personal Details</h2>
              <fieldset class=»ui-corner-all»>
    <label>Name:</label><input type=»text»>
    <label>DOB:</label><input type=»text»>
    <label>Choose password:</label><input type=»password»>
    <label>Confirm password:</label><input type=»password»>
              </fieldset>
            </div>
            <div id=»panel2″ class=»form-panel ui-helper-hidden»>
              <h2>Contact Details</h2>
              <fieldset class=»ui-corner-all»>
                <label>Email:</label><input type=»text»>
    <label>Telephone:</label><input type=»text»>
    <label>Address:</label><textarea rows=»3″ cols=»25″></textarea>
              </fieldset>
            </div>
            <div id=»thanks» class=»form-panel ui-helper-hidden»>
              <h2>Registration Complete</h2>
              <fieldset class=»ui-corner-all»>
    <p>Thanks for registering!</p>
              </fieldset>
            </div>
            <button id=»next»>Next ></button><button id=»back» disabled=»disabled»>< Back</button>
          </form>
        </div>
        <script type=»text/javascript» src=»jqueryui1.7/development-bundle/jquery-1.3.2.js»></script>
        <script type=»text/javascript» src=»jqueryui1.7/development-bundle/ui/ui.core.js»></script>
        <script type=»text/javascript» src=»jqueryui1.7/development-bundle/ui/ui.progressbar.js»></script>
        <script type=»text/javascript»>

Сохраните его как regForm.html в папке пользовательского интерфейса jQuery. В верхней части страницы мы ссылаемся на CSS-фреймворк; это прежде всего для добавления необходимого стиля для индикатора выполнения, но мы также можем использовать некоторые из классов, которые он предоставляет для наших собственных элементов. Мы также добавляем пользовательскую таблицу стилей, которую скоро создадим.

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

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

Внешний контейнер имеет несколько имен классов; Первый заключается в том, что мы можем применить некоторые пользовательские стили к элементу, но вторые два предназначены для различных функций CSS-фреймворка. Класс ui-helper-clearfix используется для автоматической очистки плавающих элементов и является отличным способом уменьшить беспорядок в дополнительных и ненужных элементах div.

Класс ui-corner-all используется для придания элементу контейнера (а также самому индикатору выполнения, в котором они есть автоматически, и нашим элементам набора полей) скругленных углов, используя несколько собственных правил стиля. Они поддерживаются только браузерами на основе Gecko и WebKit, но по своей природе прогрессивное улучшение вполне приемлемо для их использования. Прогрессивное усовершенствование требует, чтобы мы могли предоставлять улучшенные стили для наших веб-страниц для браузеров, которые способны отображать их. Другие браузеры будут иметь прямоугольный контейнер.

Мы используем другой класс из CSS-фреймворка внутри формы; при первой загрузке страницы необходимо скрыть несколько панелей, поэтому мы можем использовать класс ui-helper-hidden, чтобы убедиться, что они настроены на отображение: ни одна, когда мы хотим их показать, все, что нам нужно сделать, это удалить это имя класса.

В нижней части тела (по соображениям производительности, кстати, это действительно работает!) Мы ссылаемся на требуемые ресурсы JavaScript из библиотеки. Самый последний элемент скрипта пуст и ожидает кода, который оживит форму и индикатор выполнения. Давайте добавим это следующее:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
$(function() {
 
  //call progress bar constructor
  $(«#progress»).progressbar({ change: function() {
 
    //update amount label when value changes
    $(«#amount»).text($(«#progress»).progressbar(«option», «value») + «%»);
  } });
 
  //set click handler for next button
  $(«#next»).click(function(e) {
 
  //stop form submission
  e.preventDefault();
 
  //look at each panel
  $(«.form-panel»).each(function() {
 
    //if it’s not the first panel enable the back button
    ($(this).attr(«id») != «panel1») ?
 
    //if the panel is visible fade it out
    ($(this).hasClass(«ui-helper-hidden»)) ?
 
      //add hidden class and show the next panel
      $(this).addClass(«ui-helper-hidden»).next().fadeIn(«fast», function() {
 
        //if it’s the last panel disable the next button
            ($(this).attr(«id») != «thanks») ?
                                 
        //remove hidden class from new panel
        $(this).removeClass(«ui-helper-hidden»);
                                 
        //update progress bar
        $(«#progress»).progressbar(«option», «value», $(«#progress»).progressbar(«option», «value») + 50);
      });
      });
    });
  });
 
});

Во внешнем сокращенном документе. У нас есть функция конструктора для индикатора выполнения; мы передаем конструктору буквальный объект конфигурации, содержащий единственное свойство. Это свойство изменения, которое позволяет нам предоставлять анонимную функцию для выполнения каждый раз, когда обнаруживается событие пользовательского изменения. Мы можем использовать это событие для обновления метки, которую мы собираемся разместить внутри индикатора выполнения.

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

Далее у нас есть обработчик щелчка для следующей кнопки>; при нажатии этой кнопки это приведет к изменению текущей «страницы» формы через серию анимаций и значению обновления индикатора выполнения. Нам также нужно сделать несколько других вещей. Поведение кнопки по умолчанию внутри формы заключается в отправке формы, чего мы не хотим делать на этом этапе, поэтому первое, что делает наш обработчик кликов, — это предотвращает отправку формы с помощью JavaScript-функции protectDefault (). Это вызывается для объекта события, который автоматически передается анонимной функции.

Затем мы просматриваем каждую из отдельных панелей в форме, чтобы определить текущую панель; первое, что мы делаем, это проверяем, что текущая панель не является первой панелью, и если это не так, мы активируем кнопку возврата, которая по умолчанию отключена. Одновременно будет отображаться только одна панель, поэтому мы находим панель, у которой нет скрытого класса ui-helper, и исчезаем. Мы указываем анонимную функцию обратного вызова, которая будет выполняться после завершения замирания.

В этой второй функции мы выбираем следующий элемент и показываем его; если следующим элементом является последняя панель с идентификатором благодарности, мы отключаем кнопку «следующий>». Хотя мы не беспокоимся о фактической отправке формы в этом примере, именно здесь мы можем отправить данные, собранные из формы, на сервер. Мы удалили класс ui-helper-hidden, поскольку панель теперь видна.

Наконец, мы снова используем метод option, на этот раз в режиме установки, чтобы установить новое значение индикатора выполнения. Новое значение, которое мы передаем методу в качестве второго параметра, представляет собой просто текущее значение плюс 50, так как есть только 2 части формы. Эта последняя часть затем вызовет функцию, которая обновляет метку.

Далее нам нужно добавить очень похожий обработчик кликов для

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//set click handler for back button
$(«#back»).click(function(e) {
                   
  //stop form submission
  e.preventDefault();
                     
  //look at each panel
  $(«.form-panel»).each(function() {
                                         
    //if it’s not the last panel enable the next button
    ($(this).attr(«id») != «thanks») ?
                       
    //if the panel is visible fade it out
    ($(this).hasClass(«ui-helper-hidden»)) ?
                           
      //add hidden class and show the next panel
      $(this).addClass(«ui-helper-hidden»).prev().fadeIn(«fast», function() {
                             
        //if it’s the first panel disable the back button
          ($(this).attr(«id») != «panel1») ?
                                         
      //remove hidden class from new panel
      $(this).removeClass(«ui-helper-hidden»);
                                 
      //update progress bar
      $(«#progress»).progressbar(«option», «value», $(«#progress»).progressbar(«option», «value») — 50);
      });
    });
  });
});

Теперь это весь код, который нам понадобится. Все, что нам нужно сделать, — это добавить базовый CSS, чтобы выложить пример; в новом файле в вашем текстовом редакторе добавьте следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
h1, h2 { font-family:Georgia;
h2 { font-size:100%;
.form-container {
  width:400px;
  font-size:80%;
  border:3px solid #abadac;
}
.form-panel { width:400px;
.form-panel fieldset {
  width:397px;
  border:1px solid #abadac;
}
.form-panel label {
  width:146px;
  padding-top:2px;
}
.form-panel input, .form-panel textarea {
  float:left;
}
.form-container button { float:right;
p {
  margin:0;
  font-weight:bold;
}
#amount {
  position:absolute;
  font-weight:bold;
}
#thanks { text-align:center;
#thanks p {
  margin-top:48px;
}

Сохраните его как regForm.css в той же папке, что и файл HTML. Теперь у нас должна быть рабочая страница с индикатором выполнения. Когда мы запустим страницу, мы обнаружим, что можем перемещаться по каждой панели формы, и индикатор выполнения будет обновляться соответствующим образом:

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

Мы рассмотрели свойство и событие, предоставляемые его API, и обратились к одному из методов, которые мы можем вызвать, чтобы индикатор выполнения что-то делал. Пример, который мы закончили, должен прекрасно работать во всех основных браузерах, хотя в хорошем старом IE он выглядит немного грязно (что было бы очень легко исправить, если бы мы были склонны сделать это).