Javascript笔记大全03

18 篇文章 0 订阅
14 篇文章 1 订阅

BOM

简介

BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象使window

区别

DOM

  1. 文档对象模型
  2. DOM就是把【文档】当做是一个【对象】来看待
  3. DOM的顶级对象是document
  4. DOM主要学习的是操作页面元素
  5. DOM是W3C标准规范

BOM

  1. 浏览器对象模型
  2. 把【浏览器】当做是一个【对象】来看待
  3. BOM的顶级对象是window
  4. BOM学习的是浏览器窗口交互的一些对象
  5. BOM是浏览器厂商在各自浏览器上定义的,兼容性较差

BOM比DOM更大,它包含DOM

调整窗口大小事件

window.onresize = function() {}
window.addEventListener('resize',function() {});

window.onresize是调整窗口大小加载事件,当触发时就调用的处理函数

注意:

  1. 只要窗口大小发生变化,就会触发这个事件
  2. 经常利用这个事件完成响应式布局,window.innerWidth 当前屏幕的宽度
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			div {
				width: 200px;
				height: 200px;
				background-color: pink;
			}
		</style>
	</head>
	<body>
		<script type="text/javascript">
			window.addEventListener('load',function() {
				// 粉色盒子随着窗口大小而显示或者隐藏
				// 获取div
				var div = document.querySelector('div');
				window.addEventListener('resize',function() {
					console.log(window.innerWidth);
					
					console.log('变化了');
					if (window.innerWidth <= 800) {
						div.style.display = 'none';
					} else {
						div.style.display = 'block';
					}
				})
			})
		</script>
		<div></div>
	</body>
</html>

定时器

window对象给我们提供了2个非常好用的方法-定时器

  1. setTimeout()
  2. setInterval()

setTimeout() 定时器

window.setTimeout(调用函数,[延迟的毫秒数]);

setTimeout() 方法用于设置一个定时器,该定时器在定时器到期后执行调用函数

注意:

  1. window可以省略
  2. 这个调用函数可以直接写函数,或者写函数名或者采取字符串 ‘函数名()’ 三种方式。第三种不推荐
  3. 延迟的毫秒数省略默认是0,如果写,必须是毫秒
  4. 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符

setTimeout() 这个调用函数也称为回调函数 callback,普通函数是按照代码顺序直接调用,而这个函数,需要等待时间,时间到了才去调用这个函数,因此称为回调函数。

简单理解:回调,就是回头调用的意思。上一件事干完,再回头调用这个函数

案例

5秒之后自动关闭的广告

  1. 核心思路:5秒之后,就把广告隐藏起来
  2. 用定时器setTimeout
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<img src="./img/广告.jpg" class="ad" width="500px">
		<script type="text/javascript">
			var ad = document.querySelector('.ad');
			setTimeout(function() {
				ad.style.display = 'none';
			}, 5000);
		</script>
	</body>
</html>

停止setTimeout() 定时器

window.clearTimeout (timeoutID)

clearTimeout() 方法取消了先前通过调用setTimeout()建立的定时器

注意:

  1. window可以省略
  2. 里面的参数就是定时器的标识符
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<!-- 点击按钮后不会输出'爆炸了',否则5秒后输出'爆炸了' -->
		<button>点击停止定时器</button>
		<script type="text/javascript">
			var btn = document.querySelector('button');
			var timer = setTimeout(function() {
				console.log('爆炸了');
			}, 5000);
			btn.addEventListener('click',function() {
				clearTimeout(timer);
			})
		</script>
	</body>
</html>

setInterval() 定时器

window.setInterval(回调函数,[间隔的毫秒数]);

setInterval() 方法重复调用一个函数,每隔这个时间,就去调用一次回调函数

注意:

  1. window可以省略
  2. 这个调用函数可以直接写函数,或者写函数名或者采取字符串 ‘函数名()’ 三种形式
  3. 间隔的毫秒数省略默认是0,如果写,必须是毫秒,表示每间隔多少毫秒就自动调用这个函数
  4. 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			// 语法规范: window.setInterval(调用函数,延时时间);
			setInterval(function() {
				console.log('连续中出');
			}, 1000);
		</script>
	</body>
</html>
案例

秒杀倒计时

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			div {
				text-align: center;
				margin-top: 100px;
			}
			span {
				background-color: black;
				width: 50px;
				height: 50px;
				text-align: center;
				line-height: 50px;
				color: #fff;
				font-size: 20px;
				margin:50px 0;
				padding: 20px 20px;
			}
		</style>
	</head>
	<body>
		<div>
			<span class="hour">1</span>
			<span class="minute">2</span>
			<span class="second">3</span>
		</div>
		<script type="text/javascript">
			// 1.获取元素
			var hour = document.querySelector('.hour'); // 小时的黑色盒子
			var minute = document.querySelector('.minute'); // 分钟的黑色盒子
			var second = document.querySelector('.second'); // 秒数的黑色盒子
			
			var inputTime = +new Date('2021-8-2 19:00:00'); // 返回的是用户输入时间总的毫秒数
			countDown(); // 先调用一次这个函数,防止刷新页面有空白
			
			// 开启定时器
			setInterval(countDown, 1000);
			
			function countDown() {
				var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
				
				var times = (inputTime - nowTime) / 1000; // times是剩余时间总的毫秒数
				var h = parseInt(times / 60 / 60); // 时
				h = h < 10 ? '0' + h : h;
				hour.innerHTML = h; // 把剩余的小时 给 小时的黑色盒子
				
				var m = parseInt(times / 60 % 60); // 分
				m = m < 10 ? '0' + m : m;
				minute.innerHTML = m;
				
				var s = parseInt(times % 60); // 当前的秒
				s = s < 10 ? '0' + s : s;
				second.innerHTML = s;
			}
		</script>
	</body>
