前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • JavaScript Part 1

    • Ajax总结篇
    • Canvas 绘制八大行星
    • DOM编程之API学习总结篇
    • JavaScript事件机制
    • JavaScript代码片段100个
    • JavaScript作用域分析总结
    • JavaScript原型链回顾
    • JavaScript及jQuery中的各种宽高属性图解
    • JavaScript工程项目的一系列最佳实践
    • JavaScript常用API合集
    • JavaScript数组、字符串、对象常用方法
    • JavaScript数组方法总结篇
    • JavaScript深浅拷贝
    • JavaScript运动框架之速度时间版本
    • JavaScript运行机制Event Loop
    • JavaScript防抖节流原理
    • Javascript中的复制粘贴功能
    • Javascript数组详解
    • OOP之原型与原型链
    • Object.defineProperty详解
    • V8源码浅析JS数组常见方法
    • await 在 forEach 中不生效解决方案
    • iframe+表单跨域提交POST请求
    • javascript笔记总结篇
    • 业务中处理数据结构常用的JS方法
    • 作用域
    • 你真的掌握变量和类型了吗
    • 前后端分离之数据Mock
    • 原型与原型链
    • 原生JS补给(上)
    • 如何写出一个惊艳面试官的深拷贝
    • 带你填一些JS容易出错的坑
    • 彻底弄懂 JavaScript 执行机制
    • 执行上下文 执行栈
    • 正则回顾总结
    • 正则基础知识
    • 正则完整篇
    • 正则表达式
    • 浅析Promise原理
    • 浅谈JavaScript中的异步处理
    • 深拷贝 vs 浅拷贝
    • 聊一聊typeof instanceof 实现原理.
    • 聊一聊闭包
    • 高阶函数map reduce filter
  • JavaScript Part 2

  • CSS

  • HTML

  • Jquery

  • ES6

  • 小程序

  • Vue

  • React

  • 深入React

  • React Native

  • NodeJS

  • Angular

  • TypeScript

  • Webpack

  • 浏览器

  • 移动端

  • 前端工程化

  • Electron

  • HTTP

  • Nginx

  • Linux

  • 数据结构与算法

  • LeetCode算法题

  • 综合

# 一、JavaScript运动框架之速度版


# 1.1 运动框架的实现思路


运动,其实就是在一段时间内改变 left 、 right 、 width 、 height 、 opactiy 的值,到达目的地之后停止

  • 位移 top,left

  • 折叠 width,height

  • 淡入淡出 opacity

  • 时间有关系

    • setInterval
    • setTimeout
  • 用javascript直接获取行间样式很容易,但如果要获取非行间样式那我们只能借助函数了。我这里编写了一个名为getStyle的函数,专门处理取非行间的样式

function getStyle(obj,attr){
	return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
@前端进阶之旅: 代码已经复制到剪贴板

# 1.2 一些案例演示


# 1.2.1 运动之速

<div id="box"></div>
@前端进阶之旅: 代码已经复制到剪贴板
#box {
	width: 100px;
	height: 100px;
	background: red;
	 position: relative;
	left: 0;
}
@前端进阶之旅: 代码已经复制到剪贴板
var box = document.getElementById("box");
var speed = 0; //步长
var target = 600;
var timer = null;
timer = setInterval(function(){
	var curr = parseInt(getStyle(box,"left")); //去除getStyle(box,"left")的单位
	if(curr == target){
		clearInterval(timer);
		speed = 0;
		alert("运动结束");
	}else{
		speed +=10;
		box.style.left = speed + "px";
	}
	

},1000/30);

//监控left的值的变化 怎么样拿到left的值
//alert(getComputedStyle(box)["width"]);
//alert(box.currentStyle["left"]);
// currentStyle --IE 
// getComputedStyle -- 非IE

function getStyle(obj,attr){
	return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
@前端进阶之旅: 代码已经复制到剪贴板

在线演示

# 1.2.2 运动速度之封装1

<div id="ball"></div>
@前端进阶之旅: 代码已经复制到剪贴板
#ball {
	width: 100px;
	height: 100px;
	background: blue;
}
@前端进阶之旅: 代码已经复制到剪贴板
var ball = document.getElementById("ball");

