内容


和 Polymer 一起加入 Web 组件革命

使用可重用的、可组合的、可视的功能组件组装现代的移动 Web 应用程序

Comments

和所有广泛部署的技术一样,HTML 浏览器也面临着过时和边缘化的风险。由于网络化信息访问模式的变化和主流用户要求提供新的 UI 功能(有竞争力的替代技术层出不穷),浏览器厂商要想生存就必须求变。这种需求催生了 W3C Web Components,这是一个数年前启动的社区标准计划,获得了所有现代浏览器厂商的支持。Web Components 包含几种规范草案,支持开发人员以可扩展和可维护的方式创建和共享可重用的自定义 HTML 元素(Web 组件)。

Polymer 是一种拥有丰富工具、受到良好支持的跨平台开源库,它利用了新兴的 Web Components 标准。Polymer 的及时出现为渴望构建现代 Web 应用程序的开发人员带来了福音。目前,Web 应用程序设计趋向于单页面和高度交互式的应用程序。使用 Web 技术构建的混合型移动应用程序正在变成惯例而非特例。借助 Polymer,创建这两类应用程序比使用传统的 JavaScript DOM 操作库要简单得多。

使用 Polymer(和 Web Components 库)有两种方式:

  • 以消费者(consumer)身份: 使用 Web 组件构建自己的应用程序。
  • 以创建者(creator)的身份: 创建可重用的 Web 组件,用于自己的应用程序或进行共享。

通过一系列的示例,本指南向您介绍了 Polymer,并说明了如何使用和定制 Polymer Web 组件。(参见 下载 部分,以便获取示例代码。)配套指南"使用 Polymer 创建可重用的自定义 Web 组件" 分步介绍了如何在 IBM Bluemix™ 中使用 Mobile Cloud 样板文件创建用户自己的 Web 组件。

Polymer:一个跨平台的 Web 组件库

Polymer 是一个预编译库,其中包含的 Web 组件可用于构建应用程序或新的 Web 组件。Polymer 还包含行业标准的 polyfill,确保库的行为方式与所有现代浏览器相同。polyfill 是必不可少的,因为浏览器厂商仍然在积极实现 Web Components 标准的各个方面,并取得了各自的进展。

Polymer 是一家浏览器厂商通过调整自身产品,以求将来在 Web Components 大行其道的立足产物。Polymer 开发团队与核心浏览器 (Chrome) 开发团队开展了空前的合作,因此该浏览器的开发与这个库是紧密耦合的 — 确保经过所有核心的 Chrome 变化后,库依然能维持高性能水平并正常工作。在撰写本文之际,Polymer 正处于 “开发人员预览” 阶段。

图 1 显示了 Polymer 的高级结构。

图 1. Polymer 的高级结构
Polymer 的高级结构
Polymer 的高级结构

目前,通过 Polymer 的平台,应用程序可以将 Web Components 用于多种浏览器,具体使用方法是包含 platform.js。Polymer 可保证针对包含各种水平的 Web Components 规范本地实现的浏览器、库和组件的使用效果完全相同。

Polymer 可保证针对包含各种水平的 Web Components 规范本地实现的浏览器、库和组件的使用效果完全相同。

使用 Polymer 时,您对于 DOM、CSS 和 JavaScript 的了解和喜好都可以继续发挥作用。另外,通过使用 DOM、CSS 和 JavaScript,您现在可以创建可重用的自定义 HTML 组件,并在组件中完整封装 UI 部分或应用程序功能。

Polymer 能够在以下方面提供帮助:组件注册、生命周期管理、属性处理,但与 Web 组件部署相关的其他任务除外。Web 开发社区目前正在共享一个不断增长的公用组件开源库。对于使用别人创建的 Web 组件的开发人员,惟一需要了解的其他事情是一套要使用的新 HTML 标签。

一种自适应的响应式布局组件

假设您希望应用程序的布局随着打开应用程序设备的大小而变化。有一种布局应该适合小尺寸的移动设备屏幕,而另一种布局则适合桌面浏览器。在第一个例子中,我们可以了解如何使用 Polymer 创建响应式的布局。