</html>

在这里插入图片描述

区别

  1. setTimeout 延时时间到了,就去调用这个回调函数,只调用一次就结束了这个定时器
  2. setInterval 每隔一个这个延时时间,就去调用这个回调函数,会调用很多次,重复调用这个函数

停止setInterval() 定时器

window.clearInterval(intervalID);

clearInterval() 方法取消了先前通过调用setInterval()建立的定时器

注意:

  1. window可以省略
  2. 里面的参数就是定时器的标识符
<body>
	<button class="begin">开启定时器</button>
	<button class="stop">停止定时器</button>
	<script type="text/javascript">
		var begin = document.querySelector('.begin');
		var stop = document.querySelector('.stop');
		var timer = null; // 全局变量 null是一个空对象
		begin.addEventListener('click',function() {
			timer = setInterval(function() {
				console.log('你好啊');
			}, 1000);
		})
		stop.addEventListener('click',function() {
			clearInterval(timer);
		})
	</script>
</body>
案例

发送短信

<body>
	手机号码: <input type="number"> <button>发送</button>
	<script type="text/javascript">
		// 按钮点击之后,会禁用disabled为true
		// 同时按钮里面的内容会变化,注意button里面的内容通过innerHTML修改
		// 里面秒数是有变化的,因此需要用到定时器
		// 定义一个变量,在定时器里面,不断递减
		// 如果变量为0 说明到了时间,我们需要停止定时器,并且复原按钮初始状态
		var btn = document.querySelector('button');
		var time = 3; // 定义剩下的秒数
		btn.addEventListener('click',function() {
			btn.disabled = true;
			var timer = setInterval(function() {
				if (time == 0) {
					// 清除定时器和复原按钮
					clearInterval(timer);
					btn.disabled = false;
					btn.innerHTML = '发送';
					time = 3; // 这个3需要从新开始
				} else {
					btn.innerHTML = '还剩下' + time + '秒';
					time--;
				}
			}, 1000);
		})
	</script>
</body>

同步和异步

Javascript的一大特点就是单线程,就是说,同一个时间只能做一件事。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样会导致:如果JS执行时间过长,会造成页面的渲染不连贯。

同步

前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。

比如做饭的同步做法:烧水煮饭,等水开了,再去切菜、炒菜。

异步

在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,还可以去处理其他事情。

比如做饭的异步做法:在烧水的同时,利用这10分钟,去切菜、炒菜。

同步和异步的本质区别:这条流水线上各个流程的执行顺序不同

以下代码执行的结果是什么?

console.log(1);
setTimeout(function() {
    console.log(3);
}, 0);
console.log(2);

结果:1 2 3

执行机制

  1. 先执行 执行栈 中的同步任务
  2. 异步任务(回调函数)放入任务队列中
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

在这里插入图片描述

location 对象

URL的一般语法格式为:

protocol://host[:post]/path/[?query]#fragment
http://www.itcast.cn/index.html?name=andy&age=18#link
组成说明
protocol通信协议 常用的http,ftp,maito等
host主机(域名)www.itheima.com
port端口号 可选,省略时使用方案的默认端口 如http的默认端口为80
path路径 由 0 或多个’/'符号隔开的字符串,一般用来表示主机上的一个目录或文件地址
query参数 以键值对的形式,通过&符号分隔开来
fragment片段 #后面内容 常见于链接、锚点

location对象的属性

location对象属性返回值
location.href获取或者设置整个URL
location.host返回主机(域名)www.itheima.com
location.port返回端口号 如果未写返回空字符串
location.pathname返回路径
location.search返回参数
location.hash返回片段 #后面内容 常见于链接、锚点

重点记住:href 和 search

<body>
	<button>点击</button>
	<div></div>
	<script type="text/javascript">
		var btn = document.querySelector('button');
		var div = document.querySelector('div');
		// 点击跳转
		btn.addEventListener('click',function() {
			location.href = 'http://www.baidu.com';
		})
		// n秒后跳转
		var timer = 5;
		setInterval(function() {
			if (timer == 0) {
				location.href = 'http://www.baidu.com';
			} else {
				div.innerHTML = '将在'+ timer +'秒钟之后跳转';
				timer--;
			}
		}, 1000);
	</script>
</body>
案例
  1. 第一个登录页面,里面有提交表单,action提交到index.html页面
  2. 第二个页面,可以使用第一个页面的参数,这样实现了一个数据不同页面之间的传递效果
  3. 第二个页面之所以可以使用第一个页面的数据,是利用了URL里面的location.search参数
  4. 在第二个页面中,需要把这个参数提取
  5. 第一步去掉? 利用substr
  6. 第二步利用=号分割键和值 split(’=’)

