web前端主要技术概述

参考资料:
2018 Web 开发者路线图
2017年前端框架、类库、工具大比拼

本文主要是介绍部分主流和新兴的web前端技术,希望能帮助想学web前端的小白,理清其技术学习路线。

首先有些技能是web前端需要掌握的:

接下来,先看下要介绍的内容大纲:

这里写图片描述
web前端的基础技术就是html、css和js,而html的进阶就是jade,css的进阶就是scss,js的进阶就是es6、coffeescript和typescript。

而做个web项目的话,你就需要使用框架来帮助你快速开发,依赖的框架多了,就需要构建/管理工具来管理依赖的模块。

你的代码不只是写给你自己看,也是写给别人看,所以你的代码编写必须符合一定的规范。项目的目录结构,文件命名这些也是有着一定的规范的。

下面,就开始一个个地进行详细介绍。

html5

这里写图片描述

HTML(HyperText Markup Language)超文本标记语言,一种用于创建网页的标准标记语言。

HTML5是HTML的升级,设计目的是为了在移动设备上支持多媒体。HTML5广义上来说包含了html5、css和JavaScript三个部分。

HTML5对比HTML,除了标签语义化、新增了些多媒体元素和表单元素外,其绘图功能可以实现各种图表,Storage和webSQL可以实现本地离线存储,还有些新API可以实现特殊需求。

HTML5学习资料:

激活状态判断API加video元素示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>visibilityState</title>
    <script src="../lib/jquery/dist/jquery.min.js"></script>
</head>
<body>
<h4>visibilityState</h4>
<p>
    这是一个HTML5新提供的一个api,主要作用就是记录当前标签页在浏览器中的激活状态。
    所谓“激活状态”指的是当前标签是否正在被用户浏览。
</p>
<h4>应用场景</h4>
<p>
    监控用户行为,当用户的视角不在当前页面时,暂停加载广告,幻灯片、停止加载视频、
    开始加载小动画等。减少对用户宽带的占用,减少服务器压力,节省用户内存,
    以及到达更好的播放效果。
</p>

<video id="video1" width="420" controls>
    <source src="http://www.runoob.com/try/demo_source/mov_bbb.mp4" type="video/mp4">
    <source src="http://www.runoob.com/try/demo_source/mov_bbb.ogg" type="video/ogg">
    您的浏览器不支持 HTML5 video 标签。
</video>
<script>
    var myVideo = document.getElementById("video1");
    myVideo.play();
    document.addEventListener("visibilitychange", function () {
        if (document.visibilityState == "visible") {
            //do something
            //继续视频播放
            myVideo.play();
        }
        if (document.visibilityState == "hidden") {
            //do something else
            //暂停视频播放
            myVideo.pause();
        }
    });

</script>
</body>
</html>

在浏览器中查看此html,切换到另一个页面,视频会停止播放,切换回来,则视频会继续播放。注意:需要引入jquery。

jade

Jade是编写HTML模板的简洁语言,简称模板引擎,其实就是 HTML 预处理语言,非常类似 Sass 之于 CSS。其特点如下:

  • 生成HTML
  • 支持动态代码:if、case、each、while
  • 支持可重用性(DRY):mixins、includes、extends、block
  • 采用对缩进敏感的语法形式,提高了可读性,省略了一些界定符号(大括号、尖括号……)

pug其实就是jade,只是名称不一样而已。

对于中大型项目来说,具有可重用性的jade是可以节省html页面编写时间的。

下面是一些简单的生成列表的示例:

1. 理解缩进风格和尖括号的省略

ul
  li Item A
  li Item B
  li Item C

对应的HTML

<ul>
  <li>Item A</li>
  <li>Item B</li>
  <li>Item C</li>
</ul>

2. 通过each理解动态代码

ul
  each val, index in ['zero', 'one', 'two']
    li= index + ': ' + val

对应的HTML

<ul>
  <li>0: zero</li>
  <li>1: one</li>
  <li>2: two</li>
</ul>

3. 通过mixins理解可重用性

mixin list(id, ...items)
  ul(id=id)
    each item in items
      li= item