ball.onmouseover = function(){
	//同时变换 用的最多
	//move(this,"width",500,10);
	//move(this,"height",500,10);
	move(ball,{"width":400,"height":300},10);
}
ball.onmouseout = function(){
	//move(this,"width",100,-10);
	//move(this,"height",100,-10);
	move(ball,{"width":100,"height":100},-10);
}
function move(obj,json,speed){
	clearInterval(obj.timer);
	var mark = true;
	obj.timer = setInterval(function(){
		for(var attr in json){
			var curr = parseInt(getStyle(obj,attr));
			var target = json[attr];
			if(curr != target){
				obj.style[attr] = curr+speed+"px";
				mark = false;
		  }
		}
		if(mark){
			clearInterval(obj.timer);
		}
	},1000/30);
}


function getStyle(obj,attr){
	return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
@前端进阶之旅: 代码已经复制到剪贴板
  • 需要注意的地方
    • 当需要两个动画的时候,会执行后面一个,解决办法如下,回调函数
    • 当需要两个以上的时候,需要考虑是否可写一行代码变换多个属性
    • 变换不一致的时候,定时器被提前清除

在线演示

# 1.2.3 运动速度之封装2–增加opacity
<div id="ball"></div>
@前端进阶之旅: 代码已经复制到剪贴板
#ball {
  position: relative;
  left: 0;
  top: 0;
  width: 100px;
  height: 100px;
  background: blue;
  opacity: 1;
}
@前端进阶之旅: 代码已经复制到剪贴板
var ball = document.getElementById("ball");
ball.onmouseover = function(){
	move(ball,{"width":300,"height":300,"opacity":0.3});
}
//			ball.onmouseout = function(){
//				move(ball,{"width":100,"height":100},-10);
//			}
function move(obj,json){
	clearInterval(obj.timer);
	var mark = true;
	obj.timer = setInterval(function(){
		for(var attr in json){
			var curr = null;
			var target = json[attr];
			var speed = null;
			if(attr == "opacity"){
				curr = getStyle(obj,attr)*100;
				speed = (target*100-curr)*0.15;
			}else {
				curr = parseInt(getStyle(obj,attr));
				speed = (target - curr)*0.15;
			}
			speed = speed>0 ? Math.ceil(speed):Math.floor(speed);
			if(curr != target){
				if(attr == "opacity"){
					obj.style[attr] = (curr+speed)/100;
				}else {
					obj.style[attr] = curr+speed+"px";
				}
				
				mark = false;
		  }
		}
		if(mark){
			clearInterval(obj.timer);
		}
	},1000/30);
}


