用于构建跨设备 Web 应用的无响应方法

Boris Smus
Boris Smus

媒体查询很棒,但...

媒体查询非常好用,如果网站开发者希望 只要对样式表稍作调整,就能 使用各种尺寸的设备从本质上讲,媒体查询可让您 根据屏幕尺寸自定义网站的 CSS。潜水之前 请参阅这篇文章,详细了解自适应设计并参阅 下面是一些关于媒体查询用法的精致示例:mediaqueri.es

正如 Brad Frost 在先前的文章中所指出的,改变了外观 只是在构建移动网站时需要考虑的众多事项之一。 如果您在构建移动网站时唯一要做的事情就是 媒体查询布局,就会出现以下情况:

  • 所有设备均获取相同的 JavaScript、CSS 和资源(图片、视频), 进而导致加载时间超过所需时间
  • 所有设备均获得相同的初始 DOM,这可能会迫使开发者 编写过于复杂的 CSS
  • 无法灵活指定为每个广告系列量身定制的自定义互动 设备。

Web 应用需要的不仅仅是媒体查询

不要误会我的意思。我并不讨厌通过媒体查询进行的自适应设计, 并坚信它在世界上的任何地方此外, 上述问题可以通过 自适应图片、动态脚本加载等。 那么您可能会发现自己进行了太多的增量调整 最好提供不同的版本

随着您构建的界面不断增加,您倾向于 您需要做更多事情来为每个应用自定义界面, 设备类型本文将向您介绍 轻松完成自定义。一般方法 涉及到将访问者的设备分类到正确的设备 类,并为该设备提供适当的版本,而 尽可能在版本之间重复使用代码。

您定位的是哪些设备类别?

市面上有大量联网设备, 但其中大多数都安装了浏览器复杂之处在于它们的多样性:Mac 笔记本电脑、Windows 工作站、iPhone、iPad、带触控功能的 Android 手机 输入, 滚轮, 键盘, 语音输入, 有压力的设备 智能手表、烤面包机和冰箱等等。 其中一些设备无处不在,而另一些则非常罕见。

<ph type="x-smartling-placeholder">
</ph> 各种设备。
多种设备(来源)。

为了打造良好的用户体验,您需要了解您的用户 以及所使用的设备如果您为应用构建了 桌面设备用户,他们会使用鼠标和键盘,然后把它交给智能手机 因为您的界面是专为 不同的屏幕尺寸和输入模式。

这些方法存在两种极端结果:

  1. 构建一个适用于所有设备的版本。用户体验将会受到影响 因为不同的设备有不同的设计考虑因素。

  2. 为您希望支持的每台设备构建一个版本。这需要 因为你将构建过多版本的 应用。此外,在新款智能手机问世时 (大约每周发生一次),因此您必须创建 另一个版本。

需要从根本上做出权衡:您选择的设备类别越多 就能提供更出色的用户体验 设计、实现和维护所需的工作量。

为您决定的每个设备类别创建单独的版本 或您想投放的版本 差异很大。否则,使用自适应网页设计 设计是一种完全合理的方法。

可能的解决方案

一种折衷方案是:对设备进行分类, 最佳体验。您选择的类别 取决于您的产品和目标用户。下面是一个分类示例 能够很好地覆盖当今流行的具有网络兼容性的设备。

  1. 小屏幕 + 触摸(大多数手机)
  2. 大屏幕 + 触摸(大多数平板电脑)
  3. 大屏幕 + 键盘/鼠标(大多数台式机/笔记本电脑)

这只是众多可能的细分之一, 更有意义。上述列表中缺少移动设备 无触摸屏设备(例如功能手机、某些专用的电子书) 读者)。不过,大多数这类应用都支持键盘导航或屏幕导航 已安装读卡器软件,如果您构建自己的网站,就能正常使用 也非常注重无障碍功能

特定于外形规格的 Web 应用示例

很多网站媒体资源的投放方式都完全不同 针对不同外形规格提供不同的版本。Google 搜索就是这样做到的 Facebook。对于这种情况, 资源、呈现网页)和更笼统的用户体验。

在原生应用的世界中,许多开发者选择 设备类别的体验例如 Flipboard, 与 iPhone 上的 Flipboard 相比,iPad 的界面截然不同。平板电脑 针对双手操作和水平翻转操作进行了优化 手机版本适合单手互动, flip。许多其他 iOS 应用提供的功能与 手机和平板电脑版本,例如Things(待办事项列表)以及 Showyou(社交视频),精选如下:

