分离

在web应用开发中主要关注的有三种东西:

  • 内容

    即HTML文档

  • 表现

    指定文档样式的CSS

  • 行为

    JavaScript,用来处理用户交互和页面的动态变化

尽可能地将这三者分离可以加强应用在各种用户代理(译注:user agent,即为用户读取页面并呈现的软件,一般指浏览器)的可到达性(译注:delivery,指可被用户代理接受并理解的程度),比如图形浏览器、纯文本浏览器、用于残障人士的辅助技术、移动设备等等。分离常常是和渐进增强的思想一起实现的,我们从一个最基础的体验(纯HTML)开始,它将被用于最简单的用户代理,当用户代理的兼容性提升时再添加更多的可以为体验加分的东西。如果浏览器支持CSS,那么用户会看到文档更好的呈现。如果浏览器支持JavaScript,那文档会更像一个应用,有更多用来增强用户体验的特性。

在实践中,分离意味者:

  • 在关掉CSS的情况下测试页面,看页面是否仍然可用,内容是否可以呈现和阅读
  • 在关掉JavaScript的情况下测试页面,确保页面仍然可以完成它的主要功能,所有的链接都可以正常工作(没有href=”#”的链接),表单仍然可以正常填写和提交
  • 不要使用内联的事件处理(如onclick)或者是内联的style属性,因为它们不属于内容层
  • 使用语义化的HTML元素,比如头部和列表等

JavaScript(行为)层的地位不应该很显赫,也就是说它不应该成为页面正常工作必须依赖的东西,不应该使得用户在使用不支持的浏览器操作时存在障碍。它只应该被用来增强页面。

通常比较优雅的用来处理浏览器差异的方法是特性检测,它的思想是你不应该使用浏览器类型检测来决定代码的逻辑,而是应该检测在当前环境中你需要使用的某个方法或者是属性是否存在。浏览器检测一般认为是一种“反模式”,虽然有的情况下不可避免要使用,但它应该是最后才考虑的选择,并且应该只在特性检测没有办法给出明确答案(或者造成明显性能问题)的时候使用:

  1. // 反模式
  2. if (navigator.userAgent.indexOf('MSIE') !== 1) {
  3. document.attachEvent('onclick', console.log);
  4. }
  5. // 更好的方式
  6. if (document.attachEvent) {
  7. document.attachEvent('onclick', console.log);
  8. }
  9. // 或者还可以再具体一点
  10. if (typeof document.attachEvent !== "undefined") {
  11. document.attachEvent('onclick', console.log);
  12. }

分离也有助于开发、维护,减少升级一个现有应用的难度,因为当出现问题的时候,你知道去看哪一块。当出现一个JavaScript错误的时候,你不需要去看HTML或者是CSS就能修复它。