login.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<form action="index.html">
			用户名:<input type="text" name="uname"/>
			<input type="submit" value="登录"/>
		</form>
		<script type="text/javascript">
			console.log(location.search);
			// 1.先去掉? substr('起始位置','截取几个字符');
			var params = location.search.substr(1);
			console.log(params);
			// 2.利用=把字符串分割为数组 split('=');
			var arr = params.split('=');
			console.log(arr);
		</script>
	</body>
</html>

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div></div>
		<script type="text/javascript">
			console.log(location.search);
			// 1.先去掉? substr('起始位置','截取几个字符');
			var params = location.search.substr(1);
			console.log(params);
			// 2.利用=把字符串分割为数组 split('=');
			var arr = params.split('=');
			console.log(arr);
			var div = document.querySelector('div');
			// 3.把数据写入div中
			div.innerHTML = arr[1] + '欢迎您';
		</script>
	</body>
</html>

location对象的方法

location对象方法返回值
location.assign()跟href一样,可以跳转页面(也称为重定向页面)
location.replace()替换当前页面,因为不记录历史,所以不能后退页面
location.reload()重新加载页面,相对于刷新按钮或者f5 如果参数为true 强制刷新 Ctrl + f5

navigator对象

navigator对象包含有关浏览器的信息,它有很多属性,最常用的时userAgent,该属性可以返回客户机发送服务器的user-agent头部的值

判断用户哪个终端打开页面,实现跳转

if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|blackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
	window.location.href = ''; // 手机
} else {
	window.location.href = ''; // 电脑
}

history对象

window对象给我们提供了一个history对象,与浏览器历史记录进行交互。

history对象方法作用
back()可以后退功能
forward()前进功能
go(参数)前进后退功能 参数如果是1前进1个页面,如果是-1后退一个页面

history对象一般在实际开发中比较少用,但是会在一些OA办公系统中见到。

PC端网页特效

元素偏移量offset系列

offset翻译过来就是偏移量,使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等

  1. 获得元素距离带有定位父元素的位置
  2. 获得元素自身的大小(宽度高度)
  3. 注意:返回的数值都不带单位

offset系列常用属性:

offset系列属性作用
element.offsetParent返回作为该元素带有定位的父级元素 如果父级都没有定位则返回body
element.offsetTop返回元素相对带有定位父元素上方的偏移
element.offsetLeft返回元素相对带有定位父元素左边框的偏移
element.offsetWidth返回自身包括padding、边框、内容区的宽度,返回数值不带单位
element.offsetHeight返回自身包括padding、边框、内容区的高度,返回数值不带单位
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			* {
				padding: 0;
				margin: 0;
			}
			.father {
				position: relative;
				width: 200px;
				height: 200px;
				background-color: pink;
				margin: 100px;
			}
			.son {
				width: 100px;
				height: 100px;
				background-color: plum;
				margin-left: 45px;
			}
		</style>
	</head>
	<body>
		<div class="father">
			<div class="son"></div>
		</div>
		<script type="text/javascript">
			// offset系列
			var father = document.querySelector('.father');
			var son = document.querySelector('.son');
			// 可以得到元素的偏移 位置 返回的不带单位的数值
			console.log(father.offsetTop); // 100
			console.log(father.offsetLeft); // 100
			// 它以带有定位的父亲为准 如果没有父亲或者父亲没有定位 则以body为准
			console.log(son.offsetLeft); // 45
		</script>
	</body>
</html>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			* {
				padding: 0;
				margin: 0;
			}
			.w {
				width: 200px;
				height: 200px;
				background-color: skyblue;
				margin: 0 auto 200px;
				padding: 10px;
			}
		</style>
	</head>
	<body>
		<div class="w"></div>
		<script type="text/javascript">
			// offset系列
			var w = document.querySelector('.w');
			// 可以得到元素的大小、宽度、高度,是包含padding + border + width
			console.log(w.offsetWidth); // 220
			console.log(w.offsetHeight); // 220
		</script>
	</body>
</html>

offset与style的区别

offset

  1. 可以得到任意样式表中的样式值
  2. 获得的数值没有单位
  3. 包含padding + border + width
  4. offsetWidth等属性是只读属性,只能获取不能赋值
  5. 所以,想要获取元素大小位置,用offset更合适

style

  1. 只能得到行内样式表中的样式值
  2. style.width获得的是带有单位的字符串
  3. style.width获得不包括padding和border的值
  4. style.width是可读写属性,可以获取也可以赋值
  5. 所以,想要给元素更改值,则需要用style改变
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			.box {
				width: 500px;
				height: 500px;
				background-color: pink;
				margin: 0 auto;
			}
		</style>
	</head>
	<body>
		<div class="box"></div>
		<script type="text/javascript">
			// 在盒子内点击,想要得到鼠标距离盒子左右的距离
			// 首先得到鼠标在页面中的坐标(e.pageX,e.pageY)
			// 其次得到盒子在页面中的距离(box.offsetLeft,box.offsetTop)
			// 用鼠标距离页面的坐标减去盒子在页面中的距离,得到鼠标在盒子内的坐标
			var box = document.querySelector('.box');
			box.addEventListener('click',function(e) {
				// console.log(e.pageX);
				// console.log(e.pageY);
				// console.log(box.offsetLeft);
				var x = e.pageX - this.offsetLeft;
				var y = e.pageY - this.offsetTop;
				this.innerHTML = 'x坐标是' + x + 'y坐标是' + y;
			})
		</script>
	</body>
</html>

元素可视区client系列

通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等

