1.复习
2.鼠标滚轮轮播图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
list-style: none;
}
#container {
position: relative;
width: 560px;
height: 300px;
margin: 50px auto;
border: 3px solid red;
overflow: hidden;
}
/* 滚动轮播图的布局关键: ul的宽度是足够的大 */
#imgs {
position: absolute;
width: 8888px;
height: 300px;
left: 0;
top: 0;
}
/* 所有的li元素并排在一起 */
#imgs > li {
float: left;
}
</style>
</head>
<body>
<!-- 布局 -->
<div id="container">
<ul id="imgs">
<li><img src="./images/0.jpg" alt=""></li>
<li><img src="./images/1.jpg" alt=""></li>
<li><img src="./images/2.jpg" alt=""></li>
<li><img src="./images/3.jpg" alt=""></li>
<li><img src="./images/4.jpg" alt=""></li>
<!-- 设置猫腻图 -->
<li><img src="./images/0.jpg" alt=""></li>
</ul>
</div>
<!-- 引入tools -->
<script src="./js/tools.js"></script>
<script>
// 获取元素
var container = $('container');
var ul = $('imgs');
// 所有的图片
var lis = document.getElementsByTagName('li');
// 定义长度
var length = lis.length - 1;
console.log(length);
// 获取元素的宽度
var width = container.clientWidth;
// 定义锁
var lock = true;
// 定义信号量
var idx = 0;
// 定义获取滚轮方向的方法
function direction(e) {
// 在chrome中 指示鼠标滚轮方向的属性: e.wheelDelta
// console.log(e.wheelDelta);
// 在火狐中 指示鼠标滚轮方向的属性: e.detail
// console.log(e.detail);
// 定义结果变量
// 由于e.wheelDelta在火狐中显示的是undefined 所以可以通过判断是否是undefined 来判断出浏览器信息
if (e.wheelDelta === undefined) {
// 指示鼠标滚轮方向的属性: e.detail
// 判断鼠标滚轮的方向
// if (e.detail > 0) {
// // 向下滚动 3
// return true;
// } else {
// // 向上滚动 -3
// return false;
// }
// 当值是二取一的时候 就可以使用三目运算简化
return e.detail > 0 ? true : false;
} else {
// 指示鼠标滚轮方向的属性: e.wheelDelta
// 判断鼠标滚轮的方向
// if (e.wheelDelta > 0) {
// // 向上滚动
// return false;
// } else {
// // 向下滚动
// return true;
// }
// 值为假的有6个: '' undefined NaN null false 0
// 简写
return e.wheelDelta > 0 ? false : true;
}
}
// 绑定事件
bindEvent(document, 'mousewheel', function(e) {
// 执行方法获取滚轮方向
if (direction(e)) {
// 判断锁的状态
if (!lock) return;
// 把锁关闭
lock = false;
// 说明图片应该从右边进去 相当于右按钮事件
// 右按钮事件的策略: 先拉动 再验证
// 该变信号量
idx++;
// 拉动
animate(ul, { left: -width * idx }, 600, function() {
// 验证信号量
if (idx > length - 1) {
// 让idx从0开始
idx = 0;
// 瞬移到真图
css(ul, 'left', 0);
}
// 动画执行完毕之后 开锁
lock = true;
})
} else {
// 判断锁的状态
if (!lock) return;
// 把锁关闭
lock = false;
// 说明是向上滑动 相当于左按钮点击事件
// 左按钮点击事件策略: 先验证 后拉动
// 改变信号量
idx--;
// 先验证
if (idx < 0) {
// 让idx变为最大值
idx = length - 1;
// 瞬移
// 注意: 设置的value值要加上px
css(ul, 'left', -width * length + 'px');
}
// 拉动
animate(ul, { left: -width * idx }, 600, function() {
console.log('动画执行完毕了');
// 开锁
lock = true;
})
}
})
</script>
</body>
</html>
3.面向对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 我们想要通过变量来描述一个人
// 人的特征有: 姓名 性别 年龄 身高
// 因此我们要通过四个变量来描述一个人
// var name = '张三';
// var age = 30;
// var sex = '男';
// var length = 175;
// 如果想要描述10个人 则需要40个变量
// 所以对象这个数据结构解决了以上变量增多的问题
// var person = {
// name: 'wangwu',
// age: 31,
// sex: 'nan',
// length: 180
// }
// var person2 = {
// name: 'wangwu2',
// age: 32,
// sex: 'nan',
// length: 181
// }
// 现在虽然可以通过粘贴复制的形式快速创建一个人 但是我们仍然希望有一种简单的形式能够快速创建同类型的对象出来
// 结论: 使用函数 函数是可以复用的
// // 定义创建对象的函数
// function createObject() {
// // 定义对象
// var person = {
// name: 'wangwu3',
// age: 33,
// sex: 'nan',
// length: 183
// }
// // 返回对象
// return person;
// }
// // 执行方法
// var p = createObject();
// var p1 = createObject();
// console.log(p);
// console.log(p1);
// 目前为止 虽然可以快速创建一个同类型的数据结构出来 但是该对象中的数据值都是一样的 而我们希望每一个对象的数据值都是不同的
// 结论: 可以将不变的数据写死 将可变的值提取为函数的参数即可
// 改造:
// 定义创建对象的函数
function createObject(name, age, sex, length) {
// 定义对象
var person = {
name: name,
age: age,
sex: sex,
length: length
}
// 返回对象
return person;
}
// 执行方法
var p = createObject('xiaoming', 12, 'nan', 165);
var p1 = createObject('xiaohong', 11, 'nv', 160);
var p2 = createObject('xiaogang', 13, 'nan', 170);
console.log(p);
console.log(p1);
// 此时可以执行方法并传递不同的参数 即可得到不同的对象
// 而这个函数此时叫做 '工厂方法'
</script>
</body>
</html>
4.将面向过程改为面向对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
list-style: none;
}
#container {
position: relative;
width: 560px;
height: 300px;
margin: 50px auto;
border: 3px solid red;
overflow: hidden;
}
/* 滚动轮播图的布局关键: ul的宽度是足够的大 */
#imgs {
position: absolute;
width: 8888px;
height: 300px;
left: 0;
top: 0;
}
/* 所有的li元素并排在一起 */
#imgs > li {
float: left;
}
</style>
</head>
<body>
<!-- 布局 -->
<div id="container">
<ul id="imgs">
<li><img src="./images/0.jpg" alt=""></li>
<li><img src="./images/1.jpg" alt=""></li>
<li><img src="./images/2.jpg" alt=""></li>
<li><img src="./images/3.jpg" alt=""></li>
<li><img src="./images/4.jpg" alt=""></li>
<!-- 设置猫腻图 -->
<li><img src="./images/0.jpg" alt=""></li>
</ul>
</div>
<!-- 引入tools -->
<script src="./js/tools.js"></script>
<script>
// 以下是面向对象的形式:
// 定义对象
var carousel = {
// dom属性
dom: document.getElementById('imgs'),
// 图片属性
lis: document.getElementsByTagName('li'),
// 长度属性
length: document.getElementsByTagName('li').length - 1,
// 宽度属性
width: document.getElementById('container').clientWidth,
// 锁
lock: true,
// 信号量
idx: 0,
// 获取鼠标滚轮方向的方法 (一个方法尽量只做一件事件)
direction: function(e) {
if (e.wheelDelta === undefined) {
// 当值是二取一的时候 就可以使用三目运算简化
return e.detail > 0 ? true : false;
} else {
// 简写
return e.wheelDelta > 0 ? false : true;
}
},
// 显示下一张图片方法
showNext: function() {
// 方法中的this指向carousel
// 判断锁的状态
if (!this.lock) return;
// 把锁关闭
this.lock = false;
// 该变信号量
this.idx++;
// 缓存(备份)this
var me = this;
// 拉动
animate(this.dom, { left: -this.width * this.idx }, 600, function() {
// 验证信号量
if (me.idx > me.length - 1) {
// 让idx从0开始
me.idx = 0;
// 瞬移到真图
css(me.dom, 'left', 0);
}
// 动画执行完毕之后 开锁
me.lock = true;
})
},
// 显示上一张图片的方法
showPrev: function() {
// 判断锁的状态
if (!this.lock) return;
// 把锁关闭
this.lock = false;
// 说明是向上滑动 相当于左按钮点击事件
// 左按钮点击事件策略: 先验证 后拉动
// 改变信号量
this.idx--;
// 先验证
if (this.idx < 0) {
// 让idx变为最大值
this.idx = this.length - 1;
// 瞬移
// 注意: 设置的value值要加上px
css(this.dom, 'left', -this.width * this.length + 'px');
}
// 缓存this
var me = this;
// 拉动
animate(this.dom, { left: -this.width * this.idx }, 600, function() {
// 开锁
me.lock = true;
})
},
// 定义初始化方法
init: function() {
// 备份this
var me = this;
// 为document绑定鼠标滚轮事件
document.onmousewheel = function(e) {
// 判断鼠标滚轮的方法
if (me.direction(e)) {
// 执行显示下一张图片的方法
me.showNext();
} else {
// 执行显示上一张图片的方法
me.showPrev();
}
}
}
}
// 执行初始化方法
carousel.init();
/****************************************************************************************************************/
// 以下是面向过程的形式:
// 获取元素
// var container = $('container');
// var ul = $('imgs');
// // 所有的图片
// var lis = document.getElementsByTagName('li');
// // 定义长度
// var length = lis.length - 1;
// // 获取元素的宽度
// var width = container.clientWidth;
// // 定义锁
// var lock = true;
// // 定义信号量
// var idx = 0;
// // 定义获取滚轮方向的方法
// function direction(e) {
// if (e.wheelDelta === undefined) {
// // 当值是二取一的时候 就可以使用三目运算简化
// return e.detail > 0 ? true : false;
// } else {
// // 简写
// return e.wheelDelta > 0 ? false : true;
// }
// }
// // 绑定事件
// bindEvent(document, 'mousewheel', function(e) {
// // 执行方法获取滚轮方向
// if (direction(e)) {
// // 判断锁的状态
// if (!lock) return;
// // 把锁关闭
// lock = false;
// // 说明图片应该从右边进去 相当于右按钮事件
// // 右按钮事件的策略: 先拉动 再验证
// // 该变信号量
// idx++;
// // 拉动
// animate(ul, { left: -width * idx }, 600, function() {
// // 验证信号量
// if (idx > length - 1) {
// // 让idx从0开始
// idx = 0;
// // 瞬移到真图
// css(ul, 'left', 0);
// }
// // 动画执行完毕之后 开锁
// lock = true;
// })
// } else {
// // 判断锁的状态
// if (!lock) return;
// // 把锁关闭
// lock = false;
// // 说明是向上滑动 相当于左按钮点击事件
// // 左按钮点击事件策略: 先验证 后拉动
// // 改变信号量
// idx--;
// // 先验证
// if (idx < 0) {
// // 让idx变为最大值
// idx = length - 1;
// // 瞬移
// // 注意: 设置的value值要加上px
// css(ul, 'left', -width * length + 'px');
// }
// // 拉动
// animate(ul, { left: -width * idx }, 600, function() {
// console.log('动画执行完毕了');
// // 开锁
// lock = true;
// })
// }
// })
</script>
</body>
</html>
5.备份this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 定义函数
function a() {
var num = 10;
// 定义一个b函数中不存在的变量即可
var num2 = num;
// 备份this (定义一个b函数中不存在的变量)
var me = this;
// 定义内部函数
function b() {
var num = 20;
// console.log(num2);
console.log(me);
}
// 执行b函数
b();
}
// 执行a函数
a();
</script>
</body>
</html>
6.构造函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
/**
* 构造函数
* 与普通函数在定义方式上没有不同, 只不过构造函数的首字母要大写,此要求非语法要求
*
* 目的:
* -普通函数: 为了实现某一功能
* -构造函数: 为了创建对象
*
* 调用方式:
* -普通函数: 直接调用
* -构造函数: 通过new关键字调用
*
**/
// 定义普通函数
function demo() {
console.log(this);
}
// 直接调用
demo();
// 构造函数
function People() {
console.log(222, this);
}
new People();
</script>
</body>
</html>
7.对象之间的区别
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 定义方法 创建人
// function people(name, age, sex) {
// // 定义对象
// var obj = {
// name: name,
// age: age,
// sex: sex
// }
// // 返回结果
// return obj;
// }
// // 执行方法
// console.log(people('xiaoming', 12, '男'));
// // 定义方法 创建狗
// function dog(name, age, sex) {
// // 定义对象
// var obj = {
// name: name,
// age: age,
// sex: sex
// }
// // 返回结果
// return obj;
// }
// console.log(dog('小白', 1, '公'));
// 通过构造函数创建对象
function People() {}
function Dog() {}
console.log(new People());
console.log(new Dog());
// 结论: 对于普通函数创建出来的对象 无法精确类型 而构造函数是可以的
</script>
</body>
</html>
8.构造函数执行时候的四个步骤
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 构造函数执行时候的四个步骤
// 1 开辟一个新的内存空间
// 2 改变this指向
// 3 执行函数中的代码,为this赋值
// 4 返回this
// 概念介绍:
// People称为构造函数 常常称之为People类
// 从People类中new出来的对象 称之为实例化对象 (该类的实例)
function People(name, age, sex) {
// 添加数据
this.name = name;
this.age = age;
this.sex = sex;
}
// 创建对象 (实例化对象)
var p = new People('xiaoming', 12, 'nan');
console.log(222, p.name);
console.log(222, p.age);
console.log(222, p.sex);
</script>
</body>
</html>
9.构造函数中出现return的情况
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 定义普通函数
// function demo() {
// return 100;
// }
// // 普通函数如果想要得到内容 必须在函数中返回数据
// console.log(demo());;
// 定义类
function People(name, age, sex) {
// 添加数据
this.name = name;
this.age = age;
this.sex = sex;
// 返回值类型 是忽略的
// return 100;
// return 'abc';
// return true;
// 返回引用类型数据 则以返回值为准
// return {}
// return [];
// return function() {}
// 注意: 不要在构造函数中出现return
}
// 创建对象 (实例化对象)
var p = new People('xiaoming', 12, 'nan');
console.log(p);
</script>
</body>
</html>
10.气球类
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 定义气球类
function Balloon(img) {
// 定义dom属性
this.dom = document.createElement('div');
// 定义宽的和高度属性
this.width = img.width / 4;
this.height = img.height / 3;
// 定义随机的X值
this.positionX = parseInt(Math.random() * 4);
// 定义随机的Y值
this.positionY = parseInt(Math.random() * 3);
// 定位left值
this.left = 0;
// 定位top值
this.top = 0;
// 定义方法用于设置样式
this.setStyle = function() {
// 设置容器元素的宽高
this.dom.style.width = this.width + 'px';
this.dom.style.height = this.height + 'px';
// 设置元素的定位
this.dom.style.position = 'relative';
this.dom.style.left = this.left + 'px';
this.dom.style.top = this.left + 'px';
// 设置盒子的背景图片
this.dom.style.backgroundImage = 'url('+ img.src +')';
// 设置图片的随机位置
this.dom.style.backgroundPositionX = -this.width * this.positionX + 'px';
this.dom.style.backgroundPositionY = -this.height * this.positionY + 'px';
}
// 定义上树方法
this.upTree = function() {
document.body.appendChild(this.dom);
}
// 定义气球移动的方法
this.move = function() {
// 改变this.left值
this.left += 5;
// 设置元素的定位值
this.dom.style.left = this.left + 'px';
}
// 定义检测是否到达边界的方法
this.check = function() {
// 判断气球的定位值
if (this.dom.offsetLeft >= document.documentElement.clientWidth - this.dom.clientWidth) {
// 设置元素的定位值
this.dom.style.left = (document.documentElement.clientWidth - this.dom.clientWidth) + 'px';
}
}
// 定义初始化方法
this.init = function() {
// 调用设置样式的方法
this.setStyle();
// 设置上树的方法
this.upTree();
}
// 在最下面调用init方法
this.init();
}
// 定义定时器的句柄
var timer = null;
// 创建图片元素
var img = document.createElement('img');
// 设置图片元素的路径
img.src = './images/balloon.jpg';
// 为了保证图片加载完毕之后使用 要设置load事件
img.onload = function() {
// 实例化气球类
window.b = new Balloon(img);
// 赋值定时器
timer = setInterval(function() {
// 不断调用move方法
b.move();
// 检测气球是否到达边界
b.check();
}, 30)
}
</script>
</body>
</html>