+list('my-list', 1, 2, 3, 4)

对应的HTML

<ul id="my-list">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
</ul>

通过includes可导入其他代码页面;通过extends可继承代码片段,利用 block替换代码片段,append 在原有代码片段之后追加,prepend 在原有代码片段之前追加。

css3

CSS(**C**ascading **S**tyle **S**heets)层叠样式表,定义如何显示HTML 元素。

这里写图片描述

上图列出了CSS3的主要技术点。这里主要介绍下精灵图片。

CSS精灵图是把一系列图片放到一张图上。这样可以减少请求数因而网页加载更快。CSS会把每个图标移动到正确位置。但是精灵图的缺点就是图片大小是固定的,被拉伸后可能会失真。

使用gulp生成sprites图片和样式表

SCSS

SASS是CSS的预处理语言。SASS采用缩进风格,不支持{}语法,而为了向下兼容CSS语法,SCSS被开发出来。下图列出了SCSS的主要语法点。

这里写图片描述

下面是部分语法的示例和说明:

1. 通过变量可统一某个样式

局部变量 & 全局变量(3.4+)

$color: orange !default;//定义全局变量
.block {
  color: $color;//调用全局变量
}
em {
  $color: red;//定义局部变量(全局变量 $color 的影子)
  a {
    color: $color;//调用局部变量
  }
}

对应的CSS

.block {
  color: orange;
}
em a {
  color: red;
}

2. 理解嵌套

原先我们需要一层层的指明样式作用的对象,可读性差,但通过嵌套,可以清晰地看出选择器的层级。

nav {
  a {
    color: red;

    header & {
      color:green;
    }
  }
}

对应的CSS

nav a {
  color:red;
}
header nav a {
  color:green;
}

3. css与scss @import区别:

  • css 只有执行到@import时,浏览器才会去下载其他css文件,这导致页面加载起来特别慢。

  • scss的@import规则在生成css文件时就把相关文件导入进来。这意味着所有相关的样式被归纳到了同一个css文件中,而无需发起额外的下载请求。另外,所有在被导入文件中定义的变量和混合宏均可在导入文件中使用。

4. 理解可复用性

$list: adam john wynn mason kuroir;//$list 就是一个列表

@mixin author-images {
    @each $author in $list {
        .photo-#{$author} {
            background: url("/images/avatars/#{$author}.png") no-repeat;
        }
    }
}
.author-bio {
    @include author-images;
}

生成的CSS

.author-bio  .photo-adam  { background: url("/images/avatars/adam.png") no-repeat; }  .author-bio  .photo-john  { background: url("/images/avatars/john.png") no-repeat; }  .author-bio  .photo-wynn  { background: url("/images/avatars/wynn.png") no-repeat; }  .author-bio  .photo-mason  { background: url("/images/avatars/mason.png") no-repeat; }  .author-bio  .photo-kuroir  { background: url("/images/avatars/kuroir.png") no-repeat; }

你可能也听说过其他css预处理语言,如less、stylus等,这里介绍篇不错的文章:表析LESS、Sass和Stylus的异同

在了解scss后,你可以再看看Compass。Sass本身只是一个编译器,Compass在它的基础上,封装了一系列有用的模块和模板,补充Sass的功能。它们之间的关系,有点像Javascript和jQuery的关系。简单说,Compass是Sass的工具库(toolkit)。

jade和scss实例

这里展示一个手风琴效果的例子

这里写图片描述

jade:

doctype
html(lang='en')
    head
        meta(charset='UTF-8')
        title 纯CSS实现手风琴效果
        link(rel='stylesheet', type='text/css', href='../css/app.css')
    body
        .accordian
            -
                var data=[
                    {'link_title':'KungFu Panda', 'link_img':'http://thecodeplayer.com/uploads/media/3yiC6Yq.jpg'},
                    {'link_title':'Toy Story 2', 'link_img':'http://thecodeplayer.com/uploads/media/40Ly3VB.jpg'},
                    {'link_title':'Wall-E', 'link_img':'http://thecodeplayer.com/uploads/media/00kih8g.jpg'},
                    {'link_title':'Up', 'link_img':'http://thecodeplayer.com/uploads/media/8k3N3EL.jpg'},
                    {'link_title':'Cars 2', 'link_img':'http://thecodeplayer.com/uploads/media/2rT2vdx.jpg'}
                ]
            ul
                each item in data
                    li
                        .image_title
                            a(href='#') #{item.link_title}
                        a(href='#')
                            img(src=item.link_img)