client系列属性作用
element.clientTop返回元素上边框的大小
element.clientLeft返回元素左边框的大小
element.clientWidth返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位
element.clientHeight返回自身包括padding、内容区的高度,不含边框,返回数值不带单位
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			div {
				width: 200px;
				height: 200px;
				background-color: pink;
				border: 10px solid red;
			}
		</style>
	</head>
	<body>
		<div></div>
		<script type="text/javascript">
			// client宽度 和offsetWidth最大的区别就是 不包含边框
			var div = document.querySelector('div');
			console.log(div.clientWidth); // 200
		</script>
	</body>
</html>

立即执行函数

主要作用:创建一个独立的作用域

<body>
	<script type="text/javascript">		
        function fn() {
			console.log(1);
		}
		fn();			// 1.立即执行函数:不需要调用,立马能够自己执行的函数
		// 2. 写法 也可以传递参数进来
		// (function () {})()  或者  (function(){}())
		(function(a,b) {
			console.log(a + b); // 3
			var num = 10;
		})(1,2); // 第二个小括号可以看做是调用函数
		
		(function sum(a,b) {
			console.log(a + b); // 5
			var num = 10; // 局部变量
		}(2,3));
		// 3.立即执行函数最大的作用就是:独立创建一个作用域,里面所有的变量都是局部变量 不会有命名冲突的情况
	</script>
</body>

元素滚动scroll系列属性

使用scroll系列的相关属性可以动态的得到该元素的大小、滚动距离等

scroll系列属性作用
element.scrollTop返回被卷去的上侧距离,返回数值不带单位
element.scrollLeft返回被卷去的左侧距离,返回数值不带单位
element.scrollWidth返回自身实际的宽度,不含边框,返回数值不带单位
element.scrollHeight返回自身实际的高度,不含边框,返回数值不带单位
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			div {
				width: 200px;
				height: 200px;
				background-color: pink;
				border: 10px solid red;
				padding: 10px;
				overflow: auto;
			}
		</style>
	</head>
	<body>
		<div>
			 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容
			 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容
			 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容
		</div>
		<script type="text/javascript">
			// scroll系列
			var div = document.querySelector('div');
			console.log(div.scrollHeight); // 这里是440,数值随着内容的增加而增大
			console.log(div.clientHeight); // 220
		</script>
	</body>
</html>

案例

  1. 原先侧边栏是绝对定位
  2. 当页面滚动到一定位置,侧边栏改为固定定位
  3. 页面继续滚动,会让返回顶部显示出来
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			.slider-bar {
				position: absolute;
				left: 50%;
				top: 300px;
				margin-left: 600px;
				width: 45px;
				height: 130px;
				background-color: pink;
			}
			
			.w {
				width: 1200px;
				margin: 10px auto;
			}
			
			.header {
				height: 150px;
				background-color: purple;
			}
			
			.banner {
				height: 250px;
				background-color: skyblue;
			}
			
			.main {
				height: 1000px;
				background-color: yellowgreen;
			}
			
			span {
				display: none;
				position: absolute;
					bottom: 0;
			}
		</style>
	</head>
	<body>
		<div class="slider-bar">
			<span class="goBack">返回顶部</span>
		</div>
		<div class="header w">头部区域</div>
		<div class="banner w">banner区域</div>
		<div class="main w">主体部分</div>
		<script type="text/javascript">
			// 获取元素
			var sliderbar = document.querySelector('.slider-bar');
			var banner = document.querySelector('.banner');
			// banner.offsetTop就是被卷去头部的大小一定要写到滚动的外面
			var bannerTop = banner.offsetTop;
			// 当侧边栏固定定位之后应该变化的数值
			var sliderbarTop = sliderbar.offsetTop - bannerTop;
			// 获取main主体元素
			var main = document.querySelector('.main');
			var goBack = document.querySelector('.goBack');
			var mainTop = main.offsetTop;
			
			// 页面滚动事件 scroll
			document.addEventListener('scroll',function() {
				// window.pageYoffset 页面被卷去的头部
				// 当页面被卷去的头部大于等于172 此时 侧边栏就要改为固定定位
				if (window.pageYOffset >= 172) {
					sliderbar.style.position = 'fixed';
					sliderbar.style.top = sliderbarTop + 'px';
				} else {
					sliderbar.style.position = 'absolute';
					sliderbar.style.top = '300px';
				}
				// 当页面滚动到main盒子,就显示goback模块
				if (window.pageYOffset >= mainTop) {
					goBack.style.display = 'block';
				} else {
					goBack.style.display = 'none';
				}
			})
		</script>
	</body>
</html>
页面被卷去的头部兼容性解决方案

页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:

  1. 声明了DTD,使用document.documentElement.scrollTop
  2. 声明了DTD,使用document.body.scrollTop
  3. 新方法window.pageYoffset 和 window.pageXoffset,IE9开始支持
function getScroll() {
    return {
        left:window.pageXoffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0,
        top:window.pageYoffset || document.documentElement.scrollTop || document.body.scrollTop || 0
    };
}
// 使用的时候
getScroll().left

三大系列总结

三大系列大小对比作用
element.offsetWidth返回自身包括padding、边框、内容区的宽度,返回数值不带单位
element.clientWidth返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位
element.scrollWidth返回自身实际的宽度,不含边框,返回数值不带单位

