定时器

定时器基础

1
2
3
4
5
6
7
8
9
var timer1 = setTimeout(function(){

}, 1000);
console.log(timer1); //=> 1

var timer2 = setInterval(function(){

}, 1000);
console.log(timer2); //=> 2
  • 定时器的返回值: 当我们设置定时器(不管是setTimeout还是setInterval),都会有一个返回值,返回值是一个数字,代表当前实在浏览器中设置的第几个定时器(返回的是定时器序号)
  • setTimeout和setInterval虽然是处理不同需求的定时器,但是都是浏览器的定时器,所以设置的时候,返回的序号是依次排列的
  • setInterval设置完成定时器会有一个返回值,不管执行多少次,这个代表序号的返回值不变(设置定时器就有返回值,执行多少次是定时器的处理)

清除定时器

  • clearTimeout([定时器排队序号])
  • clearInterval([定时器排队序号])
  • 定时器需要手动清除
1
2
3
4
5
6
var t1 = setTimeout(function(){
//=> 当方法执行完成后,定时器没用了,我们清除定时器即可
//=> clearTimeout(t1);
clearInterval(t1); //=> 使用它也可以清除掉
t1 = null; //=> 我们手动把之前存储序号的变量赋值为null
}, 1000);

实现动画效果

1
2
3
4
5
6
7
8
9
10
11
12
function imgFade(curImg){
var n = 0;
var timer = setInterval(function(){
if(n > 1){
clearInterval(timer);
timer = null;
return;
}
n += 0.05;
utils.css(curImg, 'opacity', n);
}, 17); //=> 17ms是执行定时器动画相对比较理想的时间间隔
}

JS中的同步和异步编程

JS是单线程的(一次只能执行一个任务,当前任务没有完成,下面任务不进行处理)

同步编程(sync:synchronize):任务是按照顺序一件件的完成的,当前任务没有完成,下面的任务部进行处理

异步编程(async)当前任务再等待执行的时候,我们不去执行,继续完成下面的任务,当下面的任务完成后,而是也到达等待的时间了,采取完成当前的任务

定时器都是异步编程的

所有的时间绑定都是异步编程的

AJAX中有异步编程

有些人把回调函数当作异步编程(牵强)

1
2
3
4
5
6
7
8
9
//=> 同步编程以及如何验证当前任务小号的时间或者性能
var startTime = new Date();
for(var i = 0; i < 1000000; i += 1){
if(i === 999999){
console.log('no');
}
}
console.log(new Data() - startTime);
console.log('ok');
1
2
3
//=> 项目中要避免死循环,因为循环是同步编程,当前循环无法结束,后续的任务操作都执行不了
while(1===1){}
console.log(1);
1
2
3
4
5
6
var n = 0;
setTimeout(function(){
n++;
console.log(n);
}, 1000);
console.log(n);

同步异步编程的核心原理

  • JS中有两个任务队列(存放任务列表的空间就是任务队列)
  • 1、主任务队列:同步执行任务(从上到下一次执行)
    2、等待任务队列:异步执行任务(主任务队列中的任务全部完成,把等待任务队列中的任务拿到主任务队列中执行(哪一个先到,先找哪一个,同时到,按照创建顺序来),当前这个任务完成后,再到等待中去找其他任务)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
setTimeout(function(){
console.log(1);
}, 50);

setTimeout(function(){
console.log(2);
}, 10);

setTimeout(function(){
console.log(3);
}, 30);

for(var i = 0; i < 100000000; i += 1){
if(i === 99999999){
console.log(4);
}
};
console.log(5);

JS中固定步长和固定时间的匀速运动动画

1、步长固定(每走一步多少固定),但是多长时间运动完成不固定

1
2
3
4
5
6
7
8
9
10
11
12
13
var oBox = document.getElementById('box'),
target = document.documentElement.clientWidth - oBox.offsetWidth;
//=> 动画:每隔一段时间都在自己原有的left基础上累加步长10排序,一直到达目标值结束
var timer = setInterval(function(){
var curL = oBox.offsetLeft;
curL += 10;
oBox.style.left = curL + 'px';
if(curL >= target){
oBox.style.left = target + 'px';
clearInterval(timer);
timer = null;
}
}, 17);

2、固定时间的匀速动画

  • target: 目标值
  • start: 起始值
  • change:总距离 target-start
  • duration: 总时间
  • time:已经运动的时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function linear(time, begin, change, duration){
return time/duration*change + begin
}
var oBox = document.getElementById('box'),
time = 0,
duration = 1000,
begin = parseInt(getComputedStyle(oBox).left),
target = document.documentElement.clientWidth - oBox.offsetWidth,
change = target - begin;

