Компоненты HTML5: Специальные (ad-hoc) компоненты. Часть 2

Поддержка слушателей события (event listener), анимация элементов с помощью CSS3 и добавление контента в DOM-дерево

В этом цикле статей специалист по HTML5 Дэвид Джири демонстрирует реализацию HTML5-компонентов. В данной статье вы закончите реализацию специального (ad-hoc) компонента типа ползунок, которая была начата в первой статье цикла под названием Компоненты HTML5: специальные (ad-hoc) компоненты. Часть 1. В частности, вы узнаете, как включить слушателей события (event listener), как анимировать кнопку ползунка и как добавить ползунок в существующее DOM-дерево.

Дэвид Джири, президент, Clarity Training, Inc.

David GearyАвтор, лектор и консультант Дэвид Джири является президентом компании Clarity Training, Inc., Он обучает разработчиков создавать Web-приложения с использованием JSF и Google Web Toolkit (GWT). Он участвовал в экспертных группах JSTL 1.0 и JSF 1.0/2.0, был соавтором сертификационного экзамена Web Developer Certification Exam компании Sun, а также принимал участие в проектах с открытым кодом, в том числе Apache Struts и Apache Shale. Книга Дэвида Graphic Java Swing стала одной из самых продаваемых книг о Java, а Core JSF (в соавторстве с Кэем Хорстманом) - одна из самых продаваемых книг о JSF. Дэвид регулярно выступает на конференциях и встречах пользовательских групп. Он является регулярным участником конференций NFJS с 2003 года, проводил курсы в университете Java и дважды удостаивался звания JavaOne rock star.



09.09.2013

HTML5 – это изощренная платформа веб-программирования, обладающая такими мощными возможностями, как элемент canvas, CSS3 и модель событий. HTML5 предоставляет всю базовую функциональность, которая может потребоваться разработчику для реализации собственных компонентов.

Об этом цикле статей

Модель стандартных компонентов пользовательского интерфейса для платформы HTML5 все еще находится в стадии развития. В этом цикле статей Дэвид Джири, высококвалифицированный специалист по HTML5, показывает, как создавать собственные специальные (ad-hoc) HTML5-компоненты с помощью существующей технологии — и как задействовать спецификации, которые пока еще находятся в процессе определения подлинной системы HTML5-компонентов.

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

  • Применение альтернативных органов управления ползунком
  • Реализации поддержки для регистрации и инициализации слушателей изменения
  • Анимирование HTML-элементов с помощью CSS3-переходов
  • Введение контента в DOM-дерево
  • Кастомизация специальных (ad-hoc) компонентов с помощью атрибутов элемента

Альтернативные органы управления ползунком

На рис. 1 показана разновидность простого приложения из первой статьи данного цикла, в котором используется компонент типа ползунок. В данной разновидности для пошагового увеличения и уменьшения значения ползунка вместо клавиш используются ссылки. Для этих органов управления можно использовать любой элемент, который генерирует события типа mouse-click (нажатие мышью).

Рисунок 1. Использование ссылок вместо кнопок
Screenshot of the slider with links, instead of buttons

Кроме того, пользователь может изменить значение ползунка посредством нажатия на его направляющую или посредством перемещения его кнопки. В разделе Перемещение кнопки первой статьи данного цикла объясняется, каким образом ползунок обеспечивает перемещение своей кнопки. В разделе этой статьи, который называется Анимация кнопки ползунка, вы увидите, как ползунок подстраивает положение кнопки с помощью CSS3-перехода, когда пользователь нажимает на направляющую ползунка.

В листинге 1 приведен HTML-код для приложения, показанного на рис.1.

Листинг 1. HTML-код для версии приложения с ползунком, в котором вместо клавиш используются ссылки
<html>
   <head>
      ...
   <head>

   <body>
      <div id='slider-component'>
         <div id='controls'>
            <a href='#' class='slider-control' id='decrement'>-</a>
            <a href='#' class='slider-control' id='increment'>+</a>

            <div id='slider'>  <!-- slider goes here -->  </div>
         </div>

         <div id='readout'>0</div>
      </div>
   </body>

   <script type="text/javascript" src="lib/slider.js"></script>
   <script type="text/javascript" src="sliderExample.js"></script>
</html>