主要用法

  1. offset系列经常用于获得元素位置 offsetLeft offsetTop
  2. client系列经常用于获取元素大小 clientWidth clientHeight
  3. scroll系列经常用于获取滚动距离 scrollTop scrollLeft
  4. 注意页面滚动的距离通过 window.pageXoffset 获得

动画函数封装

核心原理:通过定时器setinterval()不断移动盒子位置

步骤:

  1. 获得盒子当前位置
  2. 让盒子在当前位置加上1个移动距离
  3. 利用定时器不断重复这个操作
  4. 加一个结束定时器的条件
  5. 注意此元素需要添加定位,才能使用element.style.left
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			div {
				position: absolute;
				left: 0;
				width: 100px;
				height: 100px;
				background-color: pink;
			}
		</style>
	</head>
	<body>
		<div></div>
		<script type="text/javascript">
			var div = document.querySelector('div');
			
			var timer = setInterval(function() {
				if(div.offsetLeft >= 400) {
					// 停止动画 本质是停止定时器
					clearInterval(timer);
				}
				div.style.left = div.offsetLeft + 1 + 'px';
			}, 30);
		</script>
	</body>
</html>
动画函数给不同元素记录不同定时器

如果多个元素都使用这个动画函数,每次都要var声明定时器。可以给不同元素使用不同的定时器(自己专门用自己的定时器)

核心原理:利用js是一门动态语言,可以很方便的给当前对象添加属性

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			div {
				position: absolute;
				left: 0;
				width: 100px;
				height: 100px;
				background-color: pink;
			}
			
			span {
				position: absolute;
				left: 0;
				top: 200px;
				display: block;
				width: 150px;
				height: 150px;
				background-color: purple;
			}
		</style>
	</head>
	<body>
		<button>点击阿波才走</button>
		<div></div>
		<span>阿波</span>
		<script type="text/javascript">
			// 简单动画函数封装obj目标对象 target 目标位置
			// 给不同的元素指定了不同的定时器
			function animate(obj,target) {
				// 当不断点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
				// 解决方案是:让我们元素只有一个定时器执行
				// 先清除以前的定时器,只保留当前的一个定时器执行
				clearInterval(obj.timer);
				obj.timer = setInterval(function() {
					if(obj.offsetLeft >= target) {
						// 停止动画 本质是停止定时器
						clearInterval(timer);
					}
					obj.style.left = obj.offsetLeft + 1 + 'px';
				}, 30);
			}
			
			var div = document.querySelector('div');
			var span = document.querySelector('span');
			var btn = document.querySelector('button');
			// 调用函数
			animate(div,300);
			
			btn.addEventListener('click',function() {
				animate(span,200);
			})
		</script>
	</body>
</html>

缓动效果

缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来

思路:

  1. 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来
  2. 核心算法:(目标值-现在的位置)/ 10 做为每次移动的距离步长
  3. 停止的条件是:让当前盒子位置等于目标位置就停止定时器
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			span {
				position: absolute;
				left: 0;
				top: 200px;
				display: block;
				width: 150px;
				height: 150px;
				background-color: purple;
			}
		</style>
	</head>
	<body>
		<button class="btn500">点击阿波到500</button>
		<button class="btn800">点击阿波到800</button>
		<span>阿波</span>
		<script type="text/javascript">
			// 简单动画函数封装obj目标对象 target 目标位置
			function animate(obj,target) {
				// 先清除以前的定时器,只保留当前的一个定时器执行
				clearInterval(obj.timer);
				obj.timer = setInterval(function() {
					// 步长值写道定时器的里面
					var step = (target - obj.offsetLeft) / 10;
					// 把步长值改为整数 不要出现小数的问题
					step = step > 0 ? Math.ceil(step) : Math.floor(step);
					if(obj.offsetLeft == target) {
						// 停止动画 本质是停止定时器
						clearInterval(obj.timer);
					}
					// 把每次加1这个步长值改为一个慢慢变小的值,步长公式:(目标值-现在的位置)/ 10
					obj.style.left = obj.offsetLeft + step + 'px';
				}, 15);
			}
			
			var span = document.querySelector('span');
			var btn500 = document.querySelector('.btn500');
			var btn800 = document.querySelector('.btn800');
			// 调用函数
			btn500.addEventListener('click',function() {
				animate(span,500);
			})
			btn800.addEventListener('click',function() {
				animate(span,800);
			})
			// 匀速动画 就是 盒子是当前的位置 + 固定的值 10
			// 缓动动画 就是 盒子当前的位置 + 变化的值(目标值 - 现在的位置)/ 10)
		</script>
	</body>
</html>

动画函数添加回调函数

回调函数:函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程叫回调。