编写gulp任务将jade编译成html:

var gulp = require('gulp');
var jade = require('gulp-jade');
// 创建jade编译任务
gulp.task('jade', function () {
    gulp.src('src/**/*.jade')
        .pipe(jade({
            pretty: true
        }))
        .pipe(gulp.dest('www'));
});

最终生成的html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>纯CSS实现手风琴效果</title>
    <link rel="stylesheet" type="text/css" href="../css/app.css">
  </head>
  <body>
    <div class="accordian">
      <ul>
        <li>
          <div class="image_title"><a href="#">KungFu Panda</a></div><a href="#"><img src="http://thecodeplayer.com/uploads/media/3yiC6Yq.jpg"></a>
        </li>
        <li>
          <div class="image_title"><a href="#">Toy Story 2</a></div><a href="#"><img src="http://thecodeplayer.com/uploads/media/40Ly3VB.jpg"></a>
        </li>
        <li>
          <div class="image_title"><a href="#">Wall-E</a></div><a href="#"><img src="http://thecodeplayer.com/uploads/media/00kih8g.jpg"></a>
        </li>
        <li>
          <div class="image_title"><a href="#">Up</a></div><a href="#"><img src="http://thecodeplayer.com/uploads/media/8k3N3EL.jpg"></a>
        </li>
        <li>
          <div class="image_title"><a href="#">Cars 2</a></div><a href="#"><img src="http://thecodeplayer.com/uploads/media/2rT2vdx.jpg"></a>
        </li>
      </ul>
    </div>
  </body>
</html>

scss:

//图像个数
$imageN: 5;
//图像hover之前的总宽度
$w: 800px;
//图像hover之后的宽度
$imageL: 640px;
//图像hover之前的宽度
$imageS: $w/$imageN;
//边框宽度
$bdWidth: 2px;
//阴影宽度
$shadowWidth: 20px;
.accordian {
  width: $w + $bdWidth * $imageN + $shadowWidth*2;
  margin: 100px auto;

  ul li {
    float: left;
    list-style: none;
    width: $imageS;
    transition: all 2s;
    position: relative;
    overflow: hidden;
    border-left: 1px solid rgba(255, 255, 255, .8);
    border-left-width: $bdWidth;
    box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.8);

    .image_title {
      position: absolute;
      width: 100%;
      height: 50px;
      background-color: rgba(0, 0, 0, .5);
      text-indent: 2em;
      line-height: 50px;
      bottom: 0px;
      left: 0;

      a {
        color: #fff;
        text-decoration: none;
      }
    }
  }

  ul:hover li {
    width: $imageS - $imageL/$imageN;
    -webkit-filter: grayscale(.8);
    filter: grayscale(.8);
  }

  ul li:hover {
    width: $imageL;
    -webkit-filter: grayscale(0) hue-rotate(300deg);
    filter: grayscale(0) hue-rotate(300deg);
  }
}

编写gulp任务将scss编译成css:

var gulp = require('gulp'),
    sass = require('gulp-sass'),
    csso = require('gulp-csso'),
    rename = require('gulp-rename'),
    concat = require('gulp-concat');

// 创建sass编译任务
gulp.task('sass', function () {
    gulp.src('src/**/*.scss')
        .pipe(concat('app.scss')) // 合并所有的scss到一个文件中
        .pipe(sass())
        .pipe(gulp.dest('www/css'))
        .pipe(rename({suffix: '.min'}))
        .pipe(csso())   // 压缩
        .pipe(gulp.dest('www/css'));
});

编译后生成的css:

