HTML5 组件: 特殊组件,第 1 部分

理解 HTML5 组件模型并开始实现特殊组件

作为一个简短的 系列文章 的开篇文章,David Geary 将在本文中讨论 HTML5 组件。在本文中,您将获得 HTML5 组件技术的概述,并将从头学习如何实现复杂的滑块组件。

David Geary, 作者和演讲家, Clarity Training, Inc.

David GearyDavid Geary 是 Core HTML5 Canvas 的作者,也是 HTML5 Denver User's Group 的合著者和其他 8 本 Java 图书的作者,其中包括畅销书 Swing 和 JavaServer Faces。David 经常在各大会议发表演讲,包括 JavaOne、Devoxx、Strange Loop、NDC 和 OSCON,他曾三次当选为 JavaOne 之星。他还为 developerWorks 撰写了 JSF 2 fuGWT fu 系列文章。您可以通过 @davidgeary 在 Twitter 上关注他。



2013 年 4 月 16 日

关于本系列

面向 HTML5 的标准 UI 组件模型仍在不断进化。在本 系列文章 中,HTML5 专家 David Geary 将向您展示如何使用现有技术创建属于自己 HTML5 组件,以及如何利用正在开发的规范定义一个真实的 HTML5 组件系统。

组件模型对任何编程平台来说都是一个重要组成部分,因为它们提供一组标准 UI 元素和基础架构来构建更多的东西。

HTML5 是一个较新的技术,拥有一组更为年轻的规范,旨在标准化 HTML5 组件的实现以及与其他组件的集成。HTML5 组件模型目前是通过三个规范定义的:

  • “Introduction to Web Components”
  • “Shadow DOM”
  • “HTML Templates”

这三个规范中的功能包括:封装组件 DOM 树(Shadow DOM),为组件网页设计者在其 HTML 页面中使用的组件创建自定义标签(自定义 HTML 元素),以声明的方式指定 Shadow DOM 和插入点(HTML Templates)。(参阅 “HTML5 组件规范” 侧边栏,获取有关的更多详细信息。)

HTML5 组件规范

“Introduction to Web Components” 是对 Web 组的高度概述,主要是为了生成其他规范,比如 “Shadow DOM” 和 “HTML Templates” 规范。

“Shadow DOM” 规范是一个万维网联盟(W3C)工作草案,也就是说,可以认为它是 HTML5 的一个组成部分。Shadow DOM 为普通开发人员提供特殊功能来封装实现的组件,

就像浏览器供应商长期以来在其视频元素中封装低级元素和范围输入 (range input) 一样。

“HTML Templates” 规范目前还不是一个工作草案,但据说广受开发人员的青睐,极有可能成为一个工作草案。Templates 支持以声明的方式指定带有插入点的 Shadow DOM,可以将 CSS 选择器选中的元素插入其中。

参阅 参考资料,获取每个规范的链接。

但是,要实现组件,首先需要一个完全不同的技能组合,包括能够创建具有吸引力的图形、对 HTML 元素进行分层来支持插入交互,以及支持事件监听。本 系列文章 涵盖了这些 HTML5 组件开发的所有方面:

  • 特殊组件
  • Shadow DOM、模板和自定义元素
  • Mozilla 的 X-Tag

本文和本系列的下一期都将向您介绍如何从零开始实现特殊的 HTML5 组件,不需要任何新规范支持。稍后几期将介绍相关规范,并介绍如何将 Shadow DOM、自定义元素以及模板合并到您的 HTML5 组件构建系统中。

更具体地说,在本文中,您将学习如何:

  • 实现特殊的 HTML5 组件
  • 使用 画布 元素绘制具有吸引力的图形
  • 对画布元素进行分层来实现特殊效果
  • 实现 HTML 元素的实时拖拽

构建其中一个 HTML5 组件

显示了一个图像处理组件,该组件由其他几个较为常见的组件构成:图标、工具栏、滑块和一个图像显示区。

一个图像处理组件
图像查看器组件的两个截图:上面的截图显示了大小调整滑块的使用,下面的截图显示了使用旋转滑块旋转后的图像。

