js面向对象
swiper
下载完后找到需要的文件:注意,点开头的文件夹都没用,不要管
需要:swiper-bundle.min.css和swiper-bundle.min.js,想要看的话可以选择不带min的文件
不会或者想要改动可以查找API文档
写一个轮播图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<link rel="stylesheet" href="./css/swiper-bundle.min.css">
<body>
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
<!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- 如果需要滚动条 -->
<div class="swiper-scrollbar"></div>
</div>
<style>
.swiper-container {
width: 600px;
height: 300px;
}
</style>
</body>
<script src="./js/swiper-bundle.min.js"></script>
<script>
var mySwiper = new Swiper('.swiper-container', {
direction: 'horizontal', // 垂直切换选项
loop: true, // 循环模式选项
// 如果需要分页器
pagination: {
el: '.swiper-pagination',
},
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
// 如果需要滚动条
scrollbar: {
el: '.swiper-scrollbar',
},
})
</script>
</html>
html模板:模版之家
jquery插件,jq22.com
面向对象的概念
不是语法,是一种编程的思想,更加注重对象object
OOP:面向对象的编程
创建对象
1、字面量形式:
var obj ={}
2、构造函数形式
var obj =new Object();
第一种简洁方便,先选择第一个创建对象
先看下面的代码:
var name ="张三";
var age=12;
var name1="李四";
var age1 = 13;
变量多了容易乱:所以用对象存储。
var obj1={
name:"张三",
age:12
}
var obj2 ={
name:"李四",
age:13
}
//...
对象多了就是不停的重复(所以字面量形式定义对象不是最优发方案),我们需要处理重复:使用函数处理重复
工厂函数的创建以及他的缺点
函数处理字面量定义对象重复:
function getObj(){
var obj2={
name:"李四",
age:13,
sex:"女"
}
return obj2
}
var obj1 = getObj();
console.log(obj1);
var obj2=getObj();
console.log(obj2);
函数的参数不能写死:
function getObj(name,age,sex){
var obj2={
name:name,
age:age,
sex:sex
}
return obj2
}
var obj1 = getObj("张三",12,"男");
console.log(obj1);
var obj2=getObj("李四",13,"女");
console.log(obj2);
这种函数通常都是将数据仍进去,生产一个对象:称为工厂函数
工厂函数比直接使用字面量形式定义更加优秀
缺点:
var obj3= {
name:"阿黄",
age:12,
sex:"母"
}
typeof都是object,看不出精准的数据类型,就像你不知道obj3是人是狗,使用的时候只能靠猜
构造函数解决工厂函数的缺点
之前学的var arr = new Array[];
var num = new Number();//都是有精准的数据类型
console.log(arr,number);
所以试试构造函数:
function fn(){
}
var f = new fn();
console.log(fn);
function Preson(){
}
var obj1 = new Person();
console.log(obj1);
function Dog(){
}
var d = new Dog();
console.log(d);
可以得出自己定义构造函数来解决工厂函数数据类型不精准的缺点。
解决:
function Person(){//构造函数
//在构造函数中给对象添加属性的方式:this
this.name="张三";
this.age=12;
this.sex="女";
}
var person = new Person();//调用了构造函数
console.log(person);
this在构造函数中,代表被new 出来的对象(this代表person)
数据不应该写死:
function Person(name,age,sex){
this.name=name;
this.sex=sex;
this.age=age;
}
var zhangsan=new Person("张三",12,"男");
var lisi = new Person("李四",12,"女");
function Dog(name,age,sex){
this.name=name;
this.sex=sex;
this.age=age;
}
var ahuang = new Dog("阿黄",12,"女");
consoole.log(ahuang);
Dog和Person的区别一目了然
注意事项
-
构造函数的首字母一般大写
-
构造函数被new的时候也是在调用函数,就能有形参和实参
-
在构造函数中给对象添加属性的时候,使用this关键字
this在构造函数中,代表new出来的对象
- new关键字/new运算符干了什么?
创建了个空对象,只是这个过程是看不见的
将这个空对象直接复制给了this关键字(this=obj,也是看不见的)
给this这个对象添加属性(只能看到这个,相当于给obj添加属性)
将这个对象返回(隐形的)
如何创建对象?构造函数是最优的方案
添加属性使用自定义构造函数也是最佳方案了
添加方法在构造函数不行,在全局有缺点
//使用自定义函数创建对象并添加方法
function Person(nem,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
this.eat=function(){
console.log("能吃");
}
}
var p = new Person("张三",12,"男");
// p.eat(){
// console.log("能吃");
//}
console.log(p);
var p1 = new Person("李四",12,"女");
console.log(p.eat===p1.eat);//复杂数据类型,结果为false
为什么不相等,因为是匿名函数,每次创建都相当于在内存中开辟空间
所以在构造函数中添加方法是浪费的(方法是在堆内存开辟空间的对象的内存内的)
function eat(){
console.log("能吃");
}
function Person(nem,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
this.eat=eat;
}
var p = new Person("张三",12,"男");
var p1 = new Person("李四",12,"女");
console.log(p.eat===p1.eat);//true,这是堆内存的一种节省
缺点:全局中的东西容易被覆盖(eat =123;这两个方法全凉凉)
利用原型解决方法在全局中的缺陷
任何对象天生自带一个属性,_ _ proto _ _
注:没得空格,这里是方便区分
__ proto __值是一个对象,这个对象叫做原型/原型对象
数组为什么能用push方法?
push方法在__ proto __里面。
对象天生就能使用原型的东西,为了便于理解,相当于顺着__ proto__找到父亲,身为儿子天生可以使用父亲的东西
给数组添加方法:
arr.__proto__.eat = function(){
console.log("能吃");
}
console.log(arr);
全局函数被覆盖的问题用原型来解决。
任何函数天生自带属性prototype,指的是他老公----原型对象
现在理一下关系:我们需要的对象是由构造函数new出来的( var p = new Person() );构造出来的对象自带属性__proto__指向原型。同一个构造函数创建的对象都有共同的 proto属性(为什么?因为构造函数里面的prototype指的是原型对象)
添加方法的最优解决方法:构造函数给原型对象添加方法,对象使用
Person.prototype.eat=function(){console.log(eat)}
关系图:
案例:面向对象版tab切换
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 500px;
height: 300px;
border: 1px solid yellowgreen;
margin:50px auto;
}
ul {
height: 50px;
background-color: pink;
display: flex;
justify-content: space-evenly;
align-items: center;
}
ul li {
list-style: none;
width: 150px;
height: 30px;
background-color: gray;
text-align: center;
line-height: 30px;
font-weight: bold;
font-size: 20px;
color:green;
}
ul li.active{
background-color: #ff0;
color:#f00;
}
ol li {
display: none;
}
ol li.active {
display: block;
}
ol li img{
width: 500px;
height: 250px;
}
</style>
<div class="box">
<ul>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
<ol>
<li class="active">
<a href="">
<img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2493695704,2540399818&fm=26&gp=0.jpg" alt="">
</a>
</li>
<li>
<a href="">
<img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1242578728,2152118644&fm=26&gp=0.jpg" alt="">
</a>
</li>
<li>
<a href="">
<img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3213912571,2486886761&fm=26&gp=0.jpg" alt="">
</a>
</li>
</ol>
</div>
</body>
<script>
//使用面向对象的思维去做
function Tab(){
//给对象添加属性----属性就是你要操作的那些元素
this.ulis = document.querySelectorAll(".box ul li");
this.olis = document.querySelectorAll(".box ol li");
}
//给对象添加方法---绑定事件,处理事件
Tab.prototype.click = function(){
//给元素绑定事件
for(let i =0;i<this.ulis.length;i++){//这个this是谁现在还不知道,这里只是定义,是谁得看调用对象
this.ulis[i].onclick=()=>{
for(let j = 0 ; j<this.ulis.length;j++){//不换箭头函数this变成事件源this.ulis[i](每个li),是没有ulis的
this.ulis[j].className="";
this.olis[j].className="";
}
this.ulis[i].className="active";
this.olis[i].className="active";
}
}
}
var tab = new Tab();
tab.click();
//console.log(tab);//查看属性长什么样子
</script>
</html>
基本三步骤:做对象,添加属性,添加方法
面向对象版轮播图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>面向对象版轮播图</title>
</head>
<style>
ul,
ol {
list-style: none;
}
.box {
width: 500px;
height: 300px;
margin-left: 20px;
position: relative;
}
* {
margin: 0;
padding: 0;
}
ul {
width: 500px;
height: 300px;
border: 1px solid red;
}
ul li {
display: none;
}
ul li.active {
display: block;
}
ul li a img {
width: 500px;
height: 300px;
}
a {
text-decoration: none;
color: black;
font-size: 30px;
}
ol {
width: 200px;
height: 26px;
position: absolute;
background-color: green;
border-radius: 26px;
left: calc(50% - 100px);
bottom: 20px;
display: flex;
justify-content: space-evenly;
align-items: center;
}
ol li {
background-color: gray;
width: 26px;
height: 26px;
border-radius: 26px;
}
ol li.active {
background-color: red;
}
.leftBtn,
.rightBtn {
position: absolute;
left: 0;
top: calc(50% - 13px);
height: 50px;
width: 30px;
background-color: rgba(0, 0, 0, .5);
text-align: center;
line-height: 50px;
}
.rightBtn {
left: calc(100% - 28px);
}
</style>
<body>
<div class="box">
<ul>
<li class="active"><a href="#"><img
src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2493695704,2540399818&fm=26&gp=0.jpg"
alt=""></a></li>
<li><a href=""><img
src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1242578728,2152118644&fm=26&gp=0.jpg"
alt=""></a></li>
<li><a href=""><img
src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3213912571,2486886761&fm=26&gp=0.jpg"
alt=""></a></li>
</ul>
<ol>
<li class="active"></li>
<li></li>
<li></li>
</ol>
<a href="javascript:;" class="leftBtn"><</a>
<a href="javascript:;" class="rightBtn">></a>
</div>
</body>
<script>
//面向对象做轮播图
function Carousel(classname,speed) {
this.ulis = document.querySelectorAll("ul li");
this.olis = document.querySelectorAll("ol li");
this.leftBtn = document.querySelector("a.leftBtn");
this.rightBtn = document.querySelector("a.rightBtn");
this.box = document.querySelector("."+classname);
this.index = 0;
this.timer = null;
this.click(speed);//相当于c.click
}
Carousel.prototype.click = function (speed) {
//右键点击
this.rightBtn.onclick = () => {
this.right();
}
//左键点击
this.leftBtn.onclick = () => {
this.left();
}
//小点点击
for (let i = 0; i < this.olis.length; i++) {
this.olis[i].onclick = () => {
this.dot(i);
}
}
//自动轮播
this.timer = setInterval(() => {
//定时器中this代表window,改为箭头函数上一级的this(click方法执行对象)
this.index++;
if (this.index == this.ulis.length) {
this.index = 0;
}
for (let j = 0; j < this.ulis.length; j++) {
this.ulis[j].className = "";
this.olis[j].className = "";
}
this.ulis[this.index].className = "active";
this.olis[this.index].className = "active";
}, speed)
//鼠标移入停止
this.box.onmouseover = () => {
clearInterval(this.timer);
}
//鼠标移出继续
this.box.onmouseout = () => {
this.timer = setInterval(() => {
//定时器中this代表window,改为箭头函数上一级的this(click方法执行对象)
this.index++;
if (this.index == this.ulis.length) {
this.index = 0;
}
for (let j = 0; j < this.ulis.length; j++) {
this.ulis[j].className = "";
this.olis[j].className = "";
}
this.ulis[this.index].className = "active";
this.olis[this.index].className = "active";
}, speed)
}
}
Carousel.prototype.right = function () {
this.index++;
if (this.index == this.ulis.length) {
this.index = 0;
}
for (let j = 0; j < this.ulis.length; j++) {
this.ulis[j].className = "";
this.olis[j].className = "";
}
this.ulis[this.index].className = "active";
this.olis[this.index].className = "active";
}
Carousel.prototype.left = function () {
this.index--;
if (this.index < 0) {
this.index = this.ulis.length - 1;
}
for (let j = 0; j < this.ulis.length; j++) {
this.ulis[j].className = "";
this.olis[j].className = "";
}
this.ulis[this.index].className = "active";
this.olis[this.index].className = "active";
}
Carousel.prototype.dot = function (i) {
this.index = i;
for (let j = 0; j < this.ulis.length; j++) {
this.ulis[j].className = "";
this.olis[j].className = "";
}
this.ulis[this.index].className = "active";
this.olis[this.index].className = "active";
}
let c = new Carousel("box",2000);//调用
</script>
</html>
原型链:
什么是原型:
任何对象天生自带的属性__prroto__的值
任何函数自带的属性prototype的值
构造函数的原型和对象的原型是同一个对象
任何原型天生自带属性constructor:原型找构造函数的
function Person(){
}
var p =new Person();
console.log(p.__proto__ ===Person.prototype);
console.log(Person.prototype.constructor)
原型也是对象,只要是对象就有原型
console.log(Person.prototype.proto);
也可以控制台打印p,不断找,应该只有原型的原型
原型也是对象,对象就有原型,这样就形成了一条链式结构,叫原型链(访问属性和方法的时候用:当一个对象访问一个树形或方法的时候,逐级往上找,一直到null,null也没有返回undefined)