.accordian {
  width: 850px;
  margin: 100px auto; }
  .accordian ul li {
    float: left;
    list-style: none;
    width: 160px;
    transition: all 2s;
    position: relative;
    overflow: hidden;
    border-left: 1px solid rgba(255, 255, 255, 0.8);
    border-left-width: 2px;
    box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.8); }
    .accordian ul li .image_title {
      position: absolute;
      width: 100%;
      height: 50px;
      background-color: rgba(0, 0, 0, 0.5);
      text-indent: 2em;
      line-height: 50px;
      bottom: 0px;
      left: 0; }
      .accordian ul li .image_title a {
        color: #fff;
        text-decoration: none; }
  .accordian ul:hover li {
    width: 32px;
    -webkit-filter: grayscale(0.8);
    filter: grayscale(0.8); }
  .accordian ul li:hover {
    width: 640px;
    -webkit-filter: grayscale(0) hue-rotate(300deg);
    filter: grayscale(0) hue-rotate(300deg); }

作为一个前端工程师,html和css是基础中的基础,如果你连页面都无法实现,能算是前端工程师吗?而且,一定自己动手多写些html和css,才能对页面的布局有所体会,理解如何“切豆腐”。

js

JavaScript 是 Web 的编程语言。

这里写图片描述

对于JS,你需要重点掌握:

  • 数据类型:JavaScript 中的所有事物都是对象:字符串、数值、数组、函数…重点要理解函数定义、函数声明式。
  • 变量提升:var关键字声明变量。无论声明在何处,都会被视为声明在函数的最顶部(不在函数内即在全局作用域的最顶部)。
  • 函数式编程:如数组的sort、reduce、map等操作。
  • 闭包:闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。闭包使得函数拥有私有变量变成可能。
  • 继承:可以了解下JS实现继承的几种方式
  • DOM:通过 HTML DOM(Document Object Model),可访问 JavaScript HTML 文档的所有元素和创建动态的HTML。可重点了解JS Event对象详解
  • BOM:浏览器对象模型 (BOM) 使 JavaScript 有能力与浏览器”对话”。需要掌握计时事件(timeoutinterval)和三种弹窗(alertcomfirmprompt)的使用。
  • AJAX:AJAX (Asynchronous JavaScript and XML,异步的 JavaScript 和 XML) 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
  • 异步编程:Javascript异步编程的4种方法
  • 执行机制:js执行机制

js的进阶

es6

ECMAScript 6.0(简称 ES6)是 JavaScript 语言的下一代标准。ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现。

ES6的一些新特性真的非常激动人心:变量声明const和let,模板字符串(``,${}),扩展的函数功能(函数默认参数,rest参数,箭头函数),拓展的对象功能(简写,属性名表达式),解构赋值,展开运算符...,Set和Map,模块,Promise,Class等。

这里推荐一篇不错的文章:Excuse me?这个前端面试在搞事!

setTimeout(function() {
  console.log(1)
}, 0);
new Promise(function executor(resolve) {
  console.log(2);
  for( var i=0 ; i<10000 ; i++ ) {
    i == 9999 && resolve();
  }
  console.log(3);
}).then(function() {
  console.log(4);
});
console.log(5);

要理解这道题,你需要知道js的运行机制和es6的Promise

推荐一定要在学习js后,学习es6,然后再去学习coffeescript和typescript。因为,第一,无论你学不学coffeescript和typescript,es6 是 js的下一代标准,正在被逐渐推广使用中;第二,coffeescript和typescript与es6有很多相似的语法,学习了es6后,再去学习coffeescript和typescript会轻松得多。

coffeescript

CoffeeScript 是一门编译到 JavaScript 的小巧语言。CoffeeScript其实就是js的「语法糖」,可以让代码的读写更简单。

下面是官方的例子:

# 赋值:
number   = 42
opposite = true

# 条件:
number = -42 if opposite

# 函数:
square = (x) -> x * x

# 数组:
list = [1, 2, 3, 4, 5]

# 对象:
math =
  root:   Math.sqrt
  square: square
  cube:   (x) -> x * square x