工具栏上的三个图标(resize、rotate 和 brightness)与滑块相关。当您单击其中一个图标时,图像处理组件会在工具栏的下方显示一个滑块和一组相关按钮。 中上面的截图显示了调整滑块大小的使用;下面的截图显示了使用旋转滑块旋转后的图像。


滑块组件

滑块由一个滑轨和一个旋钮构成;可以通过在滑轨上移动旋钮来改变滑块的值。旋钮的位置决定滑块的值(反之亦然,如果以编程方式设置值并重绘滑块)。该值(介于 0.0 和 1.0 之间)表示旋钮的左侧在滑轨上的百分比;例如,当旋钮的左侧位于滑轨的四分之三处时,滑块的值为 0.75。

是一个说明如何使用滑块的简单应用程序。除了滑块之外,该应用程序还包括两个按钮,单击这两个按钮可以将滑块旋钮向右(+)或向左(—)逐步移动。该应用程序也在滑块下方提供了一个示值读数,显示滑块当前值。参阅 参考资料,获取运行该应用程序的链接;还可以从 下载 部分下载源代码。

一个滑块
滑块的截图

用户可以采用三种方式移动滑块旋钮:

HTML 5 专题

HTML5 代表了 Web 业务和云业务在实现方式上的里程碑式改变。 本 HTML 5专题将顺应潮流为您介绍 一些和 HTML5 新特性相关的内容,及其炫酷的效果。

  • 单击一次按钮滑块值增加(+)或减少(-)10%。
  • 拖拽旋钮。
  • 在滑轨上旋钮之外的任何地方单击,将旋钮移动到单击位置。

如果滑块的值是以程序方式设置的,当您激活加号(+)或减号(-)按钮或者支持 在滑轨上旋钮之外的任何位置单击时,通常可以这样做,滑块的运动是通过一个带有减缓功能的 CSS 转换激活的,该功能在旋钮接近最终目的地时减缓旋钮速度。滑块组件使用 JavaScript 设置转换属性。

要使用滑块,需要先实例化滑块,然后将其附加到现有 DOM 元素中,如 所示。

创建一个滑块
var slider = new COREHTML5.Slider( // All of the following arguments are optional
   'navy',           // Stroke color
   'cornflowerblue', // Fill color
   0.5,              // Initial slider value
   500);             // Knob animation duration in milliseconds
...

slider.appendTo('someDiv');  // Appends the slider to a DOM element with the ID someDiv

滑块的 appendTo() 方法调整了滑块的大小,以便通过伸缩来适应附加滑块的元素。

为什么不使用范围输入?

尽管 HTML 提供了范围输入,但实现滑块组件主要有两个原因。首先,您可能想确保在所有浏览器中呈现相同的外观, 中显示的图像处理组件就属于这种情况。其次,一些浏览器(比如 Firefox)坚持只使用纯文本输入来展示范围。在很多情况下,这样做是不够的。

滑块的特点是:

  • 使用一个 appendTo() 方法附加到 DOM 元素中
  • 自动调整大小来适应附加滑块的 DOM 元素
  • 使用 addChangeListener() 方法注册变更事件监听器
  • 当滑块的旋钮移动时,触发变更事件来更改监听程序
  • 当用户在滑轨上单击时,使用一个 CSS 转换激活旋钮

滑块是 COREHTML5.Slider 的实例,可避免域名空间冲突。想象一下,如果有人使用一个更明显的名称(例如 Slider)实现一个滑块(这并不是没有可能),那么有可能会使用完全相同的名称来代替所有的全局对象。但是,不太可能有人会使用自己的 COREHTML5.Slider

COREHTML5.Slider 构造函数参数都是可选的;所有这些值都有合理的默认值。 列出了关键 COREHTML5.Slider 方法。

关键滑块方法
方法描述
appendTo(elementId)将滑块的 DOM 元素附加到某个元素,该元素的 ID 与传递给该方法的值相匹配。
addChangeListener(listenerFunction)向滑块添加一个变更监听器函数。当滑块的旋钮位置发生改变时,滑块将会触发一个事件来监听所有变更监听器。
draw()绘制滑块的滑轨和旋钮。
erase()擦除滑块。
redraw()擦除然后重绘滑块。