图 2 显示了布局在桌面或平板浏览器中的外观。

图 2. 使用桌面屏幕尺寸的响应式布局
使用桌面屏幕尺寸的响应式布局
使用桌面屏幕尺寸的响应式布局

桌面布局的左侧有一个侧边栏,可能用于导航,还有它自己的标题与可单击的菜单选项。在典型的应用程序中,用户在导航栏中进行选择,右侧面板中就会显示所选择的内容。右侧面板在顶部同样有自己的标题工具栏。

当设备屏幕宽度变窄时,左侧边栏的面板也会收缩,只显示内容面板。一个 "hamburger" 菜单按钮将会自动出现在留下面板的工具栏中。图 3 显示了布局的小尺寸设备版本。

图 3. 移动手机窄屏上的响应式布局
移动手机窄屏上的响应式布局

单击本段后面的 View the layout 按钮,在桌面浏览器和手机浏览器中打开示例页面,对两种布局进行比较。或者,和本指南中所有的示例一样,您可以在桌面版本中手动调整浏览器窗口的宽度,从而模拟手机浏览器的行为。

请注意,当点击或单击 hamburger 菜单按钮时,抽屉将从左侧滑入,覆盖主面板的右侧(通常是为了显示一个可用选择的列表),如图 4 中所示。

图 4. 导航侧边栏菜单从左侧滑到内容面板之上
导航侧边栏菜单从左侧滑到内容面板之上

如果使用标准的 HTML/JavaScript 库,则需要使用大量的代码才能使用这些库来实现相同的行为。清单 1 显示了使用 Polymer 创建响应式布局的代码。

清单 1. 使用 <core-scaffold> Polymer 组件
的滑入响应式布局
<!doctype html>
<html>

<head>
  <title>unquote</title>
  <meta name="viewport" 
  content=
  "width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
  <script src="../bower_components/platform/platform.js"></script>
  <link rel="import" 
     href="../bower_components/core-scaffold/core-scaffold.html">
</head>

<body>
  <core-scaffold>
  </core-scaffold>
</body>

</html>

在清单 1 中,Polymer 平台库是通过 <script> 标签中的 platform.js 包含进来的。另外的组件则是通过 HTML Imports 包含进来的:在这个例子中,<core-scaffold> Web 组件通过 core-scaffold.html 包含进来。

要生成丰富的响应式尺寸调整行为,只需使用 <core-scaffold> Web 组件。 <core-scaffold> 似乎是新出现的 HTML 标签,但它实际上是一个自定义的 Web 组件,属于 Polymer 的核心元素库。Polymer 的核心中包含一整套有用的 Web 组件,可以给 Web 开发带来前所未有的简单体验。您可以浏览 文档 来查看可用的组件。

请注意,<body> 只包含一个 <core-scaffold> 标签,这就足够用了。<core-scaffold> 自定义元素完全封装了复杂的响应式 UI 处理。

可以将 Polymer 组件(包括 <core-scaffold>)相互结合使用,也可以与其他自定义 Web 组件结合使用,以便创建页面或单页面 Web 应用程序(或是自己自定义的 Web 组件)。

通过属性定制 Web 组件

与标准 HTML 元素一样,自定义 Web 组件也有可用于未来定制的属性。Polymer <core-scaffold> 组件有两个可用的属性:

  • responsiveWidth 控制侧边栏收缩到左侧时的最小设备宽度。此属性的默认值为 600px
  • mode 控制内容滚动时的标题行为。mode 的默认值为 seamed。(本指南将在下一示例中探讨其他可能的模式。)

清单 1 中尝试将 responsiveWidth 修改为一个较小的值,试验响应式布局切换到窄版本时的情形:

<core-scaffold responsiveWidth='300px'></core-scaffold>

请注意:您必须从 Web 服务器运行应用程序,这样 HTML Imports polyfill 才能正常工作。

自定义元素的内部结构也是使用 HTML、CSS 和 JavaScript 来实现的。但实现细节对于元素的用户不可见。感谢自定义元素的 Shadow DOM 提供的封装,您不必担心代码与组件的内部实现之间出现 JavaScript 命名空间冲突或 CSS 样式污染的情况。