# Splats:
race = (winner, runners...) ->
  print winner, runners

# 存在性:
alert "I knew it!" if elvis?

# 数组 推导(comprehensions):
cubes = (math.cube num for num in list)
var cubes, list, math, num, number, opposite, race, square,
  __slice = [].slice;

number = 42;

opposite = true;

if (opposite) {
  number = -42;
}

square = function(x) {
  return x * x;
};

list = [1, 2, 3, 4, 5];

math = {
  root: Math.sqrt,
  square: square,
  cube: function(x) {
    return x * square(x);
  }
};

race = function() {
  var runners, winner;
  winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  return print(winner, runners);
};

if (typeof elvis !== "undefined" && elvis !== null) {
  alert("I knew it!");
}

cubes = (function() {
  var _i, _len, _results;
  _results = [];
  for (_i = 0, _len = list.length; _i < _len; _i++) {
    num = list[_i];
    _results.push(math.cube(num));
  }
  return _results;
})();
typescript

typescript是JavaScript的一个超集,扩展了JavaScript的语法。TypeScript 通过类型注解提供编译时的静态类型检查。

function area(shape: string, width: number, height: number) {
    var area = width * height;
    return "I'm a " + shape + " with an area of " + area + " cm squared.";
}

document.body.innerHTML = area("rectangle", 30, 15);

上面只是一个简单的例子,更多关于typescript的语法请查看TypeScript 中文手册

框架

这里写图片描述

我将框架分成样式组将类框架和js库框架。这里只是简单介绍下,不做深入介绍,只有真的去实战,才能切实掌握这些框架。

样式组件类框架:

  • bootstrap:使用最广泛的web框架。bootstrap现在最新版本是Bootstrap4,与 Bootstrap3 相比拥有了更多的具体的类以及把一些有关的部分变成了相关的组件。同时 Bootstrap.min.css 的体积减少了40%以上。Bootstrap4 放弃了对 IE8 以及 iOS 6 的支持,现在仅仅支持 IE9 以上 以及 iOS 7 以上版本的浏览器。如果对于其中需要用到以前的浏览器,那么请使用 Bootstrap3。
  • foundation:最先进的响应式框架。
  • semanticUI:创新性地采用自然语言处理技术的web框架。不过这个框架尚在发展,目前它的安装方式还没有前两者方便。

js库框架:

  • jquery:html的元素操作、js特效和动画效果、css操作、html事件操作、ajax异步请求方式。jquery可以说是js的语法糖,读写很方便。
  • react:一个用于构建用户界面的js库。如果是复杂应用的话,就需要使用Redux.
  • angularjs:通过新的属性和表达式扩展了HTML
  • vuejs:一套构建用户界面的渐进式框架。如果是复杂应用的话,就需要使用vuex.
  • angularjs2:用来协助单一页面应用程序运行,基于ES6来开发的。

构建/管理工具

这里写图片描述

npmbower基本上是用来管理模块,两者的用法基本相同。如果你是要安装开发依赖的模块而不是生产使用的模块的话,推荐使用npm来安装模块,被安装的模块默认在node_modules文件夹下。如果你要安装生产使用的模块(会被放在www下),推荐使用bower,因为你可以很方便地指定你模块安装的位置。

gulpwebpackparcel都是打包工具。

gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器。gulp是基于Nodejs的自动任务运行器, 她能自动化地完成 javascript/coffee/sass/less/html/image/css 等文件的的测试、检查、合并、压缩、格式化、浏览器自动刷新、部署文件生成,并监听文件在改动后重复指定的这些步骤。

Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。

Parcel 是一个Web应用程序 打包器(bundler) ,与以往的开发人员使用的打包器有所不同。它利用多核处理提供极快的性能,并且你不需要进行任何配置。

规范

规范是很重要的,如果你一开始就遵循并统一文件命名规范和相应技术的代码规范的话,那么在进行代码检查的时候,你就不会有语法不规范的低级错误了。

这里我列出了我已知的规范内容:

前端编码规范
AngularJS风格指南
Airbnb JavaScript 代码规范(ES6)

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