仅列出了开发人员用于操作滑块的外部方法。COREHTML5.Slider 对象也有很多内部使用的方法,比如 initializeStrokeAndFillStyles()createKnobCanvas()

开发人员通过滑块的 knobPercent 属性访问滑块的值。


使用滑块

显示了 中展示的应用程序的 HTML。

滑块示例的 HTML
<!DOCTYPE html>
<html>
   <head>
      <title>Ad hoc components</title>

      <style>
         body {
            background: rgb(240,240,240);
         }
         
         #title {
            font: 18px Arial;
         }

         #slider-component {
            width: 400px;
            text-align: center;
         }

         #buttons {
            display: inline;
            font: 14px Arial;
         }
         
         #readout {
            margin-left: 25%;
            color: blue;
            font: 18px Arial;
            text-shadow: 2px 2px 2px rgb(255,255,255);
         }
         
         #slider {
            width: 75%;
            height: 30px;
            float: right;
         }

         .slider-button {
            background: rgba(100, 100, 100, 0.2);
            font: 24px Arial;
            font-weight: 1;
            border-radius: 4px;
            border: 1px solid rgba(100, 100, 180, 0.7);
            background: rgba(255, 255, 0, 0.2);
            box-shadow: 1px 1px 2px rgba(0,0,0,0.5);
            cursor: pointer;
            margin: 0px;
         }
      </style>
   </head>
   
   <body>
      <div id='title'>A custom slider</div>

      <p>
         <div id='slider-component'>
            <div id='controls'>
              <div id='buttons'>
                 <input type='button' class='slider-button'
                          id='minus-button' value='&ndash;'/>

                 <input type='button' class='slider-button' 
                          id='plus-button' value='&plus;'/>
              </div>

              <div id='slider'></div>
            </div>

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

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

</html>

中的 HTML 创建了 中显示的 DOM 树。

滑块示例的 DOM 树
滑块示例的 DOM 树包含一个带有滑块组件 ID 的 DIV,该滑块组件包含两个其他 DIV,一个带有控件 ID,另一带有按钮 ID。该按钮 DIV 有两个输入元素,每个类型的按钮都带有一类滑块按钮。一个按钮带有减号按钮 ID,另一个带有加号按钮 ID。最后,滑块组件 DIV 包含一个带有滑块 ID 的空 DIV。

中的 HTML 和 CSS 都比较简单。HTML 引用了两个脚本,一个用于滑块,另一个用于应用程序本身。应用程序脚本如 所示。

滑块示例的 JavaScript 脚本
var slider = new COREHTML5.Slider('black', 'cornflowerblue', 0),
    readoutElement = document.getElementById('readout');

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

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

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

slider.addChangeListener(updateReadout);

slider.appendTo('slider');
slider.draw();

顶部的 JavaScript 脚本中,应用程序创建了一个滑块,黑色描边和浅蓝色填充样式,初始值为零。底部的 JavaScript 脚本表示应用程序将滑块附加到 ID 为 slider 的 DOM 中。中间的 JavaScript 脚本定义了三个事件句柄,对按钮点击和滑块值变更作出响应。

应用程序将 onclick 事件句柄添加到加号(+)和减号(-)按钮,调整滑块值(knobPercent),重绘滑块并更新示值读数。

应用程序还将一个变更监听器添加到该滑块,更新应用程序的示值读数来反映滑块的新值。组件通常会提供一个机制来注册事件监听器,并触发事件来监听这些监听器,滑块组件也不例外。

现在,您已经了解了如何使用一个滑块,接下来,我们将了解滑块组件的实现。


创建和初始化滑块

显示滑块构造函数的 JavaScript 代码。

滑块构造函数
COREHTML5 = COREHTML5 || {};

COREHTML5.Slider = function(strokeStyle, fillStyle,
                            knobPercent, knobAnimationDuration) {
   knobPercent = knobPercent || 0;
   knobAnimationDuration = knobAnimationDuration || 1000; // milliseconds

   this.railCanvas = document.createElement('canvas');
   this.railContext = this.railCanvas.getContext('2d');
   this.changeEventListeners = [];

   this.initializeConstants();
   this.initializeStrokeAndFillStyles(strokeStyle, fillStyle);
   this.initializeKnob(knobPercent, knobAnimationDuration);

   this.createDOMTree();
   this.addMouseListeners();
   this.addKnobTransitionListeners();

   return this;
}