从内部讲,<core-scaffold> 包含其他几种 Polymer 核心组件。接下来您就将了解如何定制它们。

组合:Web 组件的基础

通过将另外的可视化 Web 组件组装到一个 <core-scaffold> 实例中,可以制造出 Web 应用程序(或单页面移动应用程序)的核心 UI 结构。下一个例子将显示如何给侧边栏添加一个选择菜单,并为当内容滚动时收缩的内容面板添加一个特别高的标题。

使用窄屏幕宽度启动应用程序时,标题区域是特别高的,以便有足够空间添加其他的 UI 组件,比如标签栏,如图 5 中所示。

图 5. 具有特别高的标题的内容面板
具有特别高的标题的内容面板

向下滚动面板的内容时,高标题会变短,最终与标准的工具栏高度一样,如图 6 中所示。

图 6. 高标题收缩至标准的工具栏高度
高标题收缩至标准的工具栏高度

如果再次向下滚动内容,标题又会扩展。如果随时单击 hamburger 菜单,侧边栏将带着一个完整菜单,并与一个带有标题与 dW 标志的工具栏同时出现,如图 7 中所示。

图 7. 使用可选择菜单与主题工具栏扩展后的侧边栏抽屉
使用可选择菜单与主题工具栏扩展后的侧边栏抽屉

这个例子的代码位于 dwpcompose/index.html 中(参见 下载)。 图 8 显示了组合在一起形成骨架 UI 的 Web 组件。

图 8. 通过组合 Polymer 核心组件来构造 UI
通过组合 Polymer 核心组件来构造 UI
通过组合 Polymer 核心组件来构造 UI

现在的代码包含更多的 HTML 导入,分别用于组合中的 Web 每个组件,其中包括用于 Roboto 字体(一种用于移动设备的清晰字体,是目前 Android 设备的主流字体)的一个组件:

<link rel="import" href="../bower_components/font-roboto/roboto.html">
  <link rel="import" href="../bower_components/core-scaffold/core-scaffold.html">
  <link rel="import" href="../bower_components/core-icon-button/core-icon-button.html">
  <link rel="import" href="../bower_components/core-menu/core-menu.html">
  <link rel="import" href="../bower_components/core-header-panel/core-header-panel.html">
  <link rel="import" href="../bower_components/core-item/core-item.html">

<core-scaffold>mode 属性现在被置为 waterfall-tall,指示 Web 组件处理高标题的折叠。<body> 标签上的 unresolved 属性将会激活代码,防止某些浏览器上出现 无样式内容闪烁 (FOUC) 现象。touch="auto" 属性确保触摸行为在所有受支持的浏览器上得到的处理都是相同的:

<body unresolved touch="auto">
  <core-scaffold mode="waterfall-tall">

收起的侧边栏包含在 <core-scaffold> 元素内。标题包含两个组成部分:<core-toolbar> 和位于 <core-header-panel> 容器内的 <core-menu>

<core-header-panel> 上的 navigation 属性通知 <core-scaffold> 容器,这是一个用于导航式可收回抽屉的元素。<core-header-panel> 也将自己的模式置为 seamed,这表示所有内容都将与标题一起滚动。<core-toolbar> 包含 dW 标志图标和标题:

<core-header-panel navigation flex mode="seamed">
  <core-toolbar><img src='/images/dwlogo.svg' width='50px' height='30px'>
  <span flex>Compose</span>
  </core-toolbar>

<core-menu> 包含两项内容,分别名为 s1s2。因为 selected 属性的值为 s1,一开始选择的是 s1 项。名为 explore 的图标用于两个菜单项,它来自于 <core-icon> 集合(早先已经导入):

  <core-menu  id='menu'  selected="s1" >
    <core-item name="s1" icon="explore"  label="Selection 1"></core-item>
    <core-item name="s2" icon="explore"  label="Selection 2"></core-item>
  </core-menu>
</core-header-panel>

在 Polymer Icons 页面上可以看到所有可用的图标以及它们相应的名称。