HTML-код в листинге 1 достаточно прост. Две ссылки и ползунок находятся в DIV-элементе controls, который, в свою очередь, находится в DIV-элементе slider-component. Когда пользователь нажимает на какую-либо ссылку, JavaScript-код приложения обрабатывает это событие нажатия (см. листинг 2).

Листинг 2. События нажатия на ссылку
var slider = new COREHTML5.Slider('black', 'cornflowerblue', 0),
...

document.getElementById('decrement').onclick = function (e) {
   slider.knobPercent -= 0.1;
   slider.redraw(); 
   updateReadout();
}

document.getElementById('increment').onclick = function (e) {
   slider.knobPercent += 0.1; 
   slider.redraw(); 
   updateReadout();
}

Обработчики событий в листинге 2 осуществляют пошаговое увеличение и уменьшение значения ползунка (хранящегося в атрибуте knobPercent ползунка), перерисовывают ползунок и обновляют элемент readout.

Если значение ползунка изменяется, приложение обновляет элемент readout с помощью слушателя изменения, который связан с этим ползунком (см. листинг 3).

Листинг 3. События изменения ползунка
var readoutElement = document.getElementById('readout');

function updateReadout() {
   if (readoutElement)
      readoutElement.innerHTML = slider.knobPercent.toFixed(2);
}

slider.addChangeListener(updateReadout);

Обратите внимание, что индикаторный элемент является опциональным; если он отсутствует, то метод updateReadout() не выполняет никаких действий.

В следующем разделе показано, как в ползунке реализована поддержка слушателей изменения.

Приложение, показанное на рис. 1 добавляет ползунок к DOM-элементу с помощью метода appendTo() ползунка.

slider.appendTo('slider'); // Append the slider to the DOM element with an ID of slider
slider.draw();

Реализация этого метода статья описывается в разделе данной статьи под названием: Добавление ползунка к DOM-элементу.


Поддержка событий изменения ползунка

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

Листинг 4. Добавление слушателей изменения и инициирование событий
COREHTML5.Slider = function {
   ...
   this.changeEventListeners = [];
   ...
};

COREHTML5.Slider.prototype = {
   ...

   addChangeListener: function (listenerFunction) {
      this.changeEventListeners.push(listenerFunction);
   },

   fireChangeEvent: function(e) {
      for (var i=0; i < this.changeEventListeners.length; ++i) {
         this.changeEventListeners[i](e);
      }
   },
   ...
};

Каждый ползунок содержит массив функций. Если значение ползунка изменяется, то метод fireChangeEvent() выполняет итеративное прохождение по этому массиву с поочередным вызовом каждой функции. В листинге 5 показано, как ползунок осуществляет вызов своего метода fireChangeEvent().