第一行使用一个常见的 JavaScript 脚本来确保存在全局对象,在本例中,该对象是 COREHTML5。(如果确实存在该对象,则将其分配给其本身,否则,将其分配给一个空对象。)

COREHTML5.Slider 构造函数带 4 个可选参数:描边颜色、填充颜色、初始滑块值和旋钮动画周期(以毫秒为单位)。knobPercent 代表滑块的值。

构造函数创建了一个画布,即 railCanvas,该画布包含滑块的滑轨。构造函数还创建了第二个画布,即 knobCanvas,该画布带有 createKnobCanvas()(如 所示),可在 中通过 initializeKnob() 调用它。最后,构造函数创建了滑块的 DOM 树,并向滑块添加了监听程序。

前三个通过滑块的构造函数调用的滑块方法(initializeConstants()initializeStrokeAndFillStyles()initializeKnob())如 所示。

滑块的初始化方法
COREHTML5.Slider.prototype = {
   initializeConstants: function () {
      this.SHADOW_COLOR = 'rgba(100, 100, 100, 0.4)';
      this.SHADOW_OFFSET_X = 3;
      this.SHADOW_OFFSET_Y = 3;
      this.SHADOW_BLUR = 4;

      this.KNOB_SHADOW_COLOR = 'rgba(255,255,0,0.8)';
      this.KNOB_SHADOW_OFFSET_X = 1;
      this.KNOB_SHADOW_OFFSET_Y = 1;
      this.KNOB_SHADOW_BLUR = 0;

      this.KNOB_FILL_STYLE = 'rgba(255, 255, 255, 0.45)';
      this.KNOB_STROKE_STYLE = 'rgb(0, 0, 80)';

      this.HORIZONTAL_MARGIN = 2.5 * this.SHADOW_OFFSET_X;

      this.VERTICAL_MARGIN = 2.5 * this.SHADOW_OFFSET_Y;

      this.DEFAULT_STROKE_STYLE = 'gray';
      this.DEFAULT_FILL_STYLE = 'skyblue';
   },

   initializeStrokeAndFillStyles: function(strokeStyle, fillStyle) {
      this.strokeStyle = strokeStyle ? strokeStyle : this.DEFAULT_STROKE_STYLE;
      this.fillStyle = fillStyle ? fillStyle : this.DEFAULT_FILL_STYLE;
   },

   initializeKnob: function (knobPercent, knobAnimationDuration) {
      this.animatingKnob = false;
      this.draggingKnob = false;

      this.knobPercent = knobPercent;
      this.knobAnimationDuration = knobAnimationDuration;

      this.createKnobCanvas();
   },

   createKnobCanvas: function() {
      this.knobCanvas = document.createElement('canvas');
      this.knobContext = this.knobCanvas.getContext('2d');

      this.knobCanvas.style.position = "absolute";
      this.knobCanvas.style.marginLeft = "0px";
      this.knobCanvas.style.marginTop = "1px";
      this.knobCanvas.style.zIndex = "1";
      this.knobCanvas.style.cursor = "crosshair";
      ...

   },
   ...
};

用于滑轨和旋钮的单独画布

滑块组件对其滑轨和旋钮分别使用了单独画布,以便在旋钮位置发生变化时使用一个 CSS 转换来激活旋钮画布。如果滑块没有在单个画布中绘制滑轨和旋钮,转换将是不可能实现的,因为转换仅适用于 HTML 元素。

initializeConstants() 方法为所有滑块常量创建变量,包括没有指定值时 initializeStrokeAndFillStyles() 使用的描边和填充样式默认值。

中最有趣的方法是 initializeKnob(),在调用 createKnobCanvas() 为滑块旋钮创建一个单独画布之前,需要设置一些变量。createKnobCanvas() 创建了一个画布元素并设置其样式属性,使画布位于封闭画布的左上方。

现在,您已经了解了如何初始化滑轨和旋钮画布,接下来让我们来看看如何将它们用于绘制滑块。