右侧面板的工具栏包含 hamburger 按钮,这是由组件内部管理的。但通过给一个元素添加 tool 属性,就可以将这个属性添加到这个工具栏。在例子中,在工具栏的底部添加了一个 "Components" 标题。此外,还有一个设置按钮(实际上是一个 <core-icon-button> 元素,带有一个名为 more-vert 的图标)被添加到工具栏的右侧。带有 flex 属性的空 <span> 占据了中心的空闲空间。Polymer 为布局属性(比如这里使用的 flex)提供一种直观的声明语法,极大地简化了底层 CSS Flexbox 的部署。

最后一点但并非最不重要的一点,content 类的 <div>distributed(Web Components 术语,意思是插入) 到 <core-scaffold> 的右侧面板的内容区域中:

 <div tool class="bottom indent">Components</div>

  <span tool flex></span>
  <core-icon-button tool icon="more-vert" on-tap="{{settingsAction}}"></core-icon-button>

  <div class="content">First line<br/>Second line</div>
  </core-scaffold>

</body>

使用 Web 组件绘制业务图

现在,我将扩展框架,添加一些数据,然后创建一个应用程序。

这第二个例子使用一个 Web 组件来绘制业务图。该应用程序根据菜单选择显示两个销售图之一,区域销售或每月总体销售。

使用收回的抽屉侧边栏,可以选择两幅图中的任意一幅,如图 9 中所示。

图 9. 两幅销售图的侧边栏选择
两幅销售图的侧边栏选择
两幅销售图的侧边栏选择

选择区域销售时,将显示一幅饼图,如图 10 中所示。

图 10. 显示区域销售饼图
显示区域销售饼图
显示区域销售饼图

选择每月总体销售时,将显示一幅柱状图,如图 11 所示。

图 11. 每月总体销售的柱状图
每月总体销售的柱状图
每月总体销售的柱状图

今天,开源社区中可用的、预先构造好的 Web 组件数以百计。这个数字很快就会变成数千,而且还会出现商业的可用组件。Google Web 组件 (本例中使用的 <google-chart> 组件的起源)和 customelements.io 是两个更为流行的 Web 组件库。查阅每个 Web 组件的文档,了解可用的属性、方法、事件与集成注意事项。

可以使用 Bower 组件来安装 Web 组件:

bower install GoogleWebComponents/google-chart --save

在 dwpgraph/index.html 中可以找到此应用程序的代码(参见 下载 部分)。 <google-chart> 组件通过 HTML Imports 包含在代码中:

<link rel="import" href="../bower_components/google-chart/google-chart.html">

这个应用程序示例通过演示表明,可以使用 CSS 设计 Web 组件的样式,处理事件,修改属性和调用方法。

使用 CSS 设计 Web 组件的样式

和使用内置的 HTML 元素一样,您可以对 Web 组件应用任何 CSS 样式。

在销售图应用程序的代码中,在 <style> 区域中可以看到 <google-chart> 元素(其宽度已经设定)的样式:

google-chart {
      width: 380px;
   }

从 Web 组件处理事件

和标准的 HTML 元素一样,Web 组件可以触发事件来响应用户交互或其他输入。例如,当用户触摸或单击 <core-menu> 项时,就会触发 core-select 事件。

通过给菜单添加一个事件监听器,可以为时间编写一个处理器。添加处理器的代码如下:

 var menu = document.querySelector('core-menu');

 menu.addEventListener( 'core-select', function (evt) {
    ... event handler logic ...
});

此应用程序中的时间处理器逻辑操作 <google-chart> Web 组件的属性,以显示选定的销售图。这些图的数据来自于一个硬编码的、与 JSON 兼容的 JavaScript 对象。在生产应用程序中,可以通过网络从数据库中(或许使用 Polymer <core-ajax> 组件)获取数据。

修改自定义 Web 组件的属性

通过声明或编程的方式可以修改 Web 组件包含的属性。前面曾经使用过 <core-scaffold> 组件的 responsiveWidth 属性。在销售图应用程序的事件处理器中,以编程方式设置了 <google-chart> 组件的四个属性(通过 DOM 节点的 setAttribute() 方法),用于设置的值来自于 JSON 数据源。