Листинг 5. Инициирование событий изменения
COREHTML5.Slider.prototype = {
   addMouseListeners: function () {
      this.knobCanvas.addEventListener('mousemove', function(e) {
         var mouse = null,
             percent = null;

         e.preventDefault();

         if (slider.draggingKnob) {
            slider.deactivateKnobAnimation();
            
            mouse = slider.windowToCanvas(e.clientX, e.clientY);
            percent = slider.knobPositionToPercent(mouse.x);

            if (percent >= 0 && percent <= 1.0) {
               slider.fireChangeEvent(e);
               slider.erase();
               slider.draw(percent);
            }
         }
      }, false);

   },

По мере того, как пользователь перемещает кнопку ползунка, слушатель события mouse-move (движение мыши), присоединенный к элементу canvas кнопки, корректирует значение ползунка, инициирует событие изменения, а затем стирает и перерисовывает ползунок. Кроме того, этот слушатель события деактивирует анимацию кнопки ползунка, пока пользователь перемещает кнопку. Это гарантирует отсутствие отрицательного влияния со стороны анимации на перемещение кнопки пользователем.

Теперь, когда вы увидели обстоятельства, при которых ползунок деактивирует анимацию кнопки, посмотрим, как работает эта анимация.


Анимация кнопки ползунка

На рис. 2 показано, как ползунок анимирует свою кнопку. Верхний снимок экрана на рис. 2 был сделан непосредственно перед тем, как пользователь нажал на направляющую ползунка. Остальные два снимка экрана показывают последовательное перемещение кнопки к месту расположения курсора (рис. 2 представляет собой "плохое приближение" реальной анимации; для получения полного эффекта загрузите программный код и запустите его на исполнение).

Рисунок 2. Анимация ползунка
Series of three screenshots that demonstrate the slider animation

Как указывалось в разделе Создание и инициализация ползунка первой статьи данного цикла, ползунок рисует свою направляющую и свою кнопку в разных элементах canvas. Было бы значительно проще, если бы ползунок рисовал направляющую и кнопку в одном и том же элементе canvas; однако CSS3-переходы работают с элементами только индивидуально, поэтому кнопка должна быть в отдельном элементе canvas.

В предыдущем разделе было показано, что ползунок вызывает свой метод deactivateKnobAnimation(), чтобы деактивировать анимацию кнопки, пока пользователь перемещает ее. В листинге 6 этот метод показан вместе с противоположным ему методом activateKnobAnimation().

Листинг 6. Активирование и деактивирование анимации кнопки
COREHTML5.Slider.prototype = {
   ...

   activateKnobAnimation: function () {
      var transitionString = "margin-left " +
          (this.knobAnimationDuration / 1000).toFixed(1) + "s";

      this.knobCanvas.style.webkitTransition = transitionString;
      this.knobCanvas.style.MozTransition = transitionString;
      this.knobCanvas.style.OTransition = transitionString;
      this.knobCanvas.style.transition = transitionString;
   },

   deactivateKnobAnimation: function () {
      slider.knobCanvas.style.webkitTransition = "margin-left 0s";
      slider.knobCanvas.style.MozTransition = "margin-left 0s";
      slider.knobCanvas.style.OTransition = "margin-left 0s";
      slider.knobCanvas.style.transition = "margin-left 0s";
   },
   ...
};

Различия между браузерами применительно к именованию

Как и многие HTML5-функции, CSS3-переходы сначала были реализованы как зависимая от браузера функциональность, а затем стандартизированы организацией W3C. Чтобы гарантировать, что переходы работают во все версиях браузеров, которые поддерживают их, такой код, как в листинге 6, должен допускать все "браузерозависимые" варианты имен CSS-атрибутов.

Метод activateKnobAnimation(), показанный в листинге 6, программным образом добавляет CSS3-переход к CSS-атрибуту margin-left элемента canvas для кнопки. Это позволяет учитывать вариации имени самого атрибута перехода в разных браузерах. В результате этого перехода браузер плавно анимирует элемент canvas для кнопки между разными ее положениями при изменении атрибута margin-left. Продолжительность этой анимации задается в миллисекундах посредством атрибута knobAnimationDuration ползунка.

Метод deactivateKnobAnimation() изменяет продолжительность CSS3-перехода до нуля секунд, что фактически отключает анимацию.

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

Листинг 7. Нажатие на направляющую ползунка
COREHTML5.Slider.prototype = {
   ...
   addMouseListeners: function () {
      ...
   
      this.railCanvas.onmousedown = function(e) {
         var mouse = slider.windowToCanvas(e.clientX, e.clientY),
             startPercent,
             endPercent;

         e.preventDefault();

         startPercent = slider.knobPercent;
         endPercent = slider.knobPositionToPercent(mouse.x);

         slider.animatingKnob = true;

         slider.moveKnob(mouse.x);
         slider.trackKnobAnimation(startPercent, endPercent);
      };
   },
   ...
};

Метод ползунка moveKnob(), показанный в листинге 8, перемещает кнопку посредством задания CSS-атрибута margin-left элемента canvas для кнопки. Задание этого атрибута инициирует CSS3-анимацию кнопки, при условии, что эта анимация кнопки является активной.

Листинг 8. Перемещение кнопки ползунка
COREHTML5.Slider.prototype = {
   ...

   moveKnob: function (position) {
      this.knobCanvas.style.marginLeft = position - this.knobCanvas.width/2 + "px";
   },
   ...
};

CSS-имена атрибутов на языке JavaScript

Многие CSS3-имена атрибутов содержат дефисы, использование которых не допускается в JavaScript-именах атрибутов. Это прискорбное несоответствие вынуждает нас преобразовывать CSS3-имена атрибутов, содержащие дефисы, в JavaScript-имена в стиле CamelCase, в результате чего margin-left превращается в marginLeft, а padding-top превращается в paddingTop.

Помимо перемещения кнопки ползунка, обработчик события mouse-down элемента canvas для направляющей вызывает метод trackKnobAnimation() ползунка (см. листинг 7). Этот метод, который рассматривается в следующем разделе, сохраняет синхронность значения ползунка с кнопкой на всем протяжении соответствующей анимации CSS3-перехода.


Отслеживание CSS3-переходов

Конец CSS3-перехода можно обнаружить с помощью слушателя события. Компонент типа ползунок делает именно это посредством вызова метода addKnobTransitionListener() ползунка из конструктора ползунка (см. листинг 9).

Листинг 9. Добавление слушателей перехода кнопки
COREHTML5.Slider = function(strokeStyle, fillStyle, knobPercent, knobAnimationDuration) {
   ...
   this.createDOMTree();
   this.addMouseListeners();
   this.addKnobTransitionListener();
};

Метод addKnobTransitionListener() ползунка (см. листинг 10), добавляет слушателя перехода к элементу canvas для кнопки, что также позволяет учесть различия между браузерами применительно к именованию.

Листинг 10. Слушатели CSS-перехода
COREHTML5.Slider.prototype = {
   ...

   addKnobTransitionListener: function () {
      var BROWSER_PREFIXES = [ 'webkit', 'o' ];

      for (var i=0; i < BROWSER_PREFIXES.length; ++i) {
         this.knobCanvas.addEventListener(
            BROWSER_PREFIXES[0] + "TransitionEnd", // Everything but Mozilla

            function (e) {
               slider.animatingKnob = false;
            }
         );
      }

      this.knobCanvas.addEventListener("transitionend", // Mozilla
         function (e) {
            slider.animatingKnob = false;
         }
      );
   },      
   ...

Когда анимация перехода кнопки завершается, браузер вызывает слушателя перехода, показанного в листинге 10. Этот слушатель просто присваивает атрибуту animatingKnob ползунка значение false, в результате чего ползунок прекращать отслеживать анимацию кнопки. Это отслеживание реализовано с помощью метода trackKnobAnimation() ползунка (см. листинг 11).

Листинг 11. Отслеживание анимации кнопки
trackKnobAnimation: function (startPercent, endPercent) {
      var count = 0,
          KNOB_ANIMATION_FRAME_RATE = 60,  // fps
          iterations = slider.knobAnimationDuration/1000 * KNOB_ANIMATION_FRAME_RATE + 1,
          interval;

      interval = setInterval( function (e) {
         if (slider.animatingKnob) {
            slider.knobPercent = startPercent +
                                 ((endPercent - startPercent) / iterations * count++);

            slider.knobPercent = slider.knobPercent > 1.0 ? 1.0 : slider.knobPercent;
            slider.knobPercent = slider.knobPercent < 0 ? 0 : slider.knobPercent;

            slider.fireChangeEvent(e);
         }
         else { // Done animating knob 
            clearInterval(interval);
            count = 0;
         }
      }, slider.knobAnimationDuration / iterations);
   },
   ...   
};

Конец анимации CSS3-перехода можно обнаружить с помощью слушателя события (см. листинг 10), однако при таком подходе невозможно выявить промежуточные шаги этой анимации, а это необходимо ползунку для инициирования событий изменения при анимации кнопки.

Сравнение CSS3-переходов с CSS3-анимацией

Чтобы анимировать кнопку ползунка, я использовал CSS3-переходы, которые относительно просты в применении, однако не поддерживают уведомление о событии в процессе соответствующей анимации перехода. Я мог бы использовать CSS3-анимацию, которая труднее в применении, однако реально поддерживает уведомления о событии в ходе анимации.

Поскольку не представляется возможным обнаруживать шаги анимации CSS3-перехода, метод trackKnobAnimation() ползунка использует метод setInterval() для аппроксимирования шагов анимации и для инициирования событий изменения на каждом шаг.

Итак, мы рассмотрели анимирование кнопки ползунка с помощью CSS3-переходов, а теперь рассмотрим добавление ползунка к существующему DOM-элементу.


Добавление ползунка к DOM-элементу

В разделе Рисование ползунка в первой статье данного цикла рассматривалась реализация компонента типа ползунок без ссылки на CSS3-переходы. Данная реализация создает DOM-дерево для ползунка (рис. 3).

Рисунок 3. DOM-дерево ползунка
Illustration of the slider's DOM tree, consisting of two canvas elements and a DIV

Конструктор ползунка создает элемент DIV и два элемента canvas— один элемент для направляющей ползунка и один элемент для его кнопки — и добавляет эти элементы canvas к элементу DIV. Когда приложение, показанное в листинге 1, впоследствии добавляет ползунок к существующему DOM-элементу, этот ползунок добавляет охватывающий его DOM-элемент к существующему элементу (см. рис. 4).

Рисунок 4. Формирование DOM-дерева ползунка
Diagram illustrating the merging of the slider's DOM tree

Конструктор ползунка вызывает метод createDOMTree() ползунка (см. листинг 12).

Листинг 12. Создание DOM-дерева ползунка
COREHTML5.Slider = function(strokeStyle, fillStyle, knobPercent, knobAnimationDuration) {
   ...
   this.createDOMTree();
   this.addMouseListeners();
   this.addKnobTransitionListener();
};

В листинге 13 показан метод createDOMTree() ползунка.

Листинг 13. Метод createDOMTree()
COREHTML5.Slider.prototype = {
   ...

   createDOMTree: function () {
      var self = this;

      this.domElement = document.createElement('div');

      this.domElement.appendChild(this.knobCanvas);
      this.domElement.appendChild(this.railCanvas);
   },
   ...
};

К тому моменту, когда ползунок осуществляет вызов метода createDOMTree(), он уже создал элементы canvas для кнопки и для направляющей. Метод createDOMTree() создает охватывающий элемент DIV ползунка и добавляет к этому элементу существующие элементы canvas для кнопки и для направляющей.

После того, как ползунок создал свое DOM-дерево, все готово к добавлению ползунка к существующим DOM-элементам с помощью метода appendTo() ползунка (см. листинг 14).

Листинг 14. Метод appendTo(): присоединение ползунка к существующему DOM-элементу
COREHTML5.Slider.prototype = {
   ...

   appendTo: function (elementName) {
      if (typeof element === 'string') {
         document.getElementById(element).
            appendChild(this.domElement);
      }
      else {
         element.appendChild(this.domElement);
      }

      this.resize();
   },
   ...
};

Настройка размеров CSS и элемента canvas

TПоследние четыре строки в методе setKnobCanvasSize() ползунка в листинге 15 иллюстрируют весьма важный момент: Не следует задавать CSS-атрибутов "ширина" и "высота" для элемента canvas без одновременного присвоения атрибутам "ширина" и "высота" самого элемента canvas таких же значений. Это обусловлено тем обстоятельство, что CSS-атрибуты применяются только к элементу canvas, тогда как атрибуты "ширина" и "высота" элемента canvas применяются и к самому элементу canvas, и к его пространству для рисования. Если вы зададите только CSS-атрибуты, то будет иметь место несоответствие между размерами элемента canvas и размерами его пространства для рисования, что вынудит браузер масштабировать пространство для рисования элемента canvas в соответствии с размерами этого элемента. Как показано в листинге 15, метод resize() ползунка задает размеры элемента canvas для направляющей ползунка и размеры элемента canvas для кнопки, в дополнение к размерам самого ползунка.

В метод appendTo() можно передать или строку, представляющую идентификатор (ID) соответствующего элемента, или сам этот элемент; в любом случае данный метод добавляет охватывающий DOM-элемента ползунка к указанному элементу, а затем изменяет размеры элемента canvas и размеры охватывающего DOM-элемента ползунка. Это изменение размеров имеет место в методе resize() и в методах, которые он вызывает; все эти методы показаны в листинге 15.

Листинг 15. Изменение размеров ползунка в соответствии с его охватывающим элементом
COREHTML5.Slider.prototype = {
   ...

   setRailCanvasSize: function () {
      var domElementParent = this.domElement.parentNode;

      this.railCanvas.width = domElementParent.offsetWidth;
      this.railCanvas.height = domElementParent.offsetHeight;
   },

   
   setKnobCanvasSize: function () {
      this.knobRadius = this.railCanvas.height/2 -
                        this.railContext.lineWidth;

      this.knobCanvas.style.width = this.knobRadius * 2 + "px";
      this.knobCanvas.style.height = this.knobRadius * 2 + "px";
      this.knobCanvas.width = this.knobRadius*2;
      this.knobCanvas.height = this.knobRadius*2;
   },

   setSliderSize: function() {
      this.cornerRadius = (this.railCanvas.height/2 -
                           2*this.VERTICAL_MARGIN)/2;

      this.top = this.HORIZONTAL_MARGIN;
      this.left = this.VERTICAL_MARGIN;

      this.right = this.left +
                   this.railCanvas.width - 2*this.HORIZONTAL_MARGIN;

      this.bottom = this.top + 
                   this.railCanvas.height - 2*this.VERTICAL_MARGIN;
   },

   resize: function() {
      this.setRailCanvasSize();
      this.setKnobCanvasSize();
      this.setSliderSize();
   },
   ...
};

Кастомизация компонентов

По состоянию на данный момент времени компонент типа ползунок является весьма полезным. Однако независимо от того, сколько пользы обеспечивает какой-либо компонент, люди наверняка захотят кастомизировать его тем или иным способом. Эта кастомизация может быть весьма простой, например, ограничиваться изменением цвета, как показано на рис.5, или весьма значительной, например, обеспечивать поддержку вертикальных ползунков (не рассматриваемых в данной статье).

Рисунок 5. Ползунок цвета морской волны
Screenshot of the slider in a new color: aqua

В листинге 16 показано добавление двух атрибутов к DIV-элементу slider-component для цветов ползунка stroke и fill.

Листинг 16. Задание атрибутов элемента
<!DOCTYPE html>
<html>
   <head>
      ...
   </head>
   
   <body>
      <div id='title'>A custom slider</div>

      <p>
         <div id='slider-component' stroke='blue' fill='aqua'>
            ...
         </div>
      </p>
   </body>

   <script type="text/javascript" src="lib/slider.js"></script>
   <script type="text/javascript" src="sliderExample.js"></script>
</html>

Как показано в листинге 17, JavaScript-код приложения использует метод getAttribute() с целью получения значений для атрибутов stroke и fill.

Листинг 17. Обращение к атрибутам элемента
var sliderElement = document.getElementById('slider-component'),
    slider = new COREHTML5.Slider(sliderElement.getAttribute('stroke'),
                                  sliderElement.getAttribute('fill'),
                                  0),
    ...

Впоследствии эти значения используются при создании ползунка.


В следующей статье этого цикла

В следующей статье данного цикла рассматривается спецификация Introduction to Web Components от организации W3C и демонстрируется реализация компонента типа ползунок с использованием таких механизмов, как Shadow DOM, специальные элементы и шаблоны. До встречи в следующей статье.


Загрузка

ОписаниеИмяРазмер
Учебный программный кодwa-html5-components-2-code.zip6 КБ

Ресурсы

  • Оригинал статьи: HTML5 components: Ad-hoc components, Part 2.
  • Core HTML5 Canvas: Книга Дэвида Гири, предлагающая обширный обзор API Canvas и сведения по разработке игр. Посетите также сопутствующий веб-сайт и блог.
  • Mind-blowing apps with HTML5 Canvas(Умопомрачительные приложения с применением HTML5 Canvas): презентация Дэвида Гири на конференции Strange Loop 2011.
  • Основы HTML5: Познакомьтесь с основами HTML5 на этом "пути к знаниям" developerWorks.
  • Приложение Slider: Онлайновая версия приложения с ползунком, описываемого в данной статье (вариант с клавишами).
  • HTML5 2D game development: (Разработка 2D-игр на HTML5); Цикл статей Дэвида Гири, посвященный созданию игры на платформе HTML5.
  • Раздел для веб-разработчиков на ресурсе developerWorks: Статьи по различным веб-решениям. Материалы по тематике "Веб-разработка" в разделе Technical library (техническая библиотека): обширный ассортимент технических статей, рекомендаций, руководств, учебных пособий и стандартов, а также материалов серии IBM Redbook.

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Web-архитектура
ArticleID=943814
ArticleTitle=Компоненты HTML5: Специальные (ad-hoc) компоненты. Часть 2
publish-date=09092013