<ph type="x-smartling-placeholder">
</ph> 针对手机和平板电脑的重要界面自定义。
针对手机和平板电脑的重要界面自定义。

方法 1:服务器端检测

在服务器上,我们对设备的了解要少得多 这点可能是目前找到的 是用户代理字符串,通过 。因此,相同的 UA 嗅探方法将会起作用 此处。事实上,DeviceAtlas 和 WURFL 项目已经这样做了(并且 提供有关设备的大量额外信息)。

遗憾的是,每种解决方案都有自己的挑战。WURFL 非常 包含 20MB XML 文件,可能会导致 服务器端开销。有几个项目将 出于性能方面的原因使用 XML。DeviceAtlas 不开源,并且 需要付费许可才能使用

还有更简单的免费替代方案,例如检测移动设备 Browsers 项目。当然,其缺点是 检测将不可避免地不够全面。此外,它只有 用于区分移动设备和非移动设备, 仅通过一组临时调整来支持平板电脑。

方法 2:客户端检测

通过使用功能,我们可以详细了解用户的浏览器和设备。 检测。我们需要确定的主要事项是,设备是否具有 触控功能,以及是大屏幕还是小屏幕。

我们需要划定界限,以区分大小和大小 设备。那么像 5 英寸Galaxy Note?以下 图中显示了许多热门的 Android 和 iOS 设备(叠加了 相应的屏幕分辨率)。星号表示 或者可能会配备双密度。尽管像素密度 CSS 仍会报告相同的尺寸。

我们先说说 CSS 像素:移动网站上的 CSS 像素并不是 与屏幕像素相同。iOS Retina 设备引入了 将像素密度翻倍的做法(例如,iPhone 3GS 与 4、iPad 2 对比 3)。 Retina Mobile Safari UA 仍会报告相同的设备宽度,以避免 突破网络当其他设备(例如Android 设备)获得更高的分辨率 那么它们在设备宽度上的做法完全一样。

<ph type="x-smartling-placeholder">
</ph> 设备分辨率(以像素为单位)。
设备分辨率(以像素为单位)。

然而,重要的是考虑将这种决策复杂化。 均支持竖屏和横屏模式我们不想重新加载页面或 虽然我们每次调整设备方向时都会加载额外的脚本, 可能需要以不同的方式呈现网页。

在下图中,正方形表示每个图片的最大尺寸 因为在纵向和横向轮廓上叠加 (并完成方格):

<ph type="x-smartling-placeholder">
</ph> 纵向 + 横向分辨率(以像素为单位)
纵向 + 横向分辨率(以像素为单位)

通过将阈值设为 650px,我们将 iPhone 和 Galaxy Nexus 归类为 将 iPad、Galaxy Tab 用作“平板电脑”。双生星系 注意,在这种情况下被归类为“手机”, 布局。

因此,合理的策略可能如下所示:

if (hasTouch) {
  if (isSmall) {
    device = PHONE;
  } else {
    device = TABLET;
  }
} else {
  device = DESKTOP;
}

查看实际应用的特征检测方法的最小示例。

此处的替代方法是使用 UA 嗅探来检测设备 类型。基本上,您要创建一套启发词语, 用户的 navigator.userAgent。伪代码类似于 :

var ua = navigator.userAgent;
for (var re in RULES) {
  if (ua.match(re)) {
    device = RULES[re];
    return;
  }
}

查看实际应用的 UA 检测方法的示例。

客户端加载注意事项

如果您在服务器上进行 UA 检测,则可以决定 当您收到新请求时提供的 JavaScript 和 DOM。但是,如果 执行客户端检测的情况则要复杂一些。您 有以下几种选择:

  1. 重定向至设备类型专用网址,其中包含 这种设备类型。
  2. 动态加载设备类型专用资源。

第一种方法很简单,需要重定向,例如 window.location.href = '/tablet'。但该营业地点现在将 因此您可能需要使用 History API,以清理网址。很遗憾, 方法涉及重定向,速度可能会很慢,尤其是在移动设备上 设备。

第二种实现方法稍微复杂一些。您需要 用于动态加载 CSS 和 JS 的机制,并且(具体取决于浏览器) 可能无法执行自定义<meta viewport>等操作。此外, 因为没有重定向,所以会一直使用之前 。当然,您也可以使用 JavaScript 来操作它 缓慢且/或不优雅,具体取决于您的应用。

决定客户端还是服务器

以下是这两种方法之间的权衡取舍:

专业客户端

  • 由于基于屏幕尺寸/功能而非 UA,因此可以更好地满足未来需求。
  • 无需不断更新 UA 名单。