因为当取消某项选择时也会出发一个 core-select 事件,检查 isSelected 标志可以确保逻辑只会在项目选择时执行:

menu.addEventListener( 'core-select', function (evt) {
   if (evt.detail.isSelected)  {
    var chart = document.querySelector('google-chart');
    var scaffold = document.querySelector('core-scaffold');
    var graph = document.getElementById('graph');
    var selectedGraph = analytics[menu.selected];
    chart.setAttribute("type", selectedGraph.type);
    chart.setAttribute("options", selectedGraph.options);
    chart.setAttribute("cols", selectedGraph.cols);
    chart.setAttribute("rows", selectedGraph.rows);
    
    graph.innerHTML = selectedGraph.name;
    console.log(menu.selected);
    scaffold.togglePanel();
  }
});

调用 Web 组件的方法

自定义 Web 组件可以实现 Web 组件用户能够直接调用的方法。对于 <core-header-panel>,当框架处于窄显示模式时,调用一个名为 togglePanel() 的方法就可以让抽屉面板滑入和滑出。

在事件处理器代码中,在完成 chart 元素的属性更新后,就会通过调用 scaffold.togglePanel() 方法来关闭抽屉面板:

chart.setAttribute("type", selectedGraph.type);
chart.setAttribute("options", selectedGraph.options);
chart.setAttribute("cols", selectedGraph.cols);
chart.setAttribute("rows", selectedGraph.rows);		
...
scaffold.togglePanel();

一个地图应用程序

Web 组件不仅封装了可视化显示和用户交互处理,还封装了一套完整的应用程序功能:包括数据访问、应用逻辑和网络通信。

下一个例子在应用程序中添加了一个完整的、可以立即使用的交互式地图组件。

此应用程序展示了一个包含三个位置(Raleigh、San Francisco 和 San Diego)的菜单,如图 12 中所示。

图 12. 带有位置选择菜单的应用程序
带有位置选择菜单的应用程序
带有位置选择菜单的应用程序

选择其中一个位置时,内容面板中将显示一幅所选区域的地图。该地图是完全交互式的,可以添加卫星地图,放大地图等等,这些操作均由添加的 Web 组件提供

图 13 中显示的是 San Francisco 地图。

图 13. 显示 San Francisco 地区交互式地图的应用程序
显示 San Francisco 地区交互式地图的应用程序
显示 San Francisco 地区交互式地图的应用程序

图 14 中显示的是使用窄模式布局的 Raleigh 地图。

图 14. 以窄屏模式显示 Raleigh 交互式地图的应用程序
以窄屏模式显示 Raleigh 交互式地图的应用程序
以窄屏模式显示 Raleigh 交互式地图的应用程序

组件中封装了复杂的地图 UI 处理,您可以免费获得它。用于获取地图数据的网络访问,以及地图数据的处理和显示,也都封装在 Web 组件的内部。用户只需要指定位置的经度和纬度,就可以显示在地图的中心。

创建地图应用程序