var timer = setInterval(function(){
time += 17;
var curL = linear(time, begin, change, duration);
if(time >= duration){
clearInterval(timer);
timer = null;
curL = target;
}
oBox.style.left = curL + 'px';
}, 17);

多方向固定时间匀速运动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}

html, body {
width: 100%;
height: 100%;
}

.box {
width: 100px;
height: 100px;
position: absolute;
left: 0;
top: 0;
background: #ff6700;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
var box = document.getElementsByClassName('box')[0];
var time = 0,
duration = 1000;
var begin = {
left: box.offsetLeft,
top: box.offsetTop,
opacity: 1
};
var target = {
left: document.body.clientWidth - box.offsetWidth,
top: document.body.clientHeight - box.offsetHeight,
opacity: 0.2
};
var change = {};
for(var key in target){
if(target.hasOwnProperty(key)){
change[key] = target[key] - begin[key];
}
}

function linear(t, b, c, d){
return t / d * c + b;
}

box.timer = setInterval(function(){
if(time >= duration-17){
box.style.left = target.left + 'px';
box.style.top = target.top + 'px';
clearInterval(box.timer);
return;
}
time += 17;
var curPos = {};
for(var key in change){
curPos[key] = linear(time, begin[key], change[key], duration);
}

for(var key in curPos){
if(key !== 'opacity'){
box.style[key] = curPos[key] + 'px';
}else{
box.style[key] = curPos[key];
}

}
}, 17)
</script>
</body>
</html>

webpack使用攻略

安装相关包

tips:
网络不好,请使用淘宝镜像安装

1
npm install -g cnpm --registry=https://registry.npm.taobao.org

开始安装

webpack模块

1
npm install webpack webpack-cli webpack-dev-server --save-dev

JavaScript模块

tips:
这里由于版本兼容性问题,babel-loader我安装的版本是7.1.5

  • babel-core 和 babel-loader 充当的就是翻译官的角色,用来解析代码中的js代码
  • babel-preset-env 和 babel-preset-stage-0 是告诉翻译官,要把js解析成 es5 还是 es7
1
npm install babel-core babel-loader@7.1.5 babel-preset-env babel-preset-stage-0 --save-dev

css模块

tips: 要解析什么类型的css文件就安装对应的loader即可

  • css-loader 解析css代码
  • style-loader 将css解析的代码以style标签引入到页面中
  • less 和 less-loader 解析less
1
npm install style-loader css-loader less less-loader --save-dev

图片模块

tips: url-loader 依赖于 file-loader
所以两个都需要安装

1
npm install file-loader url-loader --save-dev

html模块

1
2
3
4
5
6
7
npm install html-webpack-plugin --save-dev
```

#### vue模块

> tips:
> 这里我是用vue写页面,所以安装vue相关依赖

npm install vue vue-cli vue-loader vue-template-compiler

1
2
3
4
5


### 配置文件

#### webpack.config.js

let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
  mode: 'development',
  entry: './src/main.js',
  output: {
      filename: 'bundle.js',
      path: path.resolve('./dist')
  },
  module: {
      rules: [
          {test: /\.js$/, use: 'babel-loader', exclude: /node_module/},
          {test: /\.css$/, use: ['style-loader', 'css-loader']},
          {test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']},
          {test: /\.(jpg|png|gif|jpeg)/, use: 'url-loader?limit=8192'},
          {test:/\.vue$/, use: 'vue-loader'}
      ]
  },
  plugins: [
      new HtmlWebpackPlugin({
          template: './src/index.html'
      }),
      new VueLoaderPlugin()
  ]
};
1
2

#### npm init 生成的package.json文件
{
  "name": "webpack-vue",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-env": "^1.7.0",
    "babel-preset-stage-0": "^6.24.1",
    "css-loader": "^1.0.0",
    "file-loader": "^2.0.0",
    "html-webpack-plugin": "^3.2.0",
    "less": "^3.8.1",
    "less-loader": "^4.1.0",
    "style-loader": "^0.23.0",
    "url-loader": "^1.1.1",
    "vue-loader": "^15.4.1",
    "vue-template-compiler": "^2.5.17",
    "webpack": "^4.17.2",
    "webpack-cli": "^3.1.0",
    "webpack-dev-server": "^3.1.7"
  }
}
1
2

#### js配置 .babelrc文件
{
  "presets": ["env", "stage-0"]
}

`