绘制滑块

滑块组件的 draw()erase() 方法如 所示。

绘制和擦除滑块
COREHTML5.Slider.prototype = {
   ...

   erase: function() {
      this.railContext.clearRect(
         this.left - this.knobRadius, 0 - this.knobRadius,
         this.railCanvas.width  + 4*this.knobRadius,
         this.railCanvas.height + 3*this.knobRadius);

      this.knobContext.clearRect(0, 0, this.knobCanvas.width,
                                       this.knobCanvas.height);
   },

   draw: function (percent) {
      this.drawRail();
      this.drawKnob(percent ? percent : this.knobPercent );
   },
};

erase() 方法可以擦除这两个滑块画布:滑轨画布和旋钮画布。相反地,draw() 方法用于绘制滑轨和旋钮。您可以将旋钮的 percent(滑块的值)传递给 draw() 方法,也可以不带参数调用,在该情况下使用滑块的已有值。

绘制滑轨

在 中,滑块组件传递了两个参数来绘制滑轨。

绘制滑轨
COREHTML5.Slider.prototype = {
   ...
   drawRail: function () {
      var radius = (this.bottom - this.top) / 2;

      this.railContext.save();
      
      this.railContext.shadowColor   = this.SHADOW_COLOR;
      this.railContext.shadowOffsetX = this.SHADOW_OFFSET_X;
      this.railContext.shadowOffsetY = this.SHADOW_OFFSET_Y;
      this.railContext.shadowBlur = this.SHADOW_BLUR;

      this.railContext.beginPath();
      this.railContext.moveTo(this.left + radius, this.top);
      this.railContext.arcTo(this.right, this.top, this.right, this.bottom, radius);
      this.railContext.arcTo(this.right, this.bottom, this.left, this.bottom, radius);
      this.railContext.arcTo(this.left, this.bottom, this.left, this.top, radius);
      this.railContext.arcTo(this.left, this.top, this.right, this.top, radius);
      this.railContext.closePath();

      this.railContext.fillStyle = this.fillStyle;
      this.railContext.fill();
      this.railContext.shadowColor = undefined;
      this.railContext.restore();

      this.overlayRailGradient();

      this.railContext.restore();
   },

   overlayRailGradient: function () {
      var gradient =
         this.railContext.createLinearGradient(this.left, this.top,
                                           this.left, this.bottom);

      gradient.addColorStop(0,    'rgba(255,255,255,0.4)');
      gradient.addColorStop(0.2,  'rgba(255,255,255,0.6)');
      gradient.addColorStop(0.25, 'rgba(255,255,255,0.7)');
      gradient.addColorStop(0.3,  'rgba(255,255,255,0.9)');
      gradient.addColorStop(0.40, 'rgba(255,255,255,0.7)');
      gradient.addColorStop(0.45, 'rgba(255,255,255,0.6)');
      gradient.addColorStop(0.60, 'rgba(255,255,255,0.4)');
      gradient.addColorStop(1,    'rgba(255,255,255,0.1)');

      this.railContext.fillStyle = gradient;
      this.railContext.fill();

      this.railContext.lineWidth = 0.4;
      this.railContext.strokeStyle = this.strokeStyle;
      this.railContext.stroke();
   },
   ...
};

首先,滑块的 drawRail() 方法使用了纯色填充滑轨,如 所示。

滑块基底
绘制滑块基底

接着,drawRail() 叠加了一个白色渐变,如 所示。

滑块叠加
绘制滑块叠加

如 所示,为滑轨增加了一定深度,使其看起来好像有一道光从顶部照射下来。

滑块合成
绘制滑块基底和叠加

滑块的 overlayRailGradient() 方法使用 HTML5 Canvas 的 createLinearGradient() 方法来创建渐变。接着,overlayRailGradient() 沿着渐变线逐点添加起止颜色。每个起止颜色都是纯白色,带有不同程度的透明度。最后,overlayRailGradient() 将滑块填充为渐变色,然后描绘轮廓。

绘制旋钮

滑块在单个画布中绘制的旋钮如 所示。