回调函数写的位置:定时器结束的位置

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			span {
				position: absolute;
				left: 0;
				top: 200px;
				display: block;
				width: 150px;
				height: 150px;
				background-color: purple;
			}
		</style>
	</head>
	<body>
		<button class="btn500">点击阿波到500</button>
		<button class="btn800">点击阿波到800</button>
		<span>阿波</span>
		<script type="text/javascript">
			// 简单动画函数封装obj目标对象 target 目标位置
			function animate(obj,target,callback) {
				// 先清除以前的定时器,只保留当前的一个定时器执行
				clearInterval(obj.timer);
				obj.timer = setInterval(function() {
					// 步长值写道定时器的里面
					var step = (target - obj.offsetLeft) / 10;
					// 把步长值改为整数 不要出现小数的问题
					step = step > 0 ? Math.ceil(step) : Math.floor(step);
					if(obj.offsetLeft == target) {
						// 停止动画 本质是停止定时器
						clearInterval(obj.timer);
						// 回调函数写到定时器结束里面
						if (callback) {
							// 调用函数
							callback();
						}
					}
					// 把每次加1这个步长值改为一个慢慢变小的值,步长公式:(目标值-现在的位置)/ 10
					obj.style.left = obj.offsetLeft + step + 'px';
				}, 15);
			}
			
			var span = document.querySelector('span');
			var btn500 = document.querySelector('.btn500');
			var btn800 = document.querySelector('.btn800');
			// 调用函数
			btn500.addEventListener('click',function() {
				animate(span,500);
			})
			btn800.addEventListener('click',function() {
				// 使盒子变红色的函数
				animate(span,800,function() {
					// alert('你好吗');
					span.style.backgroundColor = 'red';
				});
			})
			// 匀速动画 就是 盒子是当前的位置 + 固定的值 10
			// 缓动动画 就是 盒子当前的位置 + 变化的值(目标值 - 现在的位置)/ 10)
		</script>
	</body>
</html>

轮播图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>最简单的轮播效果</title>
	<link rel="stylesheet" type="text/css" href="css/index.css"/>
	<script type="text/javascript" src="js/index.js"></script>
</head>
	<body>
		<div class="focus">
			<!-- 左侧按钮 -->
			<a href="javascript:;" class="arrow-l">&lt;</a>
			<!-- 右侧按钮 -->
			<a href="javascript:;" class="arrow-r">&gt;</a>
			<!-- 核心的滚动区域 -->
			<ul>
				<li><a href="#"><img src="img/破败大事件.jpg" ></a></li>
				<li><a href="#"><img src="img/灵能特工.jpg" ></a></li>
				<li><a href="#"><img src="img/烈阳皎月.jpg" ></a></li>
				<li><a href="#"><img src="img/阿狸.jpg" ></a></li>
				<li><a href="#"><img src="img/蜘蛛女皇伊莉丝-女巫.jpg" ></a></li>
				<li><a href="#"><img src="img/LOL英雄酒馆.png" ></a></li>
			</ul>
			<!-- 小圆圈 -->
			<ol class="circle"></ol>
		</div>
	</body>
</html>
* {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}
/* 去掉li的小圆点 */
li {
	list-style:none
}

.focus {
	position: relative;
	width: 1024px;
	height: 400px;
	/* background-color: purple; */
	margin: auto;
	margin-top: 50px;
	overflow: hidden;
}

.focus ul {
	position: absolute;
	top: 0;
	left: 0;
	width: 800%;
}

.focus ul li {
	float: left;
}
.focus ul li img {
	width: 1024px;
}

.focus ol {
	position: absolute;
	height: 20px;
	/* right: 20px; */
	right: 42%;
	bottom: 20px;
	text-align: center;
	padding: 5px;
}

.focus ol li {
	display: inline-block;
	border-radius: 50%;
	width: 20px;
	height: 20px;
	line-height: 20px;
	background-color: #fff;
	margin: 5px;
	cursor: pointer;
}

.focus ol .current {
	background-color: orangered;
}

/* 左右按钮 */
.arrow-l,
.arrow-r {
	display: none;
	position: absolute;
	top: 50%;
	/* margin-top: -20px; */
	width: 40px;
	height: 60px;
	background: rgba(255, 255, 255, 0.3);
	text-align: center;
	/* line-height: -10; */
	color: black;
	font-size: 40px;
	text-align: center;
	text-decoration: none;
	z-index: 2;
	
}