地图应用程序的源代码位于 dwpmap/index.html 文件中(参见 下载)。该应用程序的架构类似于销售图应用程序示例。下面总结了创建此应用程序的步骤:

  1. 将 Web 组件安装到项目中:
    bower install PolymerLabs/google-map --save
  2. 使用 HTML Imports 将 Web 组件导入到应用程序中:
    <link rel="import" href="../bower_components/google-map/google-map.html">
  3. <google-map> Web 组件添加到内容区域中:
      <div class="content">
        <google-map> 
        </google-map>
      </div>
  4. 自定义菜单项以显示城市名称。选择改变时将触发 core-select 事件:
    <core-menu id='menu' selected="sf" >
    <core-item name="rh" icon="explore" label="Raleigh"></core-item>
    <core-item name="sf" icon="explore" label="San Francisco"></core-item>
    <core-item name="sd" icon="explore" label="San Diego"></core-item>
    </core-menu>
  5. 使用位置的经度与纬度数据创建一个与 JSON 兼容的数据模型。请注意,密钥要与菜单中的 <core-item> 名称相匹配:
    var waypoints = { 
      "rh" : {"latitude":"35.843768", "longitude":"-78.645056", 
           "fullname":"Raleigh"},
    "sd" : {"latitude":"32.8245525", "longitude":"-117.0951632", 
    "fullname":"San Diego"},
    "sf": {"latitude": "37.77493", "longitude": "-122.414942", 
    "fullname":"San Francisco"}};
  6. core-select 事件处理器进行编码,以便在选择改变时更新 <google-map> 组件的属性:
    var menu = document.querySelector('core-menu');
    
     menu.addEventListener( 'core-select', function (evt) {
       if (evt.detail.isSelected)  {
        var map = document.querySelector('google-map');
        var scaffold = document.querySelector('core-scaffold');
        var location = document.getElementById('location');
        var selectedLocation = waypoints[menu.selected];
        map.setAttribute("latitude", selectedLocation.latitude);
        map.setAttribute("longitude", selectedLocation.longitude);
        location.innerHTML = selectedLocation.fullname;
        console.log(menu.selected);
        scaffold.togglePanel();
      }
     });

可以看出,只需使用几个 Web 组件,就可以创建一个复杂的真实应用程序。例如,您的应用程序可能基于一个在线分析处理(OLAP)数据集进行工作,在世界地图上显示销售相关的总结信息,然后允许用户深入了解每个地区(或者甚至是一个地区内的特定店面或位置)的销售详情,只要他们在移动设备上触摸选择地图即可。这个假想的示例演示了 Web 组件组合的强大之处。

Polymer 拖放式组件设计器让设计变得更简单

对 Web 组件进行手动编码十分直观。为了让 Web 组件的使用更加容易,让更多开发人员能够接受它们,Polymer 提供了一个有用的在线 beta 版 拖放式设计器

由于 Web 组件在本质上是可以组合的,可以使用拖放式设计器将现有组件结合在一起,从而创建更高级的组件,甚至是整个应用程序。

图 15 显示了使用中的拖放式设计器。

图 15. Polymer 的拖放式自定义元素设计器
Polymer 的拖放式自定义元素设计器
Polymer 的拖放式自定义元素设计器

beta 版设计器当然有一些限制。进行最复杂的组件组装时,仍然需要手动编写一些拖放式设计器无法生成的代码。但可以使用该设计器手动编辑底层的 HTML 文件。而且请您放心,用于构建应用程序与组件的更加完善的解决方案正在从各处源源不断地涌现。

结束语

Polymer 构建在 Web Components 标准之上,并将作为 Web 与移动应用程序开发基础的 DOM(现在开发人员可以进行扩展)的绝对优势延续到下一个十年。Polymer 再次证实了浏览器厂商的郑重承诺:发展和调整它们的旗舰产品,从而更好地为满足最新一代用户与应用程序开发人员的需求而服务。


下载资源


相关主题

  • "使用 Polymer 创建可重用的自定义 Web 组件"(Sing Li,developerWorks,2014 年 9 月):查阅本指南,了解构建用户自己的自定义 Web 组件的每个步骤。
  • Polymer:查找最新可用的 Polymer 组件、示例代码与文档。
  • Google Web 组件:尝试使用这个开源库中的一些实用的 Web 组件。
  • Browser Compatibility:关注这个网站,跟踪对 Polymer 最新的跨平台、跨浏览器的支持与兼容性。
  • customelements.io:试用这个库中各种社区构建的可用 Web 组件。
  • Material Design:了解 Android 系统上 material design 的更多信息,Polymer paper 组件集合完全支持它。
  • developerWorks Web development 专区:通过专门关于 Web 技术的文章和教程,扩展您在网站开发方面的技能。
  • developerWorks Ajax 资源中心:这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。
  • 查看 HTML5 专题,了解更多和 HTML5 相关的知识和动向。

评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Web development, 移动开发
ArticleID=988597
ArticleTitle=和 Polymer 一起加入 Web 组件革命
publish-date=11062014