旋钮画布
滑块旋钮的屏幕截图显示滑块颜色(rgba(255,255,0,0.5))和绘制该旋钮的简略版函数:createKnobCanvas()。此函数使用以下代码创建了画布元素:this.knobCanvas = document.createElement('canvas')。

查看 ,滑块使用了一个 document.createElement() 调用来创建旋钮画布。滑块的 fillKnob()strokeKnob() 方法(如 所示)是在该画布中绘制的。

绘制旋钮
COREHTML5.Slider.prototype = {
   ...

   drawKnob: function (percent) {
      if (percent < 0) percent = 0;
      if (percent > 1) percent = 1;

      this.knobPercent = percent;
      this.moveKnob(this.knobPercentToPosition(percent));
      this.fillKnob();
      this.strokeKnob();
   },
   
   fillKnob: function () {
      this.knobContext.shadowColor   = this.KNOB_SHADOW_COLOR;
      this.knobContext.shadowOffsetX = this.KNOB_SHADOW_OFFSET_X;
      this.knobContext.shadowOffsetY = this.KNOB_SHADOW_OFFSET_Y;
      this.knobContext.shadowBlur    = this.KNOB_SHADOW_BLUR;

      this.knobContext.beginPath();

      this.knobContext.arc(this.knobCanvas.width/2, this.knobCanvas.height/2,
                           this.knobCanvas.width/2-2, 0, Math.PI*2, false);

      this.knobContext.clip();

      this.knobContext.fillStyle = this.KNOB_FILL_STYLE;
      this.knobContext.fill();
   },

   strokeKnob: function () {
      this.knobContext.lineWidth = 1;
      this.knobContext.strokeStyle = this.KNOB_STROKE_STYLE;
      this.knobContext.stroke();
   },
   ...
};

drawKnob() 方法带有 percent 参数,该参数代表滑块的位置。该方法设置滑块的值并以此移动旋钮,随后填充和描绘旋钮。

fillKnob() 方法使用半透明黄色填充旋钮,这使得底层的滑轨可以隐约显示,让旋钮看起来像是在发光。strokeKnob() 方法使用纯色描绘旋钮轮廓。


拖拽旋钮

拖拽旋钮的滑块代码如 所示。

拖拽旋钮
COREHTML5.Slider.prototype = {
   ...
   
   addMouseListeners: function () {
      var slider = this; // Let event handlers access this object

      this.knobCanvas.addEventListener('mousedown', function(e) {
         slider.draggingKnob = true;
         e.preventDefault();
      };
      
      this.knobCanvas.addEventListener('mousemove', function(e) {
         var mouse = null,
             percent = null;

         e.preventDefault();

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

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

      this.knobCanvas.addEventListener('mouseup', function(e) {
         e.preventDefault();
         slider.draggingKnob = false;
      }; 
   }, 

   windowToCanvas: function(x, y) {
      var bbox = this.railCanvas.getBoundingClientRect();

      return {
         x: x - bbox.left * (this.railCanvas.width  / bbox.width),
         y: y - bbox.top  * (this.railCanvas.height / bbox.height)
      };
   },

   knobPositionToPercent: function(position) {
      var railWidth = this.right - this.left - 2*this.knobRadius;
          percent = (position - this.left - this.knobRadius) / railWidth;

      percent = percent > 1.0 ? 1.0 : percent;
      percent = percent < 0 ? 0 : percent;

      return percent;
   },
   ...
};

回忆一下 ,滑块的构造函数调用了 所示的 。该方法向旋钮画布添加了鼠标按下、鼠标移动和鼠标释放事件句柄,用它们来管理旋钮画布的拖拽。两个帮助函数方法(windowToCanvas()knobPositionToPercent())使得这些事件句柄易于理解。


结束语

通过本文的简述,相信您现在已经了解如何实现特殊的 HTML5 组件。本 系列文章 的下一篇文章将继续介绍滑块组件,向您展示如何支持更改监听器,如何通过编程方式使用 CSS 转换来激活滑块的旋钮,以及如何将滑块组件添加到任意的 DOM 树。下期见!


下载

描述名字大小
样例代码wa-html5-components-1.zip8KB

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Web development
ArticleID=862132
ArticleTitle=HTML5 组件: 特殊组件,第 1 部分
publish-date=04162013