.arrow-r {
	right: 0;
}
window.addEventListener('load',function() {
	// 获取元素
	var arrow_l = document.querySelector('.arrow-l');
	var arrow_r = document.querySelector('.arrow-r');
	var focus = document.querySelector('.focus');
	var focusWidth = focus.offsetWidth;
	
	// 鼠标经过 focus 就显示隐藏左右按钮
	focus.addEventListener('mouseenter',function() {
		arrow_l.style.display = 'block';
		arrow_r.style.display = 'block';
		// 鼠标经过停止轮播
		clearInterval(timer);
		timer = null; // 清除定时器变量
	});
	focus.addEventListener('mouseleave',function() {
		arrow_l.style.display = 'none';
		arrow_r.style.display = 'none';
		// 鼠标离开继续轮播
		timer = setInterval(function() {
			// 手动调用点击事件
			arrow_r.click();
		}, 2000);
	});
	
	// 动态生成小圆圈 有几张图片就生成几个小圆点
	var ul = focus.querySelector('ul');
	var ol = focus.querySelector('.circle');
	
	for (var i = 0; i < ul.children.length; i++) {
		// 创建li
		var li = document.createElement('li');
		// 记录当前小圆圈的索引号 通过自定义属性来做
		li.setAttribute('index',i);
		// 把li插入到ol里面
		ol.appendChild(li);
		// 排他思想 直接生成小圆圈的同时直接绑定点击事件
		li.addEventListener('click',function() {
			// 干掉所有人 把所有的 li 清除 current 类名
			for (var i = 0; i < ol.children.length; i++) {
				ol.children[i].className = '';
			}
			// 留下我自己 当前的li设置为 current 类名
			this.className = 'current';
			// 点击小圆圈,移动图片 移动的是ul
			// ul的移动距离 小圆圈的索引号 乘以 图片的宽度 注意是负值
			// 点击某个li 就拿到当前li的索引号
			var index = this.getAttribute('index');
			// 点击了某个li就把这个li的索引号给num
			num = index;
			// 点击了某个li就把这个li的索引号给circle
			circle = index;
			
			animate(ul,-index * focusWidth);
		})
	}
	// 把ol里面的第一个li的类名设置为current
	ol.children[0].className = 'current';
	// 克隆第一张图片放到ul最后面
	var first = ul.children[0].cloneNode(true);
	ul.appendChild(first);
	// 点击右侧按钮,图片滚动一张
	var num = 0;
	// circle控制小圆圈的播放
	var circle = 0;
	
	// 节流阀
	var flag = true;
	// 右侧按钮
	arrow_r.addEventListener('click',function() {
		if(flag) {
			flag = false; // 关闭节流阀
			// 如果走到最后复制的一张图片,此时 ul快速复原left为0
			if (num == ul.children.length - 1) {
				ul.style.left = 0;
				num = 0;
			}
			num++;
			animate(ul,-num * focusWidth,function() {
				flag = true;
			});
			// 点击右侧图片按钮,小圆圈随着一起变化
			circle++;
			// 如果circle==ol.children.length说明走到最后我们克隆的这张图片了,就复原
			if (circle == ol.children.length) {
				circle = 0;
			}
			// 调用函数
			circleChange();
		}
		
	});
	
	// 左侧按钮
	arrow_l.addEventListener('click',function() {
		if (flag) {
			flag = false;
			// 如果走到最后复制的一张图片,此时 ul快速复原left为0
			if (num == 0) {
				num = ul.children.length - 1;
				ul.style.left = -num * focusWidth + 'px';
			}
			num--;
			animate(ul,-num * focusWidth,function() {
				flag = true;
			});
			
			// 点击右侧图片按钮,小圆圈随着一起变化
			circle--;
			// 如果circle==ol.children.length说明走到最后我们克隆的这张图片了,就复原
			// if (circle < 0) {
			// 	circle = ol.children.length - 1;
			// }
			circle = circle < 0 ? ol.children.length - 1 : circle;
			// 调用函数
			circleChange();
		}
	});
	
	// 清除圆圈函数
	function circleChange() {
		// 清除其余小圆圈的current类名
		for (var i = 0; i < ol.children.length; i++) {
			ol.children[i].className = '';
		}
		// 留下当前小圆圈的current类名
		ol.children[circle].className = 'current';
	}
	
	// 自动播放轮播图
	var timer = setInterval(function() {
		// 手动调用点击事件
		arrow_r.click();
	}, 2000);
	
	// 简单动画函数封装obj目标对象 target 目标位置
	// 给不同的元素指定了不同的定时器
	function animate(obj,target,callback) {
	// 当不断点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
	// 解决方案是:让我们元素只有一个定时器执行
	// 先清除以前的定时器,只保留当前的一个定时器执行
		clearInterval(obj.timer);
		obj.timer = setInterval(function() {
		// 步长值写道定时器的里面
		var step = (target - obj.offsetLeft) / 10;
		// 把步长值改为整数 不要出现小数的问题
		step = step > 0 ? Math.ceil(step) : Math.floor(step);
		if(obj.offsetLeft == target) {
			// 停止动画 本质是停止定时器
			clearInterval(obj.timer);
			// 回调函数写到定时器结束里面
			// if (callback) {
			// 	// 调用函数
			// 	callback();
			// }
			callback && callback();
		}
		// 把每次加1这个步长值改为一个慢慢变小的值,步长公式:(目标值-现在的位置)/ 10
		obj.style.left = obj.offsetLeft + step + 'px';
		}, 15);
	}
})