function getStyle(obj,attr){
	return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
@前端进阶之旅: 代码已经复制到剪贴板

在线演示

  • 需要注意的地方
    • 当需要两个动画的时候,会执行后面一个,解决办法如下,回调函数
    • 当需要两个以上的时候,需要考虑是否可写一行代码变换多个属性
    • 变换不一致的时候,定时器被提前清除
    • 速度speed不要写死

# 1.3 运动框架之应用

# 1.3.1 分享按钮
<div id="ball"></div>
<div id="box1">
  <div id="box2">分享到</div>
</div>
@前端进阶之旅: 代码已经复制到剪贴板
var box1 = document.getElementById("box1");
var ball = document.getElementById("ball");

box1.onmouseover = function(){
  move(this,"left",0,10);
}
box1.onmouseout = function(){
  move(this,"left",-100,-10);
}
//问题一:当需要两个动画的时候,会执行后面一个,解决办法如下,回调函数
ball.onmouseover = function(){
  //同时变换 用的最多
  //move(this,"width",500,10);
  //move(this,"height",500,10);
  //列队在执行
  move(ball,"width",500,10,function(){
    move(ball,"height",500,10);
  });
}
ball.onmouseout = function(){
  
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • JavaScript Part 1

    • Ajax总结篇
    • Canvas 绘制八大行星
    • DOM编程之API学习总结篇
    • JavaScript事件机制
    • JavaScript代码片段100个
    • JavaScript作用域分析总结
    • JavaScript原型链回顾
    • JavaScript及jQuery中的各种宽高属性图解
    • JavaScript工程项目的一系列最佳实践
    • JavaScript常用API合集
    • JavaScript数组、字符串、对象常用方法
    • JavaScript数组方法总结篇
    • JavaScript深浅拷贝
    • JavaScript运动框架之速度时间版本
    • JavaScript运行机制Event Loop
    • JavaScript防抖节流原理
    • Javascript中的复制粘贴功能
    • Javascript数组详解
    • OOP之原型与原型链
    • Object.defineProperty详解
    • V8源码浅析JS数组常见方法
    • await 在 forEach 中不生效解决方案
    • iframe+表单跨域提交POST请求
    • javascript笔记总结篇
    • 业务中处理数据结构常用的JS方法
    • 作用域
    • 你真的掌握变量和类型了吗
    • 前后端分离之数据Mock
    • 原型与原型链
    • 原生JS补给(上)
    • 如何写出一个惊艳面试官的深拷贝
    • 带你填一些JS容易出错的坑
    • 彻底弄懂 JavaScript 执行机制
    • 执行上下文 执行栈
    • 正则回顾总结
    • 正则基础知识
    • 正则完整篇
    • 正则表达式
    • 浅析Promise原理
    • 浅谈JavaScript中的异步处理
    • 深拷贝 vs 浅拷贝
    • 聊一聊typeof instanceof 实现原理.
    • 聊一聊闭包
    • 高阶函数map reduce filter
  • JavaScript Part 2

  • CSS

  • HTML

  • Jquery

  • ES6

  • 小程序

  • Vue

  • React

  • 深入React

  • React Native

  • NodeJS

  • Angular

  • TypeScript

  • Webpack

  • 浏览器

  • 移动端

  • 前端工程化

  • Electron

  • HTTP

  • Nginx

  • Linux

  • 数据结构与算法

  • LeetCode算法题

  • 综合

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

JavaScript运动框架之速度时间版本|博客系列

# 一、JavaScript运动框架之速度版


# 1.1 运动框架的实现思路


运动,其实就是在一段时间内改变 left 、 right 、 width 、 height 、 opactiy 的值,到达目的地之后停止

  • 位移 top,left

  • 折叠 width,height

  • 淡入淡出 opacity

  • 时间有关系

    • setInterval
    • setTimeout
  • 用javascript直接获取行间样式很容易,但如果要获取非行间样式那我们只能借助函数了。我这里编写了一个名为getStyle的函数,专门处理取非行间的样式

function getStyle(obj,attr){
	return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
@前端进阶之旅: 代码已经复制到剪贴板

# 1.2 一些案例演示


# 1.2.1 运动之速

<div id="box"></div>
@前端进阶之旅: 代码已经复制到剪贴板
#box {
	width: 100px;
	height: 100px;
	background: red;
	 position: relative;
	left: 0;
}
@前端进阶之旅: 代码已经复制到剪贴板
var box = document.getElementById("box");
var speed = 0; //步长
var target = 600;
var timer = null;
timer = setInterval(function(){
	var curr = parseInt(getStyle(box,"left")); //去除getStyle(box,"left")的单位
	if(curr == target){
		clearInterval(timer);
		speed = 0;
		alert("运动结束");
	}else{
		speed +=10;
		box.style.left = speed + "px";
	}
	

},1000/30);

//监控left的值的变化 怎么样拿到left的值
//alert(getComputedStyle(box)["width"]);
//alert(box.currentStyle["left"]);
// currentStyle --IE 
// getComputedStyle -- 非IE

function getStyle(obj,attr){
	return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
@前端进阶之旅: 代码已经复制到剪贴板

在线演示

# 1.2.2 运动速度之封装1

<div id="ball"></div>
@前端进阶之旅: 代码已经复制到剪贴板
#ball {
	width: 100px;
	height: 100px;
	background: blue;
}
@前端进阶之旅: 代码已经复制到剪贴板
var ball = document.getElementById("ball");

ball.onmouseover = function(){
	//同时变换 用的最多
	//move(this,"width",500,10);
	//move(this,"height",500,10);
	move(ball,{"width":400,"height":300},10);
}
ball.onmouseout = function(){
	//move(this,"width",100,-10);
	//move(this,"height",100,-10);
	move(ball,{"width":100,"height":100},-10);
}
function move(obj,json,speed){
	clearInterval(obj.timer);
	var mark = true;
	obj.timer = setInterval(function(){
		for(var attr in json){
			var curr = parseInt(getStyle(obj,attr));
			var target = json[attr];
			if(curr != target){
				obj.style[attr] = curr+speed+"px";
				mark = false;
		  }
		}
		if(mark){
			clearInterval(obj.timer);
		}
	},1000/30);
}


function getStyle(obj,attr){
	return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
@前端进阶之旅: 代码已经复制到剪贴板
  • 需要注意的地方
    • 当需要两个动画的时候,会执行后面一个,解决办法如下,回调函数
    • 当需要两个以上的时候,需要考虑是否可写一行代码变换多个属性
    • 变换不一致的时候,定时器被提前清除

在线演示

# 1.2.3 运动速度之封装2–增加opacity
<div id="ball"></div>
@前端进阶之旅: 代码已经复制到剪贴板
#ball {
  position: relative;
  left: 0;
  top: 0;
  width: 100px;
  height: 100px;
  background: blue;
  opacity: 1;
}
@前端进阶之旅: 代码已经复制到剪贴板
var ball = document.getElementById("ball");
ball.onmouseover = function(){
	move(ball,{"width":300,"height":300,"opacity":0.3});
}
//			ball.onmouseout = function(){
//				move(ball,{"width":100,"height":100},-10);
//			}
function move(obj,json){
	clearInterval(obj.timer);
	var mark = true;
	obj.timer = setInterval(function(){
		for(var attr in json){
			var curr = null;
			var target = json[attr];
			var speed = null;
			if(attr == "opacity"){
				curr = getStyle(obj,attr)*100;
				speed = (target*100-curr)*0.15;
			}else {
				curr = parseInt(getStyle(obj,attr));
				speed = (target - curr)*0.15;
			}
			speed = speed>0 ? Math.ceil(speed):Math.floor(speed);
			if(curr != target){
				if(attr == "opacity"){
					obj.style[attr] = (curr+speed)/100;
				}else {
					obj.style[attr] = curr+speed+"px";
				}
				
				mark = false;
		  }
		}
		if(mark){
			clearInterval(obj.timer);
		}
	},1000/30);
}


function getStyle(obj,attr){
	return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
@前端进阶之旅: 代码已经复制到剪贴板

在线演示

  • 需要注意的地方
    • 当需要两个动画的时候,会执行后面一个,解决办法如下,回调函数
    • 当需要两个以上的时候,需要考虑是否可写一行代码变换多个属性
    • 变换不一致的时候,定时器被提前清除
    • 速度speed不要写死

# 1.3 运动框架之应用

# 1.3.1 分享按钮
<div id="ball"></div>
<div id="box1">
  <div id="box2">分享到</div>
</div>
@前端进阶之旅: 代码已经复制到剪贴板
var box1 = document.getElementById("box1");
var ball = document.getElementById("ball");

box1.onmouseover = function(){
  move(this,"left",0,10);
}
box1.onmouseout = function(){
  move(this,"left",-100,-10);
}
//问题一:当需要两个动画的时候,会执行后面一个,解决办法如下,回调函数
ball.onmouseover = function(){
  //同时变换 用的最多
  //move(this,"width",500,10);
  //move(this,"height",500,10);
  //列队在执行
  move(ball,"width",500,10,function(){
    move(ball,"height",500,10);
  });
}
ball.onmouseout = function(){
  //move(this,"width",100,-10);
  //move(this,"height",100,-10);
  move(ball,"width",100,-10,function(){
    move(ball,"height",100,-10);
  });
}
var timer = null;
function move(obj,attr,target,speed,callback){
  clearInterval(timer); //obj.timer缓存到各自的obj下
  timer = setInterval(function(){
    var curr = parseInt(getStyle(obj,attr));
    if(curr == target){
      clearInterval(timer);
      callback && callback();
    }else {
      obj.style[attr] = curr+speed+"px";
    }
  },1000/30);
}




function getStyle(obj,attr){
  return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
@前端进阶之旅: 代码已经复制到剪贴板

在线演示

# 1.3.2运动框架之轮播图应用
  • 焦点轮播–基本版本–在线演示
  • 焦点轮播–淡入淡出–在线演示
  • 焦点轮播–左右–在线演示
  • 焦点轮播–上下–在线演示
# 1.3.2.1 焦点轮播–左右-无缝-速度版实现

← JavaScript深浅拷贝JavaScript运行机制Event Loop →

fe