专业服务器

  • 可完全控制向哪些设备提供哪个版本。
  • 性能更佳:无需客户端重定向或动态加载。

我个人偏好从 device.js 和客户端开始 检测。随着应用的发展,如果您发现客户端重定向 会极大地降低性能,您可以轻松移除 device.js 脚本,并在服务器上实现 UA 检测。

device.js 简介

Device.js 是执行基于语义的媒体查询的起点 而无需进行特殊的服务器端配置, 从而节省进行用户代理字符串解析所需的时间和精力。

这样做的目的是,您提供易于搜索引擎使用的标记(链接 rel=alternate<head> 以指明 自己想提供的网站版本

<link rel="alternate" href="http://foo.com" id="desktop"
    media="only screen and (touch-enabled: 0)">

接下来,您可以执行服务器端 UA 检测并处理 或者使用 device.js 脚本 基于功能的客户端重定向

如需了解详情,请参阅 device.js 项目页面,以及 也是一个使用 device.js 的虚假应用 客户端重定向。

建议:使用特定于外形规格的视图的 MVC

到目前为止,你可能在想我让你 一个完全独立的应用,每个设备类型对应一个。否!“代码共享”现为 密钥。

希望您一直在使用类似于 MVC 的框架,如 Backbone, Ember 等。如果你有过这样的经历,那么你应该已经熟悉 关注点分离,具体而言,您应将界面(视图层) 与逻辑(模型层)分离。如果您还不熟悉 我们首先来看一些有关 MVC 的资源,以及 MVC JavaScript

跨设备故事完美契合您现有的 MVC 框架。您 你可以轻松地将视图移到单独的文件中 。然后,您便可向所有设备提供相同的代码 但视图层除外。

<ph type="x-smartling-placeholder">
</ph> 跨设备 MVC。
跨设备 MVC

你的项目可能具有以下结构(当然,你是免费的 您可根据自己的需求选择最合适的结构 应用):

models/(共享模型) item.js item-collection.js

控制器 s/(共享控制器) item-controller.js

version/(设备特定的内容) tablet/ 桌面设备/ phone/(手机专用代码) style.css index.html 次观看/ item.js item-list.js

这种结构可让您全面控制每个资源 因为每个广告素材都有自定义的 HTML、CSS 和 JavaScript 设备。这种方法非常强大,可以带来最精简、 高效开发跨设备网站的方法, 一些技巧,例如自适应图像。

运行您喜爱的构建工具后,您需要将所有 转换为单个文件,以提高加载速度 您的生产 HTML 应如下所示(适用于手机、 使用 device.js):

<!doctype html>
<head>
  <title>Mobile Web Rocks! (Phone Edition)</title>

  <!-- Every version of your webapp should include a list of all
        versions. -->
  <link rel="alternate" href="http://foo.com" id="desktop"
      media="only screen and (touch-enabled: 0)">
  <link rel="alternate" href="http://m.foo.com" id="phone"
      media="only screen and (max-device-width: 650px)">
  <link rel="alternate" href="http://tablet.foo.com" id="tablet"
      media="only screen and (min-device-width: 650px)">

  <!-- Viewport is very important, since it affects results of media
        query matching. -->
  <meta name="viewport" content="width=device-width">

  <!-- Include device.js in each version for redirection. -->
  <script src="device.js"></script>

  <link rel="style" href="phone.min.css">
</head>
<body>
  <script src="phone.min.js"></script>
</body>

请注意,(touch-enabled: 0) 媒体查询是非标准的(只有 是在 Firefox 中通过 moz 供应商前缀实现的),但会进行处理。 通过 device.js 正确加载(得益于 Modernizr.touch)。

版本替换

设备检测功能有时可能会出错,在某些情况下 更喜欢查看手机上的平板电脑布局(或许他们 使用 Galaxy Note),因此请务必为用户提供 使用您网站的哪个版本。

通常的做法是,在您的应用程序中提供一个指向桌面版本的链接, 移动版。这很容易实现,但 device.js 支持 device GET 参数即可实现此功能。

总结

总而言之,在构建跨设备单页界面时 快速融入自适应设计的世界,请执行以下操作:

  1. 选择一组要支持的设备类别以及执行标准 对设备进行分类。
  2. 构建具有强有力关注点分离、拆分功能的 MVC 应用 从代码库的其余部分提取视图
  3. 使用 device.js 执行客户端设备类检测。
  4. 准备就绪后,将脚本和样式表打包为 每个设备类别
  5. 如果客户端重定向性能存在问题,请弃用 device.js 并切换到服务器端 UA 检测。