返回顶部

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			.slider-bar {
				position: absolute;
				left: 50%;
				top: 300px;
				margin-left: 600px;
				width: 45px;
				height: 130px;
				background-color: pink;
			}
			
			.w {
				width: 1200px;
				margin: 10px auto;
			}
			
			.header {
				height: 150px;
				background-color: purple;
			}
			
			.banner {
				height: 250px;
				background-color: skyblue;
			}
			
			.main {
				height: 1000px;
				background-color: yellowgreen;
			}
			
			span {
				display: none;
				position: absolute;
					bottom: 0;
			}
		</style>
	</head>
	<body>
		<div class="slider-bar">
			<span class="goBack">返回顶部</span>
		</div>
		<div class="header w">头部区域</div>
		<div class="banner w">banner区域</div>
		<div class="main w">主体部分</div>
		<script type="text/javascript">
			// 获取元素
			var sliderbar = document.querySelector('.slider-bar');
			var banner = document.querySelector('.banner');
			// banner.offsetTop就是被卷去头部的大小一定要写到滚动的外面
			var bannerTop = banner.offsetTop;
			// 当侧边栏固定定位之后应该变化的数值
			var sliderbarTop = sliderbar.offsetTop - bannerTop;
			// 获取main主体元素
			var main = document.querySelector('.main');
			var goBack = document.querySelector('.goBack');
			var mainTop = main.offsetTop;
			
			// 页面滚动事件 scroll
			document.addEventListener('scroll',function() {
				// window.pageYoffset 页面被卷去的头部
				// 当页面被卷去的头部大于等于172 此时 侧边栏就要改为固定定位
				if (window.pageYOffset >= 172) {
					sliderbar.style.position = 'fixed';
					sliderbar.style.top = sliderbarTop + 'px';
				} else {
					sliderbar.style.position = 'absolute';
					sliderbar.style.top = '300px';
				}
				// 当页面滚动到main盒子,就显示goback模块
				if (window.pageYOffset >= mainTop) {
					goBack.style.display = 'block';
				} else {
					goBack.style.display = 'none';
				}
			})
			// 当我们点击了返回顶部模块,就让窗口滑动到页面的最上方
			goBack.addEventListener("click",function() {
				// 里面的x和y不跟单位,直接写数字即可
				// window.scroll(0,0);
				animate(window,0);
			});
			
			// 动画函数
			function animate(obj,target,callback) {
			// 先清除以前的定时器,只保留当前的一个定时器执行
				clearInterval(obj.timer);
				obj.timer = setInterval(function() {
				// 步长值写道定时器的里面
				var step = (target - obj.offsetLeft) / 10;
				// 把步长值改为整数 不要出现小数的问题
				step = step > 0 ? Math.ceil(step) : Math.floor(step);
				if(window.pageYOffset == target) {
					// 停止动画 本质是停止定时器
					clearInterval(obj.timer);
					// 回调函数写到定时器结束里面
					callback && callback();
				}
					// 把每次加1这个步长值改为一个慢慢变小的值,步长公式:(目标值-现在的位置)/ 10
					// obj.style.left = obj.offsetLeft + step + 'px';
					window.scroll(0,window.pageYOffset - step);
				}, 15);
			}
		</script>
	</body>
</html>

本地储存

特性:

  1. 数据存储再用户浏览器中
  2. 设置、读取信息方便、甚至页面刷新不丢失数据
  3. 容量较大,sessionStorage约5M、localStorage约20M
  4. 只能存储字符串,可以将对象JSON.stringify()编码后存储

生命周期

简单来说就是:什么时候死

sessionStorage

  1. 生命周期为关闭浏览器窗口
  2. 在同一个窗口(页面)下数据都可以共享
  3. 以键值对的形式存储使用

存储数据:

sessionStorage.setltem(key,value)

获取数据:

sessionStorage.getItem(key)

删除数据:

sessionStorage.removeItem(key)

删除所有数据:

sessionStorage.clear()
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<input type="text">
		<button class="set">存储数据</button>
		<button class="get">获取数据</button>
		<button class="remove">删除数据</button>
		<button class="del">清空所有数据</button>
		<script type="text/javascript">
			var ipt = document.querySelector('input');
			var set = document.querySelector('.set');
			var get = document.querySelector('.get');
			var remove = document.querySelector('.remove');
			var del = document.querySelector('.del');
			
			set.addEventListener('click',function() {
				// 当我们点击了之后,就可以把表单里面的值存储起来
				var val = ipt.value;
				sessionStorage.setItem('uname',val);
			});
			get.addEventListener('click',function() {
				// 当我们点击了之后,就可以把表单里面的值获取过来
				console.log(sessionStorage.getItem('uname'));
			});
			remove.addEventListener('click',function() {
				// 当我们点击了之后,就可以把表单里面的值删除
				sessionStorage.removeItem('uname');
			});
			del.addEventListener('click',function() {
				// 当我们点击了之后,就可以把表单里面的值全部删除
				sessionStorage.clear();
			})
		</script>
	</body>
</html>

localStorage

  1. 声明周期永久生效,除非手动删除,否则关闭页面也会存在
  2. 可以多窗口(页面)共享(同一浏览器可以共享)
  3. 以键值对的形式存储使用

存储数据:

localStorage.setItem(key,value)

获取数据:

localStorage.getItem(key)

删除数据:

localStorage.removeItem(key)

删除所有数据:

localStorage.clear()
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<input type="text">
		<button class="set">存储数据</button>
		<button class="get">获取数据</button>
		<button class="remove">删除数据</button>
		<button class="del">清空所有数据</button>
		<script type="text/javascript">
			var ipt = document.querySelector('input');
			var set = document.querySelector('.set');
			var get = document.querySelector('.get');
			var remove = document.querySelector('.remove');
			var del = document.querySelector('.del');
			
			set.addEventListener('click',function() {
				var val = ipt.value;
				localStorage.setItem('uname',val);
			});
			get.addEventListener('click',function() {
				console.log(localStorage.getItem('uname'));
			});
			remove.addEventListener('click',function() {
				localStorage.removeItem('uname');
			});
			del.addEventListener('click',function() {
				localStorage.clear();
			})
		</script>
	</body>
</html>

案例:记住用户名

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<input type="text" id="username"> <input type="checkbox" name="" id="remember">记住用户名
		<script type="text/javascript">
			var username = document.querySelector('#username');
			var remember = document.querySelector('#remember');
			
			if (localStorage.getItem('username')) {
				username.value = localStorage.getItem('username');
				remember.checked = true;
			}
			remember.addEventListener('change',function() {
				if(this.checked) {
					localStorage.setItem('username',username.value)
				} else {
					localStorage.removeItem('username');
				}
			})
